我的滚动位图画布太慢而无法使用

时间:2011-10-11 21:56:22

标签: android canvas bitmap

我正在学习为Android编程。我做了几个基本的游戏,但是为了学习,我想制作汽车驾驶游戏。我想到的最简单的方法是将汽车保持在屏幕中间并滚动背景以产生运动的幻觉。

作为计算引擎的实验,我创建了一个2048x1200位图,我从PNG加载。这将是地图。然后我创建一个1024x600的新位图,从我在屏幕上显示的地图中裁剪出来。我这样做是为了getWidth()& getHeight()给出了这些维度。我每次根据屏幕上显示的动作拍摄不同的裁剪。

不幸的是我发现这个太慢了。如果我想让它变得平滑,那么这辆车必须以蜗牛的速度移动。我得到大约18fps。

我正在使用James Daniello's Simple Game Loop

我还阅读了以下堆栈溢出文章,该文章说尽可能地将对象创建保留在主循环之外,我尽我所能。 How to draw lots of bitmaps on screen in an Android game without slow performance

另一个有用的是Romain Guy的这篇文章,它将Bitmap保持为与屏幕相同的格式,以阻止它必须转换为在屏幕上显示,这是非常昂贵的。
Bitmap quality, banding and dithering

在进入OpenGL之前,我想了解Canvas和Bitmaps可以达到的最佳效果。我是在限制,还是应该采取不同的做法?我发现只要一次滚动地图1px就可以获得18fps,以便平滑滚动。

private Bitmap track;
private Bitmap visible;
private Point position;
private int fps = 0;
private long lastFpsTime = 0;
private int fpsCount = 0;
Paint pText;

public void Draw(Canvas c){
    visible = Bitmap.createBitmap(track, position.x + 512, position.y + 300, 512, 300);
    position.x++;
    c.drawBitmap(visible, 0,0, null);
    c.drawText("FPS: " + fps, 10, 10, pText);
}

public void Init(Resources resources) {
    // Load Map from track1.png
    track = Bitmap.createBitmap(2048, 1200, Bitmap.Config.RGB_565);
    Bitmap track1 = BitmapFactory.decodeResource(resources, R.drawable.track1);
    track = track1.copy(Bitmap.Config.RGB_565, true);
    position = new Point(0,0);

    //Setup the Text Paint Object
    pText = new Paint();
    pText.setColor(Color.WHITE);
    pText.setStyle(Style.FILL_AND_STROKE);
}

public void Update() {
    fpsCount++;

    if (System.currentTimeMillis() - lastFpsTime >= 1000){
        lastFpsTime = System.currentTimeMillis();
        fps = fpsCount;
        fpsCount = 0;
    }
}

2 个答案:

答案 0 :(得分:5)

您正在绘制的每个帧上创建一个新的位图。这是非常昂贵的。您应该使用drawBitmap()的版本,而不是采用源矩阵和目标矩形。

答案 1 :(得分:0)

您可以使用以下两种策略之一:矩阵或剪切矩形,而不是从原始位图复制和缩放。矩阵允许您执行与平移(平移),缩放,倾斜和旋转相关的所有数学到一个对象。每个操作也是可选的。根据位图的原点计算操作。与此一起使用的api是Canvas.drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)。这使您可以最大程度地控制变换Bitmap,但要完全使用它,您需要了解一些线性代数。

第二个选项是使用rectangle,我相信它在开始时更容易想象和使用。在Bitmap上使用源矩形,您可以将其视为可以在Bitmap的尺寸上滑动的窗口,也可以根据需要进行扩展和缩小。目标矩形将表示您希望在屏幕上看到的尺寸。通常是SurfaceView的背景尺寸。使用Canvas.drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint) API。