Chapter 7. Making a Battle Tank Game

You have learned a lot up until now. The last thing we covered was how to store multiple values in an array or dictionary and how to access them. You also learned about WebStorage that will store data in the player's computer; this data can be accessed when the game is played at a later time.

However, now we will develop on what we know so far. I will show you more ways in which we can use arrays other than to store the player's score. We'll also create a new kind of enemy. Earlier, our enemies were really simple and easy to make; they just went down and shot straight down. Now, we'll give our enemies a little AI to make them cleverer, by making a battle tank game.

In this chapter, you will learn how to:

  • Combine an array with the gameplay mechanic
  • Group objects in a group
  • Create a turret that can detect nearby enemies
  • Play music and sound effects in the game
  • Make simple AI for enemies

Setting up the layout

As always, we'll begin by creating the layout for our game. Unfortunately, for us, there is no sprite in freebundle.zip that fits a battle tank game. However, we can use two sprites to make a tank: one sprite for the base of the tank and another one for the turret.

First, add two sprite objects to the layout and name them tankTurret and tankBase. The tankBase sprite is from UI elementsAdventure pack. Pick any square icon; in this example, I will use the buttonSquare_blue_pressed image. For the turret, pick an arrow image that points to the right, such as arrowSilver_right. If you place these images on top of each other, you will see an icon similar to the one shown in the following screenshot:

Setting up the layout

This looks good enough for a tank. However, for it to be called a tank, the base and the turret must act like one, that is, if one is created, so is the other, and if one is destroyed, so is the other. How do we do this? Well, Construct 2 has a feature called container to group objects together.

Using a container

So, what is a container? A container is a feature in Construct 2 that eases the creation of an object composed of more than one object. Sometimes, when making a game, you'll have an object that is too complex to be represented in one object. Using a container, we can treat multiple objects as if they are one. In our example here, we have a tank that consists of two sprites: the base and the turret. Adding these two to a container enables them to rotate and move independently; they also have their own instance variables. This is useful, for example, when you want to create a side-scrolling game in which you can make the hand and sword check against collision with a target enemy to hurt them and the player's body to be checked against collision with the enemy's attack.

All objects in a container have the following traits:

  • If one object in a container is created, all the other objects in the same container would also be created
  • If one object in a container is destroyed, all other objects in the same container would also be destroyed
  • If an event manipulates one object in a container, all other objects in the same container would also be manipulated

These traits are made because Construct 2 treats a container as one object.

Now, let's create a container. To do so, select one of the objects you want in the container, such as the tankTurret object. After that, you can see the Container section of its property in the Properties bar. If it doesn't have any container yet, it will say No container along with a blue Create link beside it; click on the link to create the container.

Using a container

Construct 2 will open a new window to select objects to add to this container. For now, we only have the tankBase object; so let's add this, click on it, and press the OK button. The tankBase object is now added to the container; if you look at the Properties bar, you'll see it. Click on the two objects alternately and look at the Properties bar. You can see that they are added to each other's container.

Using a container

You can add another object to that container or remove an existing member from it. Now, every time a tankBase object is created, Construct 2 will also create a tankTurret object. However, it is not enough to have them created at the same time; we want the turret to stick to the base so that when the base tank moves, the turrets follow.

Pinning an object to another object

We can pin an object to another object using a behavior called Pin; this behavior will pin an object to another, making it maintain its distance and angle with the object it's pinned to. As we will mainly move tankBase and make tankTurret follow it, we will add this behavior to the tankTurret object.

Pinning an object to another object

After adding the Pin behavior, we will use it to pin to another object, in this case, the tankBase object. This pinning is done by code, and we will pin the tankTurret object when the turret is created. The turret is created when the base is created, so we'll pin the turret when the base is created. While pinning, we have to decide whether to pin by position only, or angle only, or both.

Note

Pinning by its position will make the pinned object retain its position relative to the other object, but when the other object rotates, the pinned object doesn't change its angle.

Pinning by its angle will make the pinned object retain its angle relative to the other object, but it doesn't change its position when the other object moves.

Pinning by both angle and position will make the pinned object retain its position and angle relative to the other object.

For now, we want to pin by both position and angle, so the code is as follows:

Pinning an object to another object

Moving the units

We have grouped two objects in a container; now, let's make them move. To move the units, we will first select them and then click on a place on the game to move the selected units there. We need an instance variable to make the units know whether or not they've been selected. This instance variable is a Boolean variable; let's call it selected, and we'll create it in the tankBase object.

