So, have you played it yet? Yep, it’s complete impossible to control, and there are bugs! I’m going to cover all the ones I’ve found now, but not initially give you any code to fix them – try to fix them yourself first…
It’s a bit quick eh?! This is a very graphic demonstration of the difference between BASIC and machine code. In BASIC if you press a key to move the player it does so after roughly half a second or so? In machine code, you can move multiple places in that same space of time – so much so that your first attempt at moving is likely to fling the sights completely off the edge of the screen!
To resolve this we need to slow the game down a bit, and add a delay into the main game loop. We wrote a function for line 5 to pause for a second, and so can use that same method before we start drawing at line 50, or before we jump back at line 140, to slow things down a bit. A second is probably too long though – perhaps try a five-frame delay at first?
We already fix one bug with the code where it wasn’t correctly checking to see if the player was aligned with the enemy, but actually there’s another to do with that. The two positions are compared exactly – that’s good – but if you try to place the player exactly where the enemy is, it’s actually shown as being one place to the right, as the enemy graphic is shown at column C, but the player’s ‘+’ graphic is actually shown at column B+1. So there’s another little bug to be fixed – either by drawing the enemy graphic one column across (C+1) or draw all three rows of the player graphic one column back – so the two are aligned once more.
Converting the game to machine code has introduced two problems. Firstly, the BASIC ‘RUN’ command at line 200 would clear the screen as it restarted the code. Our game doesn’t do that however, but should. We can either do that at that start of the game – line 5 – or before we jump back to it at the end. We’ll need to fill at 32 columns in all 24 rows with space characters.
The second problem with the machine code, although it was also partially a problem with the BASIC version as well, is that the player can move the sights off-screen. In BASIC that’s not a problem – it will validate and check everything during the PRINT command – but we don’t do any of that, so when the sight is off-screen it’ll actually still be drawing, but to other areas in memory, and so if you move it around enough you’ll eventually corrupt either the game code, or something in the system variables or display memory which causes a crash. There are two solutions to this – either prevent any of our printing from being off-screen – i.e. restrict the movement of the player to the screen – or write a nice print routine to handle the issue. In a game like this you probably want to keep the sights visible all the time, so clamping could be the best solution, but remember that the player’s sight graphic is surrounded by 8 spaces, and so would have to be stopped from ever reaching the first or last row or column.
Another problem with the BASIC version is that the enemy is drawn, and then the sights with those 8 spaces around it. The spaces are there to remove the ‘old’ sight graphic as you move. It’s a lazy method, but it works. It does mean however that if you are one space away from the enemy then it is removed from the screen by one of those spaces – making things a little more difficult. The quick solution to this is to draw the enemy after the sights. The better solution is to never draw all those spaces around the sights, and remember to replace the sight with a space before you move in any direction, so erasing the graphic at the previous position.
After all that, you actually have the groundings for quite a fun little game. Add a menu to the start, a HUD to show a score or lives, have the enemy change position every five seconds or so instead being still, have multiple enemies attacking at once….