So I’ve made a new spaceship in order to get gun turrets working. Here it is in action:
What do you think?
Since last time I have added path finding, shooting and formation movement. All three new aspects are in still in alpha trials, so they will probably change a lot before the game is finished. Here’s a video:
As you can see I’ve added in some enemy ships in red. If you are ever flying a red spaceship and you are shooting at a green spaceship, you should think long and hard about who the bad guys are…
Irritatingly the video jumps at 0:06, again this isn’t what I see on the game, and is something to do with adb’s recording. Perhaps I’m using it wrong? This one has been recorded at 4Mbps.
The path finding algorithm I have used is called A*, I’m going to write an article or two on how it works and how I implemented it, so stay tuned. At the moment when more than one unit is moved at the same time, they will stay in the formation that they were in when they were given the move order.
I spent a while with the shooting, and I think that I have already changed my mind on how I’m going to do it. I think I will reserve visible projectiles, like the ones seen in the video above, for torpedoes and other large ordinance. For the kind of guns/lasers that fighters and the like have, I think I’ll just animate the guns and the effects. We’ll see. One of the reasons the shooting took me so long, is that my first implementation was hideously slow, it was drastically reducing the frame rate. At first, as I had made no attempt to do any optimisation, I thought this might be due to the large number of loops inside loops. However, looking at LogCat, I could see that the Garbage Collector (GC) was running several times a second.
12-18 08:59:35.022: D/dalvikvm(1005): GC_CONCURRENT freed 487K, 11% free 8828K/9860K, paused 4ms+6ms, total 38ms 12-18 09:32:43.682: D/dalvikvm(10131): GC_FOR_ALLOC freed 512K, 7% free 8082K/8636K, paused 26ms, total 26ms
I have read that the GC is often the cause of performance issues, so before any other optimisation, I thought I’d attack from that angle.
It turns out the cause of the problem was that I was returning float arrays from several static methods, and each call was creating a new float array, that was then subsequently GCd. Here’s an example with a function that rotates an arbitrary number of points about a point:
public static float [] rotatePointsAboutAPoint(float [] points, float [] rotateCenter, float angle) {
float s = (float) Math.sin(Math.toRadians(angle));
float c = (float) Math.cos(Math.toRadians(angle));
float [] out = new float [points.length];
int round = 0;
for(int i = 0; i < points.length / 2; ++i) {
round = i * 2;
out[round + X] = c * (points[round + X] - rotateCenter[X]) - s * (points[round + Y] - rotateCenter[Y]) + rotateCenter[X];
out[round + Y] = s * (points[round + X] - rotateCenter[X]) + c * (points[round + Y] - rotateCenter[Y]) + rotateCenter[Y];
}
return out;
}
This function is called when checking if one ship is within range of another, which happens ALL THE TIME. So you can see how a stupid number of temp variables would be created. My solution at this point, is to make those variables static, like this:
/*
* WARNING
*
* The following static variables are global to this class, but should be treated as uninitialised
* They will be in the state that they were in before, which could cause some difficult errors
*
* They are like this to prevent the GC from running, which drastically decreased performance
*
*/
// rotatePointsAboutAPoint
private static float [] OUT_COORDS_1 = new float [2];
private static float [] OUT_COORDS_4 = new float [8];
private static float SIN_THETA, COS_THETA;
private static int ROUND;
public static float [] rotatePointsAboutAPoint(float [] points, float [] rotateCenter, float angle) {
SIN_THETA = (float) Math.sin(Math.toRadians(angle));
COS_THETA = (float) Math.cos(Math.toRadians(angle));
ROUND = 0;
for(int i = 0; i < points.length / 2; ++i) {
ROUND = i * 2;
OUT_COORDS_4[ROUND + X] = COS_THETA * (points[ROUND + X] - rotateCenter[X]) - SIN_THETA * (points[ROUND + Y] - rotateCenter[Y]) + rotateCenter[X];
OUT_COORDS_4[ROUND + Y] = SIN_THETA * (points[ROUND + X] - rotateCenter[X]) + COS_THETA * (points[ROUND + Y] - rotateCenter[Y]) + rotateCenter[Y];
}
switch(points.length) {
case 2:
OUT_COORDS_1[0] = OUT_COORDS_4[0];
OUT_COORDS_1[1] = OUT_COORDS_4[1];
return OUT_COORDS_1;
case 8:
return OUT_COORDS_4;
default:
return null;
}
}
This doesn’t look nice does it? Firstly if I ever forgot to reset any of those variables for any reason, they would be stuck at the value from the last calculation, which would cause some wacky, deceptive errors. Also the function is less versatile as it no longer works with an arbitrary number of points. That’s not so bad as so far I only use this for rotating points and rectangles, but still…
Have you encountered a better way of doing this?
After doing that, the game runs smoothly, as you can see (excluding the jumps…). Lots of people complain about Java’s GC, lots of other languages, including C++, don’t have one. At the moment I am glad it exists, as otherwise I would be spending my time battling memory leaks as well, but perhaps it will annoy me in the future.
I am not the most terrible person at art, though I may well be the slowest, I once managed to blag 7 extra hours in an 8 hour art exam, and I still didn’t finish… (Got a C, lame). One of the problems with trying to make a brilliant game is you either need to be good at everything, or you need to own a large wallet. I suppose you can be somewhere in between , but when you are just starting out, you don’t want to be spending money on concept art. So that means, for now at least, I have created my own filler art. This is just a stand in until I get something better.

It’s not nearly as grim and gritty as I would like…
Here’s the first sprite sheet I’ve attempted:
Hello,
I am starting the process of making my first ever Android game. The plan is to make a 2D strategy game set in space, a bit like a cross between Homeworld and Battlefleet Gothic. It’s working title at the moment is ‘Battlefleet’.
I want the feel of the game to be serious, grim and cold, and I want to the action to be intense, but not fast paced. I would quite like this game to require constant thinking, rather than requiring a high APM. Something else I would like this game to have, is a huge sense of scale, so maybe the biggest ships are over 100 times bigger than the smallest ships. Future revisions of the game will hopefully have multiplayer, maybe even with an RPG element. But that’s probably going to be a permanent year away… Most of the other details aren’t there yet, but they will materialise as I get further into the project.
I have done a bit of Android programming before, but never a game. I have chosen to use AndEngine as the game engine as I saw it recommended on StackOverflow quite a few times, and there is only so much research into which engine to use that I can be bothered to do… Let’s hope it’s as well documented as I have read it is.
I plan to keep this blog updated with what I manage to do, there will be code, screenshots, music samples, maybe even storyline if it ever gets one… Please write feedback or questions or whatever you like in the comments, I’ll get back to you when I can think of something witty to say.
Right, let’s go…