In this session we're adding Combat to our game. This involves creating Enemies and programming a sword-swinging action. This should give a good starting-off point for adding more complex combat later like projectiles.
To download the example game this week, click the link below:
We will continuing on from last week. If you weren't there or lost your code, you can use the example game above.
The first thing to do is create our first enemy. Visit the Assets tab and create a new Image. This image should be the image of our first Enemy.
True RPGs have a whole list of Enemies. This list is sometimes written as a book called the Bestiary.
Next, we need to turn this image into a Sprite.
Add a new 'set mySprite to sprite [ ] of kind player' to 'on start'.
First, rename mySprite to something sensible. Next, replace the [ ] with the new Asset you just drew.
Finally, change the kind from player to enemy.
At the moment, the enemy always appears at position 80, 60. To change that we're going to use the block 'set mySprite position to x 0 y 0'.
Drag this in under where you created your enemy sprite and change mySprite to be correct.
Now change the x 0 and y 0 to something else to move your sprite around the map.
We can easily get our enemy to be a bit more unpredictable but spawing it in random locations.
You can replace the x 0 and y 0 with pick random 0 to 255.
The simplest enemy behaviour is to have the enemy follow the player. This can be done with the 'set enemySprite follow playerSprite' block.
Drag this into 'on start' and change the variables appropriately.
There is a more complicated enemy movement available that uses a 'sight cone' or 'sight circle'. Only if an enemy is inside that area does it react to the player.
Create a new sprite of a new kind to act as a large ring around the player. Using 'on update' set its position to that of the player.
If the enemy touches that ring, only then set the enemy to follow the player.
One enemy is fairly easy to dispatch.
To make more, surround all of our enemy code so far with a 'repeat 4' block.
Before we program the attack we need our player to have an attack pose. Therefore we need to visit the Assets tab once again and make one.
To actually perform the attack we'll need the user to press a button. So, we're going to use the button event called 'on A button pressed'.
This does NOT go in on start, but instead is a new even all on its own.
We'll need a way of tracking whether or not an attack is currently happening. For this, we're going to create a variable that stores the value true if an attack is happening and false when it is over.
Create a variable called swordSwung or similar. Then, set this to true inside 'on A button pressed'.
Hint: True is found in the Logic panel.
Now we've stored the status of the attack, we can change the image of the player sprite.
From the Sprites panel, find 'set mySprite image to [ ]' and place it under where we set our variable. Don't forget to change all the values to the right ones.
To finish off the attack, we need to pause for a little while, then do everything we just did in reverse.
First, place a 'pause 100ms' block and change it to the time you want.
Next, reset the player's image and set the variable to false.
Now we have a perfectly working attack!...
Except the Enemies don't know what to do with it.
We're going to use a new event called 'on sprite of kind player overlaps otherSprite of kind player'
Next, we must change the last kind from player to enemy.
Inside this event we need to do the following:
Check if the sword is being swung.
If it is, kill the enemy.
If it isn't, kill the player.
To do this we'll need an 'if true then.... else' block from the logic panel.
To tell if the sword is swung we need to check wether our variable swordSwung is equal to True.
Using a '0 = 0' block from Logic, assemble the following phrase:
'if swordSwung = true then...'
If true, we can destroy the enemy. However, we only want to destroy the enemy that we're currently colliding with. We need to use the otherSprite.
From Sprite, find 'destory mySprite'.
Now, drag otherSprite from the 'on sprite of kind player collides with otherSprite of kind Enemy' block and play it in the destroy.
Two things left:
In the else part of the if, we should probably make the player lose a life. This is done with 'change life by -1' found in the Infor panel.
There's no use in removing lifes that don't exist. To create lives, place 'set life to 3' in your on start.
Currently, if our enemy hits the player, it's instant game over. This is because once the enemy hits the player there is nothing stopping it from hitting the player again instantly.
In the Games Industry this is fixed either with knockback or i-frames or both.
In some games, if the enemy hits the player, the player (or the enemy) get knocked backwards a little way.
This stops the collision and give the player a chance to fight back.
To implement this, make the player's x or y change by a small amount (10 to 20 pixels) when they touch an enemy without attacking.
i-frames or invincibility frames are the few seconds after an attack that a player or enemy is invincibile for.
To make this happen, we need an 'isInvincible' variable.
Firstly, only if 'isInvincible' is false should the enemy do damage.
If the enemy does do damage, isInvincible should be true... but only for a second or two before being set to false again.