I have a CBM Pet (Rockwell 6502, 32K of RAM, clunky keyboard, years old and still working last time I tried). My favourite game was Space Invaders. The CBM Pet version was a good emulation/clone of the original Atari arcade game.
At the time, I was intrigued by the game and wondered how one would go about programming such a thing. I thought that it would be a "Nice personal challenge" "One day!" to program it but, I never did.
A few years ago, to try a bit of Android development and to get familiar with Java, I followed the FutureLearn course: "Begin programming: build your first mobile game" from the University of Reading. Try this link https://www.futurelearn.com/courses/begin-programming or search for "begin programming" on https://www.futurelearn.com/.
The course gives you a canvas and shows you how to build simple pong and paddle type games in Java for Android. I thought that the canvas could be good springboard for Space Invaders and wrote this clone for Android in Java. It took about 40 hours to get the program working, and then loads of extra time refining assets and "improving" it.
The game play is complete but, I still need to make the startup screen and the wrapper to handle high scores, 1 or 2 players, etc. The game play works OK.
As well as the emulator I have run the game play on several physical phones: a Sony Xperia Z, a Sony Xperia XZ, and a Samsung S5 with no issues.
One day I’ll finish it!!
Before we go any further I must point out that the code is not a model work or an example of how you should code in Java; it is simply my first jaunt into the Android-Java world. The work was an exercise for me to learn something about Android development and Java, and a challenge to get something running that looked like Invaders and is playable - in my opinion I achieved both of those ends. If I was to start all over again I would do it differently, there is a huge, "If I knew then what I know now" element in the whole thing but, I didn't know then what I know now and I am certainly not going to do it again just to make it "nice"!!
The code from the course provides a canvas where all of the visible game objects are drawn, and a framework in which the game progresses updating the positions of the objects and their state, normal, exploding, gone, etc.
First, the objects in the game are created and initialised, then a cycle is started where:
All of the code for the game logic is in the source file TheGame.
The only class that I created in the program was "sprite". Sprite is used for all of the on-screen objects, like: invaders, turrets, shells, score numbers, etc... Most objects are just one sprite, e.g. an invader or a shell, but, a fort is a set of 12 sprites 4 wide and 3 high for each "brick" in the fort so that it can be blown up a brick at a time.
The sprite type (invader, shell, etc.) is defined by the variable "rank". The values of rank are given in the code snippet below. This would probably have been better handled by making separate classes for the objects based on the sprite class as a foundation.
Typically, a given sprite type will have two or more bitmaps associated with it, for example, an invader has two bitmaps that alternate as the invader moves sideways, a bomb has four. The sprite has an index that is used to keep track of which bitmap was shown last to make it easier to know which one to show next.
A sprite has the following parameters:
This is the sprite parameter definition from the code, it also lists the rank values for different types of sprite:
public int Rank;
// Rank defines what type of sprite a given object is
// Rank = 0..2 for Invader types 1..3,
// 4 for Saucer,
// 10..12 for bomb types 1 to 3,
// 20..25 for Fort 00, 01, 03, 11, 12, 21
// 30 for Shell
public int PosX;
public int PosY;
public Bitmap DisplayedIcon;
// LastDisplayed is a reference for the last bitmap displayed for this item - it is
// used to flip the bitmaps for the different Invader Ranks so - if last was 1 display 2, etc.
public int LastDisplayed;
public boolean Hit; // Hit means that the Sprite has been hit by a missile
public int Score; // Score is the score if that Sprite is hit
public boolean Gone; // means that the Sprite is no longer visible after being hit
public boolean Fired;
public boolean Flying;
The PlayCanvas is where the sprites are placed and have their places. Different sprites have specific positions on the canvas where they each belong or have areas that they may move around in. This PlayCanvas is 15 rows high and 15 columns wide. The block of invaders is 11 columns wide by 5 rows high. You can compare these lists that describe the content of the rows and columns with the picture of the game at the top of this page. From top to bottom the rows are:
Column contents are:
The bottom row contains:
When the program starts, the first tasks are: to create all of the objects, load all of the bitmaps and sounds, initialise variables for all of the objects, assign the first bitmaps to each object, etc.
Once initialised, at the start of each cycle of the game the function UpdateGame is called. This is where new positions are calculated for all objects, collisions between shells and bombs, and other objects are detected and the status of objects is updated.
Next, doDraw is called and the following items are drawn on the canvas as described in the lists of locations above:
The game continues until you lose all of your lives, or the invaders come down to the level of the turret (you lose!), or the last invaders is hit (you win!). For a score > 1500 you get an extra life. As your score increases more bombs come into play.
In the "real" game, if you hit the last of the invaders the game restarts with the invaders starting a little lower. So gradually you have less and less time to dispatch the invaders. This bit is not implemented yet.
If you would like to play with the invaders game you will need to get Android Studio the latest version that I have used to run the code is V3.5.3. Then you can download the invaders code zip file here. (Right click on the link and choose "Save Link As...")
SHA256 hash of MOOCSI20200316-B.zip: f1c9d93161493078e2d345fb124c1cab247c6f007fd72eea1cff00ac66285e05
Tip: To calculate a file hash in Windows see this tip about using CertUtil
If you download my Android Java code for Invaders or have any questions about it then email me at comments@chisholm.nl. to let me know what you managed to do with it.
The code is provided as is, no support implied and no liability for whatever it does or doesn't do. I will endeavour to answer any questions that you may have about the code but the level of support that I can provide is limited. Getting Android Studio running can be challenging but there are various places where you can get documentation or help, not to mention the Android Studio website itself. I found the documentation there very helpful