使用下面的代码滚动 我有一个 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/