This post is part of my ongoing "Bite Sized Game Development in Construct 2" series, which can be found here : http://crunchygaming.co.uk/?p=18 . This series is aimed at beginners who want to get started in Construct 2 but are not sure where to start. In each episode I hope to start with an idea and then provide a step by step guide on how to flesh it out into a full game.
In this tutorial im going to have a look at how we can add some complexity to one of the modern staples of mobile and browser based games, infinite runners. Run as far as you can, jump the gaps, dodge the obstacles.
Look anywhere online or on any app store and theres no doubt that theres a huge amount of runner games out there, and with good reason, runners have simple, 1 button controls and quickfire, addicting gameplay, so how do you make your runner game stand out from the crowd? Lets have a look at a few options
Thanks to construct 2's templates, I can get started right away. There is an 'Autorunner' template which handles the basics of an infinite runner game for me, and it also comes with art assets already added! This allows us to get working immediately on new ideas straight away, but for everyones sake, if you publish a game in this manner, using someone elses assets, please make sure to provide credit!
Now, lets get cracking with some new ideas to shake up the basic infinite runner game!
Idea 1 : Increasing the difficulty
The core gameplay is not particularly hard, after a while you can easily master the jumps such that its rare that you fall down, so it quickly turns into a game of who can just keep playing longer!
How can we add another layer of challenge to the game? A lot of infinite runners have obstacles to dodge, so lets try implementing that.
This can be quite quickly done by simply spawning an object at a random y value (though make sure the possible values are high enough so the player actually has to dodge it!) after a random amount of time passed. We'll use a simple rock for now, but we'll give it the rotate behaviour to make it look a little less lifeless, and don't forget to destroy it once it reaches the end of the screen!
Here is what we have now, with a rock coming across the screen at random intervals, the player must now both make the jump and dodge the rock. https://dl.dropboxusercontent.com/u/245987915/Infinirunner%20Rocks/index.html
Idea 1.2 : Difficulty adjustments
Playtesting shows that the game is now more interesting to play, but can be sometimes frustrating, as a rock can sometimes appear in a place that, due to the players fixed position and jump height, makes it impossible for the player to make the jump without hitting the rock. This is not very common, but when it does happen it is a very unfair way of making the player lose.
One way to fix this is by giving the player more control over their jumps. At the moment the player character always jumps at the same height, what if we could put the player in control of the height of the jump? We can easily accomplish this by changing the Y vector of the platformer when the input used to jump is released. Basically, the longer the input is held down, the higher the character will jump. Another good idea is to edit the gravity and jump strength to give a slightly higher jump now that the player has the ability to shorten it.
Here is the result after adding the improved jump control mechanic : https://dl.dropboxusercontent.com/u/245987915/Infinirunner%20Jump%20Control/index.html
Idea 1.3 : Further difficulty adjustments
Even with this system in place sometimes the rocks and jumps can align in such a way that makes performing the jump extremely difficult. Lets add a dash that can make the player character invulnerable for a short time. We can activate this dash by touching the screen while the player character is in midair. We could make the dash just last a certain amount of time and allow the player to activate it whenever they want, but that might make the game a little too easy. Lets have a finite amount of dash that the player can use, and have it refill over time so it can be used often, but not all the time.
The same one button input that we used to jump can be used to start and end the dash. Similar to when the player jumps, when the input is held down, the dash starts, and when the input is let go, the dash ends. When the dash is active a global variable counts down, and when the dash is not in use it counts back up again, just slower. If the dash variable hits 0 the player characters dash immediately ends even if the input is not released.
To show the player how much dash he has, we can create a 'health bar' that simply uses the value of the dash global variable we already have as its width. Now the player can see how much dash they have at all times. The last thing we need to do is add some sort of sprite to the player character to show they are dashing.
Now we have a pretty decent difficulty level that we can vary in various ways. The player can vary the height of their jumps and in an emergency dash through any rocks they cannot avoid. We can vary the amount of dash the player has and how quickly it refills, as well as varying the size of the rocks, and how often they spawn. We can playtest and adjust these values until we are happy with the difficulty level. I am going to make the game a little harder by decreasing the amount of maximum dash the player can use, increasing the rate it is used up, and increasing the rate at which rocks spawn slightly.
Now with the obstacles, the varying jump height and the dash attack added, this is what we currently have : https://dl.dropboxusercontent.com/u/245987915/Infinirunner%20dash/index.html
Idea 2 : Changing the scoring system
Most infinite runners simply count how far you've travelled (which in most cases is actually just a timer that really says how long you've survived as opposed to how far you've run), while thats a pretty simple and decent way of measuring a score in this case, the only way to win is to simply outlast everyone else. There isnt anything else for the player to aim for, and no extra risks the player can take to get that addtional edge on the scoreboard. Lets add something.
A quick and easy way to add a new method of scoring that the player can aim for is to add a collectable object for them to attempt to collect. However, we already have an object that spawns thats the player can interact with : the rocks! Lets make it so the player gets a point every time he dashes through a rock and destroys it when he does! This introduces a risk/reward element into the game, as the player now has a choice. They can either conserve their dash and avoid rocks, or use it up, bash through it and pick up the points, potentially using up dash power they may need later.
There are many ways you can add the score of interacting with an object to a game that already has one. In the scirra arcade, you can have a 'score' and a 'time'. In a case where several players have the same score, the one with the quicker time will be placed highest on the leaderboard in the arcade. So I will use this method, except for that instead of the quickest time, we want the game to sort by longest distance. How to achieve this in detail can be found in the documentation, but for now, I'll simply create a global variable that we increase every time the player hits a rock while dashing, and have it displayed at the top of the screen.
This really only requires a very small change to the code, but nonetheless, here is the current game with the new scoring system added : https://dl.dropboxusercontent.com/u/245987915/Infinirunner%20Scoring/index.html
Idea 3 : Adding a minigame/something to break up the action
We now have a good base game with a good challenge behind it and a good scoring method, but how about we add a little something extra? Lets add some randomly generated minigames. Im going to spawn an object for the player to collect at random intervals. Collecting the object will 'pause' the running part of the game, and will give the player another objective to complete for a short time, before the runner is resumed. For this example, I am going to massively increase the rock spawn rate and allow the player to touch on them to destroy them for a short time, while making the player character invulnerable to being hit by rocks. I will also stop the game world from scrolling.
To achieve this, I set up a variable 'minigame', and when it is set to 0, the normal game state is being played. When I set to 1, various actions happen that set up the minigame state, for instance, the background and the floor stops moving, the player character's platformer behaviour is switched off. I then set the minigame variable to 2, which is the minigames state. During this state, the rocks spawn more frequently, touching the rocks destroys them and adds 1 to the score, and both the player and rocks are immune to collisions between them. When the timer for the minigame runs out, I set the variable to 3, which allows me to get the background and floor moving again, before setting the variable to 0, the original game state, and allowing the game to resume.
There is a lot of meddling around with numbers at this point, and the only way to get the correct result is to test them and test them again. For instance, during the mini game, rock spawn is massively increased. However, the rocks have to stop spawning with just enough minigame time left over for them to clear the screen, otherwise they will hit the player just as the timer runs out and unfairly end the game.
The last thing I need to do is set it so that touches destroy the rocks and add to the score while the minigame is active. Once that is done, the current state of the game looks like this : https://dl.dropboxusercontent.com/u/245987915/Infinirunner%20Minigame/index.html
Idea 4 : Adding a layer of customisation and final touches
Ok, we now have a decent game with a good contextual touch based input (that is to say, the only input needed is to touch, but what a touch does changes depending on what is happening in the game), with a fair level of difficulty, a good risk/reward system and a minigame that breaks up the action and awards more points.
The games mechanics are mostly finished, but we can add more value to the game by offering up customisation options to the player. These options can simply come in the form of colour changes to the background, floors, player, or other objects, and can also be a really good way of monetising your game, by selling customisation options that people can buy if they wish to support you.
I am going to implement these customisations outside of construct 2, in a separate image editor. I'll simply change some of the colours of the floor blocks, player character and rocks. You can do this in a number of ways, how you do it is not really important, but you should have a minimum of three distinct colours or styles.
Implementing them however is somewhat harder. For the player and rocks, we can just add the new colours to the sprites animation, and have the game change what frame is being displayed based on what style is being picked. For the blocks however, as they are a tiled background, I will need to duplicate all the events that spawn or use them, and only allow the game to execute one set of events depending on what style the player has picked.
Now we need a way for the player to change style. This is simple enough. We need a dialog box to come up before the game begins, which allows the player to select a style, and changes them on the fly so they can see what it looks like before starting the game.
The game is mostly complete now, however some last touches will help to make the game play nicer. Lets add some sound effects and visual effects. I will just use the effects provided in the Construct 2 freebundle to save time, as they are very effective. I will however add a 'lightning bolt' sprite that will briefly flash up during the minigame when a rock is destroyed. I will also darken the background while the minigame is active. This will give the effect of showing the player character has some sort of special power during the minigame.
The next little thing we can do is improve the touch detection for the rocks on the minigame. Playtesting has shown that the rocks can be hard to hit, even when it looks like the player has felt they have touched on them directly. We can do this by increasing the size of the collision polygon used by the rocks, but only when the minigame is active otherwise rocks will kill the player character easier outside of the minigame.
Another easy thing to do is add high score integration with the scirra arcade. This is as simple as adding the Arcade object to the game, and then activating a timed high score event when the player fails. Of course in this case, the score is the number of rocks smashed, and the time is the distance.
The last thing we can do for now is add an end game difficulty spike that slowly increases as the game goes on. While the difficulty changes we implemented earlier have made the game better to play, its still easy to keep on going for a long time, so making the game slightly harder as the game goes on should give the game a more focused ending. Lets make the game increase in difficulty as the rock destroyed score increases. An easy way to do this is by reducing the respawn time of the rocks every time a rock is smashed.
There are many more touches we could add to a full game to make it look good on release, like a better start screen, further integrations to the scirra arcade and such, but for now, this is a good example on ways you can add to and evolve an idea that already exists.
The last version of my infinirunner game is linked below from the Scirra Arcade, and is best played on a mobile platform.
In my next tutorial, I'll look at ways we can use Construct 2's new multiplayer functionality to pit players against each other or alongside each other.