1

我正在尝试制作一个在不同位置有许多相同图像实例的游戏。我希望声明一次图像,然后在 onDraw() 中使用该位图。但是,当我使用在类中声明的任何类型的变量时,我会收到一个错误,因为它需要注意保持它的值。我刚开始使用surfaceview,所以也许我错过了一些东西。我目前只是尝试绘制一张图像,但这个想法是相同的,一旦我到达多个实例就会使用。我现在拥有的:

class GameView extends SurfaceView implements SurfaceHolder.Callback
{
    private GameThread _thread;
    // vars for display, scale, etc
    private int displayWidth;
    private int displayHeight;
    private double scale;
    private Bitmap groundPic;

    public GameView(Context context) {
        super(context);
        // set the surface holder for callback
        getHolder().addCallback(this);
        _thread = new GameThread(getHolder(), this);
                displayWidth = getWidth();
        displayHeight = getHeight();
        scale = displayWidth / 512.0;   // ground image is 512;
    }
@Override
    public void onDraw(Canvas canvas)
    {

        groundPic = BitmapFactory.decodeResource(getResources(), R.drawable.ground);
        groundPic = Bitmap.createScaledBitmap(groundPic, displayWidth, 50, true);
        canvas.drawColor(getResources().getColor(R.color.background_colour));
        // draw ground                  
        canvas.drawBitmap(groundPic,0, getHeight() - 50, null);
    }

这会导致强制关闭,因为 displayWidth 为 0。在构造函数中设置值我错了吗?我尝试在创建视图之后和 setContentView() 之前从我的活动中调用一个 init()。我知道如果我将所有设置都放在 onDraw() 中它会起作用,但我觉得它确实效率低下。我希望做的(但导致错误)是拥有 init() 并在其中设置 groundPic 这将是一个类变量,然后我的 onDraw 会小而快,因为它不会继续这样做每个周期都有相同的位图对象。我也将在地面周围绘制 30 枚导弹,所以如果我只能绘制一次,然后在特定位置绘制 30 次,那么每个周期绘制 30 个相同的位图将是巨大的浪费。

4

1 回答 1

0

这会导致强制关闭,因为 displayWidth 为 0。我在构造函数中设置值是否错误?

是的,因为正常行为表明SurfaceView遗嘱在构建时尚未布局。相反,您应该使用SurfaceHolder.Callback来发现SurfaceView与其大小和格式相关的任何更改。您的代码片段表明您可能已经拥有相关的方法:

class GameView extends SurfaceView implements SurfaceHolder.Callback

由于您正在实施Callback,因此您应该在surfaceChanged(SurfaceHolder holder, int format, int width, int height)某处拥有该方法。您可以使用传入的widthheight参数来计算比例并适当缩小Bitmap. 同样,您可以在surfaceCreated(SurfaceHolder holder).

有关使用SurfaceView和线程绘图的更多指示,您可能需要查看 Google 的Lunar Lander 示例项目,尤其是LunarView类。

于 2012-04-28T03:06:14.530 回答