Keeping the droid in the maps.
Currently we have all the decks of the dreadnaught in place along with the player droid we can move around but there’s nothing stopping the player from going anywhere they please. While working on this game in Unity I had to basically set up collision areas on the tiles and Unity would mostly do the rest for me. Unfortunately Game Maker doesn’t have that nice feature, so we have to work out another way to confine our little droid to the “boundaries” of each deck. There are a few methods for doing this and I have opted for a separate tile layer that contains collision markers that the game represents as tiles.
As you can see in the above screen shot, you can see the collision tiles are much smaller than the game tiles (All game tiles are 64×64 pixels and the collision tiles are 16×16). The reason for this is that nearly all the tiles have areas where the droid can enter or overlap slightly. The screenshot shows a ‘Terminal’ that has half the game tile that you can move over, which is done deliberately. When I first started drawing the collisions, I filled the whole area with the Red collision boxes where then droid couldn’t go and there’s no reason not to do this. Doing it this way was just my preference because the droid is never in a situation where it could touch those areas, and it does save a few Kilobytes in the finished project, which would have been essential when writing this game in the days when the original Paradroid was made !
My original thoughts when I started the project was to have different collision tiles for Walls, Doors, Lifts, Terminals and charging stations but then it would mean having to check for walls and colliding with them, and, if it wasn’t a wall, set a flag stating I hit something else. That is alright to do but it starts to get very tricky when the player droid is moving diagonals, as you are having to read in three directions from the player sprite. I had it working like this but then I realised that there was a much better solution for the ‘other’ game objects.
The player droid code has gone through various iterations.
My first attempt was to draw tiles under the droid and, if there was a an existing wall there, then I would allow the droid to keep moving until its centre 4 tiles collided with a wall. This worked quite well as collisions with walls were pretty accurate but the code was getting too complex, as I was having to keep track of all the tiles that I had drawn under the sprite. I also had to remove tiles as the sprite moved off the tile which was another burden. Also, as you can see in screen shot above, I was checking 9 tiles constantly and, for some reason, if you approached a tile at a certain direction, you were able to float through a wall. What I found was going wrong was that there came a point when, as you can see in the screen shot above, tiles on either side of the droid were not drawing at certain pixel position, due to the droids x and y coordinates passing across the boundaries of two tiles.
I did try to find a way to work with this tile based solution for a while, but it never quite felt right, so I started to consider other options. Some of which aren’t even worth mentioning! 😳
My next major attempt was pretty much whats in the game now. In every frame I work out the 4 corners of the sprites bouncing box, then compare those pixels with tiles under the positions of the corners so If there is a tile in 2 of them, then we have a collision. I further refined this to check the top and bottom left boundaries when moving left, along with the bottom left and bottom right when moving down, and so on, all around the droid.
Now, for the astute readers, you may have noticed that the wall collision markers actually overlap the floor and the wall. I could have solved this by making the tiles 8×8 and then had to draw twice the amount of tiles to define the collision areas. This would have had a knock on effect of increasing the amount of memory to store all this data. We all know that we’re working on computers that that have more memory than we ever need to worry about simple optimisations like this, but sometimes, for a relatively simple bit of compromising, it’s good to make things work a little neater and tighter. Just because it’s easier to do something a lazy way because we don’t care about a minor memory saving, doesn’t mean we should. Old-school programmers made things tighter because they had to otherwise we would never have had some of the great games we did. Any way I digress! I just simply moved the bounding box in 8 pixels on each corner of the sprite, instead of smaller tiles! I preferred that, simples!!