Having failed to update my infinite runner devlog for quite a while, a lot has changed in the last few weeks. I've added several more powerups to the game and had a lot of useful feedback about the mechanics, so here's a quick rundown of what's changed.
I had a lot of fun thinking up new powerups to alter the game; here's a couple I've added recently:
This one was probably the most challenging yet - this overrides the jump key and adds a different action which sets the player's
y velocity to a negative value, causing upward thrust. At the same time, the flame sprite is shown, and when the jump key is released, another custom callback switches the flame sprite's visibility off. Tethering the flame sprite's position to the player's position to look like a jetpack was fairly straightforward once I discovered Phaser.addChild, which ties two sprites together.
Similar to the laser and lightning powerups, the fireball gives the player three projectiles which destroys incoming obstacles. To differentiate from the other projectile powerups, fireballs cause obstacles to explode in a cloud of flame, and shrink the obstacle as it gets killed.
There's twelve powerups at the moment, and I'm aiming for around mid-twenties for launch.
I also posted the alpha version to Twitter and Reddit asking for feedback, and had really useful criticism:
- Poor contrast, quite difficult to see the player on the pale background
- Jumping felt 'floaty'
- Gap between obstacles was predictable which made the game too easy
Contrast was the simplest to fix (and also something I really should have noticed!) - I created a few different versions of the background with tweaked colours and chose the one which felt like the best fit:
The jumping was slightly trickier to alter: I didn't want to create a variable-height jump, where the jump continues while the jump key is held down (up to a maximum), since I want the game to work with a single button and work just as well on touch devices as on desktops. Eventually I decided to add a little animation to the jump, so it felt as if the player character was jumping rather than floating up:
Finally I played around with the timings and speed of the obstacles. Interestingly, some playtesters mentioned that they thought that the obstacles got faster the longer you stayed alive - this wasn't actually the case, but clearly the pressure made it feel that way! I decided to actually implement this, since once you got used to the game it was fairly easy to rack up scores of four- or five-hundred. This was relatively straightforward to implement - start a timer when the player spawns, then for every ten seconds the player is alive, increase a counter. The counter is then used as a multiplier for the obstacle speed, so every ten seconds the obstacles move ten pixels per second faster up to a maximum point: this means players shouldn't see sudden jumps in speed, while increasing the challenge for better players.
The obstacle timing was a bit harder to change - initially the obstacles are generated by a timer:
this.timer = game.time.events.loop(1000, addObstacle), which causes
addObstacle to be called every second (1000ms). Once the timer is running, the only way to alter the timeout is by changing the
delay property of the timer; I did this in
addObstacle, so every time an obstacle is added, the delay is changed to a random 100ms amount between 800 and 1100 milliseconds (i.e. 800, 900 etc) which has the effect of making some obstacles closer or further apart, while still allowing time for the player to land and jump again.
As a result, I think the game is looking a lot more polished - play it here and let me know what you think.