Arcodia - A ZX Spectrum Port

I present to you my second Arduboy game - ‘Arcodia’.

A port of the classic ZX Spectrum game ‘Arcadia’.

#INSTRUCTIONS
Left = Move ship left
Right = Move ship right
A = Fire ships thrusters
B = Fire lasers

Each wave gives you a different enemy to beat. You have 60 seconds till the next wave. When you kill all enemies in the wave, another wave will appear until the 60 seconds are up.

On the next level you will be presented with a new enemy and another 60 seconds to beat it.

Each enemy looks different and moves in a completely different way from the last. Only by playing the game will you learn how each enemy moves.

There are 2 enemies to beat in total. After all 12 enemies have been beaten you will start again on enemy 1. However, this time you will have 1 more enemy in the wave and the movements of the enemy will be more violent and erratic.

You start off with 5 lives and unlimited ammo.

#SCREENSHOTS

#VIDEO

#LINK TO FILES
Files

This game is really down to the wire with memory usage so I had to take out fancy loading screens and cut out some of the animations too. However, the core game is unaffected.

Have fun!

Follow me on Twitter for news of my latest game developments.

Mike McRoberts
@TheArduinoGuy

4 Likes

Case statements will kill you. Anywhere you can changing them to array lookups will save a ton of space… for example with CheckLaserHit() for example instead of 12 case statements you should have a PROGMEM array with the all the offsets (including the ships with 0 offets) and then look into that array depending on the enemy and find the proper offsets to add.

You may not be able to do this for every case statement but if you think about it I bet many of them can be collapsed into behavior you could descirbe with numbers, not code… the more the code for all 12 enemies is similar and you pustthe differences down into the data the smaller your program will get.

1 Like

You are right.

I have created

const byte PROGMEM bitmapOffsets[24]=
{
    7,9,7,11,9,10,7,4,7,9,9,9,9,9,10,7,9,9,9,9,4,9,9,9
};

and changed CheckLaserHit to :-

 void CheckLaserHit()
{
        byte offsetY = pgm_read_byte(&bitmapOffsets[(monstersIndex-1)*2]);
        byte offsetX = pgm_read_byte(&bitmapOffsets[((monstersIndex-1)*2)+1]);
        for (int index1=0; index1<8; index1++)
        {
                for (int index2=0; index2<numMonsters; index2++)
                {
                        if (lasers[index1].age>0 && monsters[index2].state>0)
                        {
                                int topB, bottomB, leftB, rightB;

                                topB = monsters[index2].y;
                                leftB = monsters[index2].x;
                                bottomB = topB+offsetY;
                                rightB= leftB+offsetX;

                                int topA = lasers[index1].y;
                                int bottomA = lasers[index1].y+3;
                                int leftA = lasers[index1].x;
                                int rightA = lasers[index1].x;

                                if (topA <= bottomB && bottomA >= topB && leftA <= rightB && rightA >= leftB)
                                {
                                        monsters[index2].state = 0;
                                        lasers[index1].age = 0;
                                        score=score+level;
                                        sprites.drawSelfMasked( leftA-4, topA-4, POP, 1);
                                }
                        }
                }
        }
        arduboy.display();
}

This has saved 478 bytes.

I will do the same for the CheckShipHit function too.

Thanks a lot.

Mike

Your collision checking should probably also be a function that you pass shapes to instead of inlined… so then all your hit functions would call the checkCollision function to return true/false rather than repeating that code 2-3 times.

The trick is to look at your code and see repeated patterns… anytime you see a repeated pattern or the same code more than one there is usually a smaller (and often better) way to write it.

May I host this on the Arduboy Manager repo?

Sure. Go ahead Jonathon.

Uploaded it just now!

1 Like

Getting this message!

@mockfrog might be able to help. This could potentially not be a bug at all since it looks like it’s just the save location for the game.

The game doesn’t install onto the Arduboy.

Hi guys,
I had a look into it. The problem comes from wrong binary files in the .arduboy file:

"binaries": [
{
  "title": "Arcodia",
  "filename": "Arcodia.ino",
  "device": "Arduboy"
},
{
  "title": "Bitmaps",
  "filename": "bitmaps.h",
  "device": "Arduboy"
}

these propagate into your repo.json @crait

What’s wrong with them? These 2 files are both inside the arduboy file.

Those are source code files and aren’t binary files. The only files you should be including for your game in the binaries section is a pre-compiled .hex file. If my memory serves me correctly, use the Sketch > Compile Binary option in the Arduino IDE to compile a .hex file that will be saved in the same directory as the .ino file.

http://community.arduboy.com/t/what-are-hex-files/2897/2

It wasn’t loading onto the Arduboy via the Arduboy Mate app for Android.

I was able to load Arcodia via the usual method.

Ahh yes. I did it correctly for Jet Pac but not for this one.

Sorry about that. I’ve fixed the .json and .arduboy files on the GitHub.

Jonathon you will have to redo your repo.

Cheers,

Mike

Just a reminder for @crait to change this on his repository as it won’t load from ArduBoy Manager.

Just downloaded this game and started playing it. It is super fun and the code looks interesting. Im hoping to learn from it to write my own vertical shooter.

1 Like