Up until now I've been mostly focusing on the game technology and neglecting the gameplay. I'm going to address that a little bit by adding scoring to the game. I want to add some risk/reward to the gamplay - score higher by taking more risks. From now on I'm going to try to make sure that I remember to add gameplay features as well as tech features.
So how do you score in a shoot-em-up where you can't actually shoot? There are a few possible ways that come to mind:
To start with, I'm going to implement..
The gameplay is still far from perfect, but it's getting better - there's actually some point to dodging bullets now.
As usual, the source code is online as is the playable version.
So how do you score in a shoot-em-up where you can't actually shoot? There are a few possible ways that come to mind:
- Score bullets: Fired from spawners like normal bullets, but instead of hurting you when you collide with them they give you score
- Bullet grazing: Score points by flying very close to bullets but not close enough to be killed
- Score zones: Marked areas of the screen that award you points when you fly over them
To start with, I'm going to implement..
Score Bullets
Score bullet objects are almost exactly the same as normal bullets except for two things: firstly, they look different and, secondly, they give you score when you collide with them instead of killing you. Because I now need two bullet types that do almost exactly the same thing, I moved the common bullet parts into a new base class, called BaseBulletObject, and then implemented two derived classes, SimpleBulletObject and ScoreBulletObject:
You can see that the only difference is in the constructors for the two objects - they use different graphics and they have different object types. I added a new object type, scoreBullet, to the object manager and added to the main game state update() function so that I now test collision against both bullet types:
So now the player will collide with both normal bullets and score bullets, but how does it know the difference? The answer lies in a change to the Object onCollision() function - I now pass in the type of the object that was collided with. It's then easy to test in the player's OnCollision() and respond appropriately:
As you can see I also added a couple of global variables, currentScore and highScore. Those are printed to the screen by the main game state render() function.
You can see that the only difference is in the constructors for the two objects - they use different graphics and they have different object types. I added a new object type, scoreBullet, to the object manager and added to the main game state update() function so that I now test collision against both bullet types:
So now the player will collide with both normal bullets and score bullets, but how does it know the difference? The answer lies in a change to the Object onCollision() function - I now pass in the type of the object that was collided with. It's then easy to test in the player's OnCollision() and respond appropriately:
As you can see I also added a couple of global variables, currentScore and highScore. Those are printed to the screen by the main game state render() function.
Score Spawner
How to spawn these new bullets? I could have added a new spanwer, but I didn't want to do that. Instead I added a new variable to the spawner config: bulletType. You can set this to either 'simple' for the normal, deadly bullets or 'score' for the new score bullets. There are two places in the spawner code that actually spawn the bullets and I don't want to have to check the value of this variable with an if/then/else in both places. To work around this, I create a spawnFunction (using JavaScript Arrow Functions) which does the actual spawn. Inside the spawner's constructor I have this:
..and then when I come to spawn the bullet I can use the function like this:
You can look at the BulletSpawnerObject in the source code to see this in context, it's inside the objects.js file.
It's Still Not Fun Enough
After implementing score bullets the game was a little bit more challenging but still not that much fun. It felt like the screen was just too cramped and there was no room to maneuver. The relative speeds of the bullets and the payer also felt wrong. The bullets were moving faster than the player so dodging them felt harder than it should do. Both of these things made it feel like the player wasn't able to zip neatly around the screen, skillfully dodging bullets, and I think that's a vital ability to have.
To alleviate this I made a couple of changes. Firstly, I kept the player the same size but reduced everything else to 50% the size. This immediately felt nicer - the bullets now feel like little gnats, swarming around the player. Secondly, I slowed down the bullets and made the player a little faster (by changing the values in config.js). This also feels better because you are now more able to dodge the bullets at the last moment, using your reflexes. I kept the score bullets moving faster than the player because I like that you have to work harder to collect them.
I also made the score bullet's collision hitbox slightly bigger so that they are harder to miss when you do catch up with them. If you sail too close to a normal bullet but the hitboxes don't collide then you just count yourself lucky, but if you get close to a score bullet and you don't collide then you feel cheated. A lot of good gameplay design comes from making a game feel fair. If the player loses a life, or misses a bonus.. it has to feel like it was the player's fault, not the game's. So, actually, this smaller hitbox on the normal bullet and larger hitbox on the score bullet makes the game feel more fair - but it's too subtle for the player to really notice that there is cheating going on behind the scenes.
To alleviate this I made a couple of changes. Firstly, I kept the player the same size but reduced everything else to 50% the size. This immediately felt nicer - the bullets now feel like little gnats, swarming around the player. Secondly, I slowed down the bullets and made the player a little faster (by changing the values in config.js). This also feels better because you are now more able to dodge the bullets at the last moment, using your reflexes. I kept the score bullets moving faster than the player because I like that you have to work harder to collect them.
I also made the score bullet's collision hitbox slightly bigger so that they are harder to miss when you do catch up with them. If you sail too close to a normal bullet but the hitboxes don't collide then you just count yourself lucky, but if you get close to a score bullet and you don't collide then you feel cheated. A lot of good gameplay design comes from making a game feel fair. If the player loses a life, or misses a bonus.. it has to feel like it was the player's fault, not the game's. So, actually, this smaller hitbox on the normal bullet and larger hitbox on the score bullet makes the game feel more fair - but it's too subtle for the player to really notice that there is cheating going on behind the scenes.
Wrap Up
I added score bullets to the game in an attempt to make the game fun by adding an element of risk/reward. This worked to some extent, but I found that tweaking the relative sizes and speeds of the game objects made a bigger difference.
As usual, the source code is online as is the playable version.
Comments
Post a Comment