如何滚动屏幕内存位图

时间:2012-01-08 03:13:32

标签: java android bitmap scroll surfaceview

使用下面的代码滚动 我有一个Surfaceview线程和一个正在生成(更改),第一行(线),每一帧然后在常规surfaceview位图上向下复制一个位置(线)以产生滚动效果的非画布纹理位图,然后我继续在此基础上绘制其他东西。那就是我真正想要的,但即使我为屏幕外位图创建一个单独的画布,我也无法使它工作。它根本就不滚动。

换句话说,我有一个内存位图,与Surfaceview画布大小相同,我需要每帧向下滚动(移动)一行,然后用新的随机纹理替换顶行,然后在常规Surfaceview画布上绘制它

这是我认为可行的;

我的surfaceChanged指定位图和画布并启动线程:

@Override
    public void surfaceCreated(SurfaceHolder holder) {
    intSurfaceWidth = mSurfaceView.getWidth();
    intSurfaceHeight = mSurfaceView.getHeight();

    memBitmap = Bitmap.createBitmap(intSurfaceWidth, intSurfaceHeight,
            Bitmap.Config.ARGB_8888);
    memCanvas = new Canvas(memCanvas);

    myThread = new MyThread(holder, this);
    myThread.setRunning(true);
    blnPause = false;
    myThread.start();
}

我的主题,只显示必要的中间运行部分:

@Override
public void run() {
  while (running) {     
    c = null;
try {
    // Lock canvas for drawing
    c = myHolder.lockCanvas(null);                  

    synchronized (mSurfaceHolder) {
        // Scroll down off screen canvas and hopefully underlying bitmap bitmap
        Rect src = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight - 1);
        Rect dst = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight);
        memCanvas.drawBitmap(memBitmap, src, dst, null);

        // Note scrolling up like this works fine
        // Rect src = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight + 1);
        // Rect dst = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight);
        // memCanvas.drawBitmap(memBitmap, src, dst, null);

        // Create random one line(row) texture bitmap
        textureBitmap = Bitmap.createBitmap(imgTexture, 0, rnd.nextInt(intTextureImageHeight), intSurfaceWidth, 1);

        // Now add this texture bitmap to top of screen canvas and hopefully underlying bitmap
        memCanvas.drawBitmap(textureBitmap,
                intSurfaceWidth, 0, null);

        // Draw above updated off screen bitmap to regular canvas, at least I thought it would update (save changes) shifting down and add the texture line to off screen bitmap the off screen canvas was pointing to.
        c.drawBitmap(memBitmap, 0, 0, null);

        // Other drawing to canvas comes here


    } finally {
        // do this in a finally so that if an exception is thrown
        // during the above, we don't leave the Surface in an
        // inconsistent state
        if (c != null) {
            myHolder.unlockCanvasAndPost(c);
        }
    }
}       
}

对于我的游戏隧道运行,https://market.android.com/details?id=com.zubima.TunnelRun,现在我有一个工作解决方案,我有一个位图数组,表面高度的大小,我用随机纹理填充,然后在循环中向下移动对于每一帧。我得到每秒50帧,但我认为我可以通过滚动位图来做得更好。

2 个答案:

答案 0 :(得分:1)

您正在尝试在自身之上绘制位图,这在Android AFAIK上从未起作用。我的第一个游戏,一个名为Mole Miner的侧卷轴,我陷入了这个洞。

问题非常简单:drawBitmap()本质上是一种特殊的memcpy(),其中字节始终是转发。这很好,并且最佳地使用L1缓存等,但是如果源和目标区域(a)重叠,并且(b)源地址<目的地址。

(顺便说一下,memcpy()的真实实现,检查这种可能性,并在必要时向后复制.Canvas.drawBitmap()不会这样做。)

我用于Mole Miner的解决方法是使用两个屏幕外位图,并在备用帧之间切换它们。但那是在2009年,这些天我可能根本不使用滚动。

答案 1 :(得分:0)

画布中有一个带有以下签名的drawBitmap函数:

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint);

你可以使你的dst达到画布的大小,你的src可以设置为新的

 Rect(0,offset,width,height+offset)

然后,您可以每帧增加偏移量,并在视图中获得平滑滚动的位图。