androidcodeexamples.com
Offcode ltd logo
ANDROID
APACHE
THUMBNAILS
SCRIPTS
GFX
World-class examples brought to you by Offcode ltd
ANDROID
Developing the empire Bluetooth low energy Facebook API Google URL shortener Short URL lookup Tabs and fragments Privacy policy Front Page
androidcodeexamples.com

Android game programming - Empire game for Android. [2/3]

In this next chapter we show how the actual rendering takes place. Our MapManager has prepared the map for us. The class EmpireSurfaceView is first introduced with its vital members. The function drawItem() draws a single grid element on two bitmaps. One for the SurfaceView itself and another for the blinking tank/artillery/ship. Function updateCanvas() draws first the 512x512 chunks that actually cover 4x4 grid elements (each 128x128 pixels in size).

Next chapter
Prev chapter

EmpireSurfaceView

EmpireSurfaceView.java

EmpireSurfaceView extends SurfaceView implements SurfaceHolder.Callback { 
 
    private static GfxItemPool gfxItemPool = null; 
    private static MapManager mMapManager = null; 
    private SurfaceHolder applicableCanvas = null; 
    SurfaceView surface; 
    private int topX = 0; 
    private int topY = 0; 
    private int mwidth = 10; 
    private int mheight = 10; 
    public int scaleFactor = 1; 
    Bitmap bmOverlay; 
    Canvas background = null; 
    GameThread thread = null

drawItem - function that draws an item

This method draws the bitmap on two canvases. One for the background and one for moving items such as tanks, boats artillery etc. In this way we store the backgroung so that if the tank is animated, or the selector around it changes, we draw the background every time before the change is made. Otherwise the it's hard to restore the backround behind the animation. Perhaps this isn't the most optimal way as we could just update the grid element underneath the tank. However, we do a complete redraw for simplifying things.

The scaleFactor is for testing purposes only. It's there for zooming in/out.

public void drawItem(Canvas canvas, Canvas bg, Bitmap bmap, int i, int j) { 
        if (scaleFactor != 1) { 
            // Use this for testing only! Terribly slow by always scaling! 
            int width = bmap.getWidth() / scaleFactor; 
            int height = bmap.getHeight() / scaleFactor; 
            Bitmap resizedBitmap = Bitmap.createScaledBitmap(bmap, width, height, false); 
            canvas.drawBitmap(resizedBitmap, i * (128/scaleFactor), j * (128/scaleFactor), null); 
            bg.drawBitmap(resizedBitmap, i * (128/scaleFactor), j * (128/scaleFactor), null); 
        } else { 
            canvas.drawBitmap(bmap, i * 128, j * 128, null); 
            bg.drawBitmap(bmap, i * 128, j * 128, null); 
        } 
    }  
    

updateCanvas() - function that draws the complete background

public void updateCanvas(int dx, int dy) { 
        int i, j, mapItem, mapBgItem; 
 
        topX += dx; 
        topY += dy; 
 
        Canvas canvas = applicableCanvas.lockCanvas(); 
        synchronized (applicableCanvas) { 
            if (topX < 0) 
                topX = 0; 
            if (topY < 0) 
                topY = 0; 
            if (topX > (100 - mwidth - 1)) 
                topX = (100 - mwidth - 1); 
            if (topY > (100 - mheight - 1)) 
                topY = (100 - mheight - 1); 
            if (thread != null) { 
                thread.locX -= dx; 
                thread.locY -= dy; 
            } 
 
            background = new Canvas(bmOverlay); 
 
            // We start from negative territory as the 512x512 tiles take 4 grid elements. 
            // This means that in some cases only 1/4th of the trailing area needs to be 
            // drawn. 
            for (j = -3; j < mheight; j++) { 
                for (i = -3; i < mwidth; i++) { 
                    if (i + topX < 0) 
                        continue; 
                    if (j + topY < 0) 
                        continue; 
                    // Fill the 512x512 backgrounds first 
                    mapItem = mMapManager.getAtLandBg(i + topX, j + topY); 
                    if ((mapItem & MapManager.landBg) == MapManager.landBg) { 
                        Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.plainLandGrass512).getBitmap(); 
                        drawItem(canvas, background, smap, i, j); 
                    } 
                    if ((mapItem & MapManager.landBgSandBorder) == MapManager.landBgSandBorder) { 
                        Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.plainLandSandBorder512).getBitmap(); 
                        drawItem(canvas, background, smap, i, j); 
                    } 
                    if ((mapItem & MapManager.landBgSand) == MapManager.landBgSand) { 
                        Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.plainLandSand512).getBitmap(); 
                        drawItem(canvas, background, smap, i, j); 
                    } 
                    if ((mapItem & MapManager.landBgMountain) == MapManager.landBgMountain) { 
                        Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.plainLandMountain512).getBitmap(); 
                        drawItem(canvas, background, smap, i, j); 
                    } 
                    if (i < 0 || j < 0) 
                        continue; 
 
                    // Land-sea borders, deep sea 
                    mapBgItem = mMapManager.getAtPos(i + topX, j + topY); 
                    // Small amount of land at one corner 
                    mapItem = mMapManager.getAtPosSpecial(i + topX, j + topY); 
                    if (mapBgItem != 0) { 
                        // Deep sea is normal sea drawn twice! Less transparent. 
                        if (mapBgItem == GfxItemTypes.plainSea1) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.plainSea).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        // Draw all others at one shot 
                        Bitmap bmap = gfxItemPool.getGfxItem(mapBgItem).getBitmap(); 
                        drawItem(canvas, background, bmap, i, j);  
                    } 
 
                    // Draw corners SW, SE, NE, NW and and combination of these 
                    if (mapItem != 0) { 
                        if ((mapItem & MapManager.landSouthEast) == MapManager.landSouthEast) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.seaLandSouthEast).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
                        if ((mapItem & MapManager.landSouthWest) == MapManager.landSouthWest) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.seaLandSouthWest).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
                        if ((mapItem & MapManager.landNorthWest) == MapManager.landNorthWest) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.seaLandNorthWest).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
                        if ((mapItem & MapManager.landNorthEast) == MapManager.landNorthEast) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.seaLandNorthEast).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
 
                        if ((mapItem & MapManager.sandSouthEast) == MapManager.sandSouthEast) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.seaSandSouthEast).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
                        if ((mapItem & MapManager.sandSouthWest) == MapManager.sandSouthWest) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.seaSandSouthWest).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
                        if ((mapItem & MapManager.sandNorthWest) == MapManager.sandNorthWest) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.seaSandNorthWest).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
                        if ((mapItem & MapManager.sandNorthEast) == MapManager.sandNorthEast) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.seaSandNorthEast).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
                    } 
                } 
            } 
 
            for (j = 0; j < mheight; j++) { 
                for (i = 0; i < mwidth; i++) { 
                    mapItem = mMapManager.getAtPosSpecial(i + topX, j + topY); 
                    if (mapItem != 0) { 
                        // Draw cities on top of land 
                        if ((mapItem & MapManager.city) == MapManager.city) { 
                            Bitmap smap = gfxItemPool.getGfxItem(GfxItemTypes.city).getBitmap(); 
                            drawItem(canvas, background, smap, i, j); 
                        } 
                    } 
 
                    // Draw deep sea effects 
                    mapItem = mMapManager.getAtPosSeaEffects(i + topX, j + topY); 
                    if (mapItem != 0) { 
                        if ((mapItem & MapManager.deepSeaSouth) == MapManager.deepSeaSouth) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepSouth).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        if ((mapItem & MapManager.deepSeaNorth) == MapManager.deepSeaNorth) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepNorth).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        if ((mapItem & MapManager.deepSeaEast) == MapManager.deepSeaEast) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepEast).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        if ((mapItem & MapManager.deepSeaWest) == MapManager.deepSeaWest) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepWest).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
 
                        if ((mapItem & MapManager.deepSeaNorthWest) == MapManager.deepSeaNorthWest) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepNorthWest).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        if ((mapItem & MapManager.deepSeaSouthWest) == MapManager.deepSeaSouthWest) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepSouthWest).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        if ((mapItem & MapManager.deepSeaSouthEast) == MapManager.deepSeaSouthEast) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepSouthEast).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        if ((mapItem & MapManager.deepSeaNorthEast) == MapManager.deepSeaNorthEast) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepNorthEast).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        if ((mapItem & MapManager.deepSeaSouthEastCorner) == MapManager.deepSeaSouthEastCorner) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepSouthEastCorner).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
                        if ((mapItem & MapManager.deepSeaNorthWestCorner) == MapManager.deepSeaNorthWestCorner) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.seaDeepNorthWestCorner).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } 
 
                    } 
                } 
            } 
 
            // Eventually cover all undiscovered areas. This order should be reversed, so that 
            // no items are drawn if the grid element is completely black! 
            for (j = 0; j < mheight; j++) { 
                for (i = 0; i < mwidth; i++) { 
                    mapItem = mMapManager.getAtPosDiscovered(i + topX, j + topY); 
                    if (mapItem != 0) { 
                        if ((mapItem & MapManager.black) == MapManager.black) { 
                            Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.black).getBitmap(); 
                            drawItem(canvas, background, bmap, i, j); 
                        } else { 
                            if ((mapItem & MapManager.blackEast) == MapManager.blackEast) { 
                                Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.blackEast).getBitmap(); 
                                drawItem(canvas, background, bmap, i, j); 
                            } 
                            if ((mapItem & MapManager.blackWest) == MapManager.blackWest) { 
                                Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.blackWest).getBitmap(); 
                                drawItem(canvas, background, bmap, i, j); 
                            } 
                            if ((mapItem & MapManager.blackSouth) == MapManager.blackSouth) { 
                                Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.blackSouth).getBitmap(); 
                                drawItem(canvas, background, bmap, i, j); 
                            } 
                            if ((mapItem & MapManager.blackNorth) == MapManager.blackNorth) { 
                                Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.blackNorth).getBitmap(); 
                                drawItem(canvas, background, bmap, i, j); 
                            } 
                            if ((mapItem & MapManager.blackSouthWest) == MapManager.blackSouthWest) { 
                                Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.blackSouthWest).getBitmap(); 
                                drawItem(canvas, background, bmap, i, j); 
                            } 
                            if ((mapItem & MapManager.blackSouthEast) == MapManager.blackSouthEast) { 
                                Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.blackSouthEast).getBitmap(); 
                                drawItem(canvas, background, bmap, i, j); 
                            } 
                            if ((mapItem & MapManager.blackNorthEast) == MapManager.blackNorthEast) { 
                                Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.blackNorthEast).getBitmap(); 
                                drawItem(canvas, background, bmap, i, j); 
                            } 
                            if ((mapItem & MapManager.blackNorthWest) == MapManager.blackNorthWest) { 
                                Bitmap bmap = gfxItemPool.getGfxItem(GfxItemTypes.blackNorthWest).getBitmap(); 
                                drawItem(canvas, background, bmap, i, j); 
                            } 
                        } 
                    } 
                } 
            } 
        } 
        applicableCanvas.unlockCanvasAndPost(canvas); 
    } 
 
    


Written on April 2018