Game development in progress: Space Invaders clone – update 3 (18 months later)

It’s been a year and a half since I’ve given an update on my Space Invaders clone on Android. Admittedly I haven’t been working continuously in my spare time on this project for 18 months, in fact the last time I remember working on it was several months back. What I got stuck on was updating the animation routines so the animation would display with a constant frame rate across different Android devices, and the display of the sprites to look consistent for devices with different sized screens, resolutions and pixel densities.

If you’re a seasoned game developer this is probably nothing new to you. If you only develop for a platform with identical hardware specs (like a game console) then this is probably something you don’t have to worry (too much?) about. However with the broad range of specs for Android devices, even testing with the device emulator for different phones, it’s pretty obvious unless your code handles these differences, your game might be fast on one device but slow on another, or the sprite layout may look at intended at the resolution on one phone but be too small on another phone.

I spent a bunch of time reading game dev articles about implementing approaches for constant frame rates, and tried to incorporate what I’d learned, but still, I’ve got some weird quirks I need to iron out.

Here’s what the game looks like on an emulated Pixel:

I was initially developing and testing on the emulated Nexus devices as my baseline test target, but it runs fine, as expected on the Pixel too (it’s harder to play when pressing the buttons with the mouse!).

Now running on an emulated Pixel 2 XL, it runs fine for a while until the number of invaders gets down to where I speed up. The speed up is too fast, and then for some reason that I haven’t found yet they animation stops before the game ends but the game is still playing:
Clearly I’ve still got some work to do here, but it’s getting close.

Android development: drawing text on a Canvas

I have an Android project bubbling away. More details soon 🙂

I’m using a SurfaceView and needed to draw some text on it. The rest of the app is mostly drawing on the SurfaceView Canvas directly, but I need some text too.

I’ve dabbled with some Android development before, and I have to admit getting the layouts to do what you want them too almost seems to suck up the majority of my development time 🙁 This time round I got sidetracked trying to create a layout that was using a mix of TextView elements and adding my SurfaceView programmatically. This didn’t go too well, didn’t work at all, so I found a few posts like this, and worked out you need to draw directly on the canvas. Something like this does the job:

Paint textPaint = new Paint();
textPaint.setColor(Color.WHITE);
this.canvas.drawText("Hello world!", 20,50, textPaint);

This code is in the middle of a game display loop, but for completeness, to be able to draw to the Canvas first you need:

SurfaceHolder surfaceHolder = this.getHolder();
if (surfaceHolder.getSurface().isValid()) {
    this.canvas = surfaceHolder.lockCanvas();
   ...
}

And then to release the Canvas after you’ve finished drawing:

this.surfaceHolder.unlockCanvasAndPost(this.canvas);

 

Ok, next up, what about custom TTF fonts? Drop the TTF font you want to use in your assets/fonts folder, and then load it up with:

Typeface typeFace = Typeface.createFromAsset(this.context.getAssets(), 
    "fonts/yourfont.ttf");

To use this font with the text snippet above, just call setTypeface() and pass it in:

textPaint.setTypeface(this.typeFace);

Ok, how about specifying a font size that’s proportional to the resolution of the user’s screen? This is an interesting question. To avoid using fixed pixel size fonts and then having them not scale appropriately for different devices with different screen resolutions, Android uses a concept called ‘scale independent pixels’, or SP. This is described in this post here. In short, defines an SP value in /res/values/dimens.xml/dimens.xml like:

<dimen name="scoreFontSize">20sp</dimen>

And then reference and set it like this:

int fontSize = getResources().getDimensionPixelSize(R.dimen.scoreFontSize);
textPaint.setTextSize(fontSize);

Done! (I’ll share more on what I’m working on in a few days 🙂