To be able to select a unit, the game must respond to a mouse input; so we'll add a Mouse object in our project. Then, we have to move the unit, but how do we do this? Construct 2 has a simple way to move an object with a Pathfinding behavior. This behavior takes a position to move to and then moves the object to this position. Sounds simple enough, so let's add this behavior to the tankBase object.

Moving the units

Now that we have this behavior, we can start moving our units. There is a way to move them: players must first click on the unit they want to move to select them; we marked the selected units by changing their selected instance variable to true:

Moving the units

After that, the players must click on a place in the game they want the selected units to move to, and we'll tell the units to find a way there using a Pathfinding behavior:

Moving the units

If the units can find a way there, they will go there:

Moving the units

We have made our selected units go where we want them to! Test the game now and you will see the units moving to where you click with the mouse. They even rotate nicely when changing directions.

Adding obstacles

I think a blank white background is pretty boring for a level, don't you? So, let's add a few obstacles in the way of our unit. We will place these obstacles in their own layer, so create a new layer called Obstacles and put it between the Main and Background layers.

We will use a tiled background to make the obstacles so that we can create several kinds of obstacles. Unfortunately, there isn't a sprite in the Sprites folder with a size of 16 x 16 or 32 x 32 that we can use for this, so we'll have to make our own. First, we'll create a tiled background object and name it tiledObstacle, and then, in the edit image window, we'll resize it by clicking on the Resize icon.

Adding obstacles

Now, change the value to 32 x 32.

Adding obstacles

After we resize it, we'll color the image in the orange color. Close the edit image window and place the tiled obstacles in three ways: vertically, horizontally, and diagonally, as shown in the following screenshot:

Adding obstacles

We've got three kinds of obstacles; this is a good way to show you how the Pathfinding behavior works. If you test the game now, our unit can still walk through the obstacles. Why? This is because the Pathfinding behavior doesn't see them as obstacles.

There are two ways for the Pathfinding behavior to recognize obstacles: solid and custom. By default, the Pathfinding behavior sees solid objects as obstacles and will try to move around them. The other setting, Custom, means that we have to tell the Pathfinding behavior which objects are the obstacles. Remember that solid objects are objects with a Solid behavior, which makes them impassable by other objects. You can change the setting in the Properties bar.

Adding obstacles

For now, let me show you how to use solid objects as obstacles. We only need to add a solid behavior to the tiledObstacle objects, and the Pathfinding behavior already knows that they are obstacles. Test the game after you've added a Solid behavior to the obstacles, and you can see that our unit now tries to evade them.

Making custom obstacles for the units

Alright, we know how simple it is to make obstacles with solid objects, but how do we make custom obstacles that aren't solid objects? To answer this, we will first create another object to be this custom obstacle. Add another sprite object to the layout, and as we don't have the appropriate sprite for this, let's resize it to 32 x 32 and give it a blue color. Name this sprite civilians; it'd make sense for tanks to avoid them. We will create custom obstacles when we want one object with the Pathfinding behavior to evade an obstacle, and when we also want the other object to not evade the same obstacle.

We'll then change the Obstacles property to Custom so that the Pathfinding behavior will look for custom objects as obstacles.

Making custom obstacles for the units

So, how do we tell the Pathfinding behavior which objects are the obstacles? We will do this using code. When tankBase is created, we'll tell it which objects are the obstacles using the add obstacle action. We'll add the civilians and tiledObstacle objects as obstacles; we want to add the solid objects in this way because the Pathfinding behavior's property has been changed to Custom. So, on the event sheet, edit the tankBase property's On created action to be as follows:

Making custom obstacles for the units

After this, place the civilians objects somewhere so that it would hinder the tank's movement. This is represented in the following screenshot:

Making custom obstacles for the units

If you test the game now, you'll see that the tank is trying to evade the civilians as they go to their destination.

Creating enemies

We've finished making our unit, so now let's create the enemy objects. For the enemy objects, we will use the same technique we use when we make our units, that is, adding two objects to a container. For the enemyBase object, we will use the buttonSquare_beige_pressed sprite from the Adventure pack folder, and for the enemyTurret object, we'll use arrowBlue_right from the same folder.

After we add them to the layout, we will place them together in a container. Follow the same process as with the player's tank, but with the enemy tank objects. We'll also add the Pin behavior to enemyTurret, and then like tankTurret, we'll pin it to enemyBase when it is created:

