• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Faster Drawing Question

I am looking at the Snake example that comes with the SDK, specifically the onDraw method inside the TileView class:

Code:
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int x = 0; x < mXTileCount; x += 1) {
            for (int y = 0; y < mYTileCount; y += 1) {
                if (mTileGrid[x][y] > 0) {
                    canvas.drawBitmap(mTileArray[mTileGrid[x][y]], 
                    		mXOffset + x * mTileSize,
                    		mYOffset + y * mTileSize,
                    		mPaint);
                }
            }
        }

    }

This works great for the snake application but I am thinking of doing something a bit more intensive so I want my draw method to be as quick as possible. I was thinking of something a bit more like this:

Code:
public Drawable canvasBuffer;
public Coordinate[] dirtyTiles; //A list of tiles that need to be re-drawn

public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < dirtyTiles.length; i += 1) {
            //I need a way to do this - drawOtherImage is not a real function
            canvasBuffer.drawOtherImage(mTileGrid[dirtyTiles.x][dirtyTiles.y],
                                     dirtyTiles.x*mTileSize, dirtyTiles.y*mTileSize)
        }
        canvasBuffer.draw(canvas);
 }

The idea being that I store a separate image (canvasBuffer) that I only draw the tiles that need to be changed, then I draw the buffer to the canvas. Also this way I do not have to calculate the offset for every tile, I can set the offset at anytime by setting the bounds of the canvasBuffer.
My question here is how to draw one drawable onto another, I can only find methods that allow you to draw to a canvas object. Any suggestions?
 
Welcome to the forum! :D

Mind you, I have zero Android graphics experience, but I like your way of thinking. Can you initialise the offscreen image to be transparent, and then display it (the non-transparent parts overwriting the existing image)? But I wonder if it's not slower to paint this relatively large image than it is to paint a number of tiny ones ... just a thought.

Remember: I know nothing! :p
 
  • Like
Reactions: FoxMulder900
Upvote 0
Klaymen, your transparency idea is interesting, I might have to give that a try; however that still leaves me trying to figure out how to draw a smaller image onto another larger image that is not the canvas. I was also wondering if the cost of drawing a single large image would be much better than a bunch of small ones, but if I can figure it out I will do some timing and post the results! - also, BIG fan of The Neverhood here! :D

seafit, what exactly is scroll Carmack? I'm assuming you mean something that John Carmack came up with, but I can't seem to find anything on google!

Thanks for the replies!
 
Upvote 0
I have finally gotten back around to taking a look at this and I have found a solution if anyone is interested. I simply did not understand the concept that you do not actually draw onto a Canvas object, rather the Canvas object is a tool used to draw onto a Bitmap. So I did something like this.

Code:
Bitmap bufferBitmap = Bitmap.createBitmap(mapWidth, mapHeight, Bitmap.Config.ARGB_8888);
Canvas bufferCanvas = new Canvas(bufferBitmap); 
Vector<Drawable> dirtyTiles = new Vector<Drawable>();

Then simply keep track of your dirty(changed) tiles and during the drawing routine, loop through the array and draw them using the bufferCanvas, then draw the bufferBitmap to the main canvas. (don't forget to clear out the dirtyTiles array after you have drawn them all)

My timings for this method were around 4 times faster than looping through every tile, every frame!
 
Upvote 0

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones