使用下面的代码滚动 我有一个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帧,但我认为我可以通过滚动位图来做得更好。
答案 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)
然后,您可以每帧增加偏移量,并在视图中获得平滑滚动的位图。