One thing that I always try to do when I'm writing a game/app/whatever is to use simple placeholder graphics. There are a couple of good reasons for this. Firstly, it makes you concentrate on the gameplay - if the game doesn't feel fun with simple graphics then it's not going to feel fun however good you make the graphics. When I worked at Denki we had a rule about not making our graphics any more "real" than basic coloured shapes until the core gameplay felt fun. Secondly, it gives a blank canvas to whichever artist comes in to create the proper graphics. At some point in the development of this game I'll get an artist in (applications for the position are open!) and I don't want to prejudice their view of how the game should look - I want the artist to tell me how it should look. Finally.. it stops me from getting distracted and spending too much time tweaking the graphics when (see first point) it doesn't make any difference at this stage.
Up until now I've been using graphics taken from Xevious as placeholders, but I want to take a step back and go for something more basic - simple shapes filled with flat colours. The interesting thing about doing this exercise was that I haven't been totally happy with the core gameplay, but it wasn't until I stripped back the graphics that I realised what was wrong.
Stripping Back
Taking the graphics back to primitive shapes and colours is a pretty simple task - you can probably imagine how many minutes it took. It was important not to strip them back too far though. There are some key elements that I didn't want to lose - the indication of a spawner firing (now a simple change of colour), the brief flash of the zapper's laser beam charging up before it fires and the player's ship changing to white when it's hit. All three of these elements are crucial in helping the player negotiate the gameplay, and now that everything else is stripped back they are all clear and easy to see and understand. Maybe they'll get softened up later on, but for now it's good to see them.What? That's Not Fun!
As soon as I had done this I noticed that collecting the score bullet felt... horrible. The player only has a tiny a collision area and that makes it hard to collide with the score bullets. This collision map was intentional and it was intended to make it easy to dodge bullets - but it also obviously makes it hard to collide with anything when you actually want to. I had sort of known this and that's why I had made the score bullets bigger than normal bullets - to compensate. This only sort of worked, and now it was obvious that it wasn't good enough.
The solution was to allow each object to have a set of different collision maps for different situations. The player should have one map (a small circle area) for colliding with normal bullets, and a much bigger one (the size of the entire ship) for collecting score bullets. This turns out to work really well, and now you can dodge normal bullets just as before but collect score bullets much more easily.
Once I'd added this collision code, I realised that it would be very simple to add another feature from my feature list - bullet grazing. This i where the player scores points for being close to bullets, but not close enough for them to kill you. After doing normal bullet collision (small player collision map vs. normal bullet map) I collide them again using the the player's "full ship" collision map. If this results in a collision then, instead of taking damage, the player scores a point. I also detect this in the bullet and change it's colour as a small visual clue that you've successfully grazed it. Gameplay-wise you've now got a choice: chase the high scores with risky bullet grazing or by collecting the safe, but lower value score bullets.
The solution was to allow each object to have a set of different collision maps for different situations. The player should have one map (a small circle area) for colliding with normal bullets, and a much bigger one (the size of the entire ship) for collecting score bullets. This turns out to work really well, and now you can dodge normal bullets just as before but collect score bullets much more easily.
Once I'd added this collision code, I realised that it would be very simple to add another feature from my feature list - bullet grazing. This i where the player scores points for being close to bullets, but not close enough for them to kill you. After doing normal bullet collision (small player collision map vs. normal bullet map) I collide them again using the the player's "full ship" collision map. If this results in a collision then, instead of taking damage, the player scores a point. I also detect this in the bullet and change it's colour as a small visual clue that you've successfully grazed it. Gameplay-wise you've now got a choice: chase the high scores with risky bullet grazing or by collecting the safe, but lower value score bullets.
The Collision Code
As always with collision code, there are two elements to consider: collision detection and collision response.
The changes to detection are small but spread over several pieces of code. First, the object animations now have a map of named collision maps. For example, here's the player:
The collide() function in the collision manager can now be told which map to use for each set of collision tests. Here's the code from GameState.update():
In the collision response code, I now pass in the type of collision map that was used. This can be seen in the SimpleBullet.onCollision() function where the response depends on whether it collided with the player's "hit" or "graze" map:
The changes to detection are small but spread over several pieces of code. First, the object animations now have a map of named collision maps. For example, here's the player:
The collide() function in the collision manager can now be told which map to use for each set of collision tests. Here's the code from GameState.update():
In the collision response code, I now pass in the type of collision map that was used. This can be seen in the SimpleBullet.onCollision() function where the response depends on whether it collided with the player's "hit" or "graze" map:
Wrapping Up
I stripped back the graphics to the most basic representations and this helped me realise that a couple of core gameplay features needed fixing. I improved the collision system to fix these problems and then realised that I could easily implement a cool gameplay feature that I've been wanting to add.
Next
In the next post I'll look at loading levels from data files and defining what the format of those data files should look like. If that's not exciting enough for you, I will also be taking a peek into the thrilling world of data validation! These will be the first real steps towards getting an in-game level editor working.
Comments
Post a Comment