java - 如何滚动屏幕内存位图

标签 java android bitmap scroll surfaceview

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

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

这是我认为可行的;

My surfaceChanged 我指定位图和 Canvas 并启动线程:

@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);
        }
    }
}       
}

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

最佳答案

您正在尝试在其自身之上绘制位图,这在 Android AFAIK 上从未起作用。我在玩第一款名为 Mole Miner 的横向卷轴游戏时就陷入了这个困境。

问题很简单:本质上,drawBitmap() 是一种特殊的 memcpy(),其中字节总是向前寻址。这很好,并以最佳方式使用 L1 缓存等,但是如果源和目标区域 (a) 重叠,并且 (b) 源地址 < 目标地址,您显然会遇到问题。

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

我在 Mole Miner 中使用的解决方法是使用 两个 屏幕外位图,并在交替帧上在它们之间切换。但那是在 2009 年,现在我可能根本不会使用滚动。

关于java - 如何滚动屏幕内存位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8775093/

相关文章:

android - CheckBoxPreference .isChecked() 返回相反的值

android - 从 Android 上的视频文件中提取元数据

android - java.lang.RuntimeException : Unable to instantiate application android. app.Application : java. lang.NullPointerException 在 LoadedApk.makeApplication

c++ - Qt 如何从 QVector 的数据创建位图并将其显示在小部件上?

java - 使用 JNA 访问包含 vector<char*> 的结构

java - Java中的SQLite(要求用户输入一个字符串并输出表中的所有数据)

android - 使用位图和 Volley 查看寻呼机内存泄漏

c++ - GDI+:如何用红色像素替换黑色像素?

java - 用泛型覆盖方法不起作用(找不到方法)

java - groovy 中 java 类的 metaClass 属性