Skip to main content

Going Back To My Roots


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 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:


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.

The codebase is available here and the game can be played online in your browser here.

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

Popular posts from this blog

Set The Controls For The Heart Of The Sun

When we last met, I had just started work on a level editor. I'd got as far as adding the ability to select an object and move it around, and then I added an undo/redo system using the command pattern. That was a good start, but dragging items around the level is only fun for so long. What I really want to be doing is.. ..editing the properties of the bullet spawners! And I want to be doing this in realtime as the game plays so that I can immediately see what effect my changes have made to the gameplay of the level.

World In Motion

In the last post I touched on how easy it is to score in this game - you can just camp out on the score bullet spawner and watch the points rack up. I'm going to add a little delay to the score bullets so that they start out in a deactivated and uncollectable state, and then change to active and collectable after a short time - say, half a second. To make it clear what state they are in I'm going to add code to let me change the look of Objects and allow them to be animated.

The Long And Winding Road

I started this blog back in November of last year. My aim was to document the development of a Bullet Hell shoot-em-up, written in JavaScript. Here we are, six months later, and lots has happened. With 20 posts already written, I thought that now would be a good time to take stock of what I've already done, and to look to the future and see what's to come.