Using below code to scroll I have a Surfaceview thread and an off canvas texture bitmap that is being generated (changed), first row (line), every frame and then copied one position (line) down on regular surfaceview bitmap to make a scrolling effect, and I then continue to draw other things on top of that. Well that is what I really want, however I can't get it to work even though I am creating a separate canvas for off screen bitmap. It is just not scrolling at all.
I other words I have a memory bitmap, same size as Surfaceview canvas, which I need to scroll (shift) down one line every frame, and then replace top line with new random texture, and then draw that on regular Surfaceview canvas.
Here is what I thought would work;
My surfaceChanged where I specify bitmap and canvasses and start thread:
@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();
}
My thread, only showing essential middle running part:
@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);
}
}
}
}
For my game Tunnel Run, https://market.android.com/details?id=com.zubima.TunnelRun, right now I have a working solution where I instead have an array of bitmaps, size of surface height, that I populate with my random texture and then shift down in a loop for each frame. I get 50 frames per second, but I think I can do better by instead scrolling bitmap.
You are trying to draw a bitmap on top of itself, something which has never worked on Android AFAIK. I fell into this exact hole with my first game, a side-scroller called Mole Miner.
The problem is very simple: the drawBitmap() is, in essence, a special kind of memcpy() in which bytes are always addressed forwards. Which is fine, and uses L1 cache optimally, etc, but you obviously hit a problem if the source and destination areas (a) overlap, and (b) source address < dest address.
(Real implementations of memcpy(), by the way, check for this possibility and do the copy backwards if necessary. Canvas.drawBitmap() does not do this.)
The workaround I used for Mole Miner was to have two off-screen bitmaps, and switch between them on alternate frames. But that was in 2009 and these days I'd probably not use scrolling at all.
There is a drawBitmap function within canvas with the following signature:
public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint);
You can make your dst the size of the canvas, and your src can be set up to be new
Rect(0,offset,width,height+offset)
You can then increment offset every frame and get a smoothly scrolling bitmap in your view.
来源:https://stackoverflow.com/questions/8775093/how-to-scroll-off-screen-memory-bitmap