Creating enemies

Put these two objects a bit away from the player's tank unit, somewhere out of the game window but still inside the layout, because they will to move and search for the player later. Don't forget to put them on top of each other, as shown in the following screenshot:

Creating enemies

We will do one more thing before we have finished making the enemy: enable it to search for the player. How are we going to do this? We'll do this by adding the Pathfinding behavior to the enemyBase object. Add this behavior to enemyBase, and we're done. We'll keep the Obstacles property as Solid for the enemy.

Making the turrets shoot

We have a turret for both the player's tank unit and the enemy's unit, but for now, they don't do anything, so let's make it shoot. To "shoot" means that it will have to recognize its target, rotate it, and then shoot at it. Lucky for us, Construct 2 already has a behavior to do all of this: the Turret behavior. So, let's add this to both tankTurret and enemyTurret.

Making the turrets shoot

After we add this behavior to both turrets, we need to determine which objects are the targets for the respective turrets. We will do this using the add object to target action that will make the turret automatically shoot the assigned object when it's in range. We want tankTurret to target the enemy unit, so we will add this object to its target:

Making the turrets shoot

We want enemyTurret to target the player's unit, so we will add this to its list of targets:

Making the turrets shoot

Now, if they come into each other's range, the following events will occur:

  • The tankTurret object will recognize enemyTurret as its target (and the other way around)
  • In this situation, the On target acquired event will fire, and the turret will rotates to its target
  • Once the turret is pointing at the target, the On shoot event will trigger at the rate determined by the rate of fire property

Remember that the turret object doesn't automatically shoot, but we must create an object with a Bullet behavior to act as the bullet, so let's do this now. Add two more sprite objects with a size of 14 x 14, make them a small circle sprite, and name them playerBullet and enemyBullet. Place them outside of the layout and give them both the Bullet behavior. We also want to destroy the bullets if they go outside of the layout, so add the destroy outside layout to them.

We'll give playerBullet a bluish color and enemyBullet a reddish color. After that, we need to add the code. Like I explained in the previous bullet points, when the turret thinks it can shoot, it will fire the On shoot event. In this event, we will create the player's bullet and shoot it at the same angle as the turret:

Making the turrets shoot

Let's do the same thing for the enemy turrets:

Making the turrets shoot

With this, the turrets will shoot at their targets. Finally, let's declare when the bullets are destroyed rather than letting them fly endlessly on the game screen. There are two scenarios when the bullets are destroyed: when they hit tankBase (for enemyBullet) and when they hit enemyBase (for playerBullet). To add a gameplay element, let's create a health instance variable to tankBase and enemyBase.

In this example, we'll give an initial value of 10 to the health instance variable of both objects, and we'll decrease it little by little:

Making the turrets shoot

Here, we are writing the code for the bullet collision with tankBase:

Making the turrets shoot

Don't forget to destroy the objects when the health of tankBase and enemyBase reaches 0; otherwise, nothing will happen. We want these objects to be destroyed when their health is 0 or less:

Making the turrets shoot

Here, we are writing the code for the tankBase Destroy event:

Making the turrets shoot

Navigating through the level

Now that we have created our own unit and an enemy, let's create a level. We will add a few more friendly and enemy units on the layout, as well as more obstacles. We want to make a level you'd find in a tank-strategy game. You can follow this design or create your own:

Navigating through the level

We now have a game in which the layout is bigger than the game window, and we want to be able to navigate around it. Previously, we were able to navigate using the Scroll To behavior that's added to an object, but now, we have more than one unit that the player can control. So we want to navigate around the layout without using the Scroll To behavior. How do we do this?

We'll use the Mouse object to scroll the layout. If the player puts the mouse on the right-hand side of the screen, then the game will scroll to the right; if the player puts the mouse on the left-hand side of the screen, then the game will scroll to the left, and the same applies for up and down. We'll use the Mouse object's expressions, absoluteX and absoluteY, which will give us the x and y coordinates of the mouse on the screen.

This is different from the usual mouse.X or mouse.Y expression that gives us the mouse's x and y coordinates on the layout and is, therefore, affected by scrolling. Both absoluteX and absoluteY expressions aren't affected by scrolling, so they're perfect if you want to know the mouse's position on screen.

So first, we'll scroll to the left when the mouse's position is near the left-hand edge of the screen, the way we know this is if the mouse's x position is a small number, for example if it is less than 20 pixels. We'll scroll it in amounts of 500 pixels per second; in this action, we will also use the dt expression; here, dt is short for delta time, which is the time difference between each tick. We will multiply the scroll speed with dt to ensure that the scrolling moves correctly even on slow computers:

Navigating through the level

Next, we will scroll the screen to the right. To do this, we need to know if the mouse position is 20 pixels from the right-hand side of the screen. Luckily, there's an expression to check the window's width: WindowWidth (pretty clear, right?). 20 pixels from the right-hand side means that 20 pixels are subtracted from the WindowWidth expression:

Navigating through the level

Then, we will scroll the screen up; doing this is the same like scrolling to the left, but we'll check the absoluteY value instead of absoluteX. We'll also scroll it in the y direction to make it move up:

Navigating through the level

Finally, we'll scroll the screen down. To do this, we also need to know the height of the screen, similar to when you want to scroll to the right. We also have an expression for this, which is WindowHeight:

Navigating through the level

Test the game now, and you can navigate the layout using your mouse.

Adding music and sound effects

We have a pretty good base for the game, but one thing is still missing: the sound. Construct 2 has an object to handle any kind of sound in the game: the Audio object. This object can play sound effects and background music needed in the game. So, we'll add this object to the game.

Adding music and sound effects

Before we use the Audio object to play sounds, we need to import the sound files. If you look at the Projects bar, there are two places where sounds can be imported: the Sounds folder and the Music folder.

Note

The files in the Sounds folder will be downloaded before they are played, so it is perfect for short sound files such as sound effects. On the other hand, files in the Music folder will be streamed from the server instead of being downloaded to the player's computer. This is suitable for long background music, so the files can be played without the player having to wait for a few minutes for the files to be downloaded. However, the music might buffer while streaming, which can cause a delay.

The sound effects we're using in this example are from the Sound FX folder in freebundle.zip; the background music is from the Music folder of the same bundle. To import the sound effects, we'll right-click on the Sounds folder in Construct 2 and select Import sounds. After that, a window will open where you can search for the intended files for sound effects. For now, we'll select the one from the freebundle folder, which is SFX1.wav present at freebundleSound FX.

After that, you'll see another window that will convert the files to be compatible with browsers. If the icon beside the filename is a green check mark, then it's good.

Adding music and sound effects

After you click on the Import button, Construct 2 will convert the files to be compatible with common web browsers. The process for this is the same as the one to import music: right-click on the Music folder and select the file. In this example, we'll use MattOglseby-3 and then import it. We now have the required files to add sound effects and background music.

Choosing the right file

There's one thing to keep in mind when importing audio files to Construct 2: file types. Even now, the browser makers still can't agree on one sound format to be supported on their browsers. Internet Explorer and Safari still use the MPEG-4 AAC format (the .m4a file), while Firefox, Chrome, and Opera support the free Ogg Vorbis format.

Therefore, to support most browsers available, you have to provide both file types for one audio. However, if you can't, you can simply provide PCM .wav files for the audio, as this file type is widely supported, and Construct 2 can convert it to both the MPEG-4 AAC and Ogg Vorbis formats.

Tip

It is advised that you import PCM .wav files for audio needs, because Construct 2 can convert them to support all browser platforms.

Playing the sound

Okay, now that you know about the Audio object and how it works, it's time to actually add the sound to our game. There are two places where we want to play the sound effects: when the tanks are shot and when the tanks are destroyed. We'll play the SFX1 audio file for both events; edit them as follows:

Playing the sound

We'll then edit the events where the player's units and enemy tanks are destroyed, to play the explosion sound effect:

Playing the sound

Here, we are writing the code for the tankBase destroy event:

Playing the sound

Now, if you test the game, you can hear the sound effects when the turrets are shot and when the tanks are destroyed, but this game is still a bit quiet. Maybe, we can add music to lighten it up. When playing music, always make sure that you play it on a trigger event, or else you might accidentally start the same music multiple times.

Tip

When playing music, make sure that you don't play it in an event where you might accidentally play the music multiple times. It is a good idea to play it at the start of a layout.

So, we'll play the background music at the start of the level. We'll use MattOglseby-3 from freebundleMusic and import it to our project, like the SFX1 file (make sure that you imported the .ogg file and not the .m4a file), and play it at the start of the layout:

Playing the sound

Test the game now; can you feel how adding background music makes the game more entertaining and enjoyable?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset