1

Directions for Tank War

Directions from the Game Maker’s Apprentice book by Jacob Habgood and Mark Overmars

Game Description

Tank War is a futuristic tank combat game for 2 players. Each player drives his or her own tank through the walled battle arena with the aim of destroying the other player’s tank. Once a tank is destroyed, both tanks are respawned at their start position, and a point is awarded to the surviving player. Most walls provide permanent cover, but some can be temporarily to create a way through. There is no ultimate goal to the game, and players simply play until one player gives up.

Each tank has a primary weapon that it can fire indefinitely. Pickups provide a limited amount of ammunition for a secondary weapon, or repair some of the tank’s damage:

  • Homing rockets: Always move in the direction of your opponent
  • Bouncing bombs: Bounce against walls, and can be used to fire around corners
  • Shields: Are activated to provide a temporary protective shield
  • Toolbox: Repairs part of the tank’s damage

The game uses a split screen view divided into two parts. The left part is centered on player 1’s tank and the right part is centered on player 2’s tank. There is also a mini map at the bottom of the screen for locating pickups and the other player.

Player 1 will move their tank with A, D, W and S Keys and fire with the spacebar (primary) and CTRL key (secondary). Player 2 will control their tank with the arrow keys and fire with the Enter key (primary) and Delete key (secondary).

Play with Tanks

Creating the arena and background walls:

  1. Launch Game Maker and start with an empty game.
  2. Create the background using Background.png in the folder on the network. Name it Background.
  3. Create 2 sprites called sprite_wall1 and sprite_wall2using Wall1.png and Wall2.png.
  4. Create a new object called object_wall1 and assign sprite_wall1. Enable Solid and close.
  5. Create a new object called object_wall2 and assign sprite_wall2. Enable Solid and set Parent to object_wall1.

Creating the controller object and the room:

  1. Create a sound resource from the folder called sound_music using the Music.mp3 file.
  2. Create a new object called object_controller with no sprite. Set Depth to -100 to make sure the drawing actions we make later on are in front of the other objects. Add an Other, Game Start event and include the Play Sound action. Set Sound to sound_music and set Loop to True.
  3. Create a new room and switch to the settings tab. Call the room room_main and add an appropriate caption.
  4. Switch to the backgrounds tab. Select the background you created earlier.
  5. Switch to the objects tab. In the toolbar, set Snap X and Snap Y to 32.
  6. Create a continuous wall using object_wall1 around the outside of the room. Also add walls of both types to the interior to provide barriers for the tanks. (You can hold the SHIFT key to add multiple instances of objects).
  7. Addone instance of the controller object to the room.

Now we will create our tanks. We need different tanks for each player but most behaviors will be identical so we will make a parent tank that contains the common events and actions. We will control the tank instances by changing the direction and speed. Direction indicates the direction of movement (0-360 clockwise). The speed indicated the speed of movement and negative speed values mean backward movement.

Creating the parent tank object:

  1. Create a new object called object_tank_parent…no sprite.
  2. Add a Create event and include Set Friction with Friction set to 0.5. This makes the tanks slow down and stop when player isn’t pressing the acceleration key.
  3. Add a Collision event with object_wall1 and include a Set Variable action. Set Variable to speed and Value to –speed. This reverses the tank’s direction when it hits the wall.
  4. Right click the Collision event you just created, right click to paste it and change the object it collides with to object_tank_parent.

Creating two player’s tank objects:

  1. Create 2 sprites called sprite_tank1 and sprite_tank2 using Tank1_strip60.png and Tank2_strip60.png. Set Origin of both to Center. EnableSeparate collision masks.
  2. Create a new object called object_tank1 and assign the 1st tank sprite. Set Parent to object_tank_parent and enable Solid. Set Depth to -5.
  3. Add a keyboard, Letters, A event and include a Set Variable action. Set Variable to direction, Value to 6 and enable Relative. The tank will move counterclockwise.
  4. Add a Keyboard, Letters, D event and include a Set Variable action. Set Variable to direction, Value to -6 and enable Relative. Tank will move clockwise.
  5. Add a Keyboard, Letters, W event and include a Test Variable action. Set Variable to speed, Value to 8 and Operation to smaller than. Include a SetVariable action, setting Variable to speed, Value to 1 and enable Relative. This increases the speed if greater than 8.
  6. Add a Keyboard, Letters, S event and include a Test Variable action. Set Variable to speed, Value to -8 and Operation to larger than. Include a SetVariable action, setting Variable to speed, Value to -1 and enable Relative. This decreases the speed if greater than -8.
  7. Add a Step, End Step event. Include a ChangeSprite action, setting Sprite to sprite_tank1, Subimage to direction/6 and Speed to 0.
  8. Add a Draw event. Include a Draw Sprite action, setting Sprite to sprite_tank1 and Subimage to -1 and Relative enabled.
  9. Select all steps, right click and copy, then paste to create object_tank2. Change any references to object_tank1 to object_tank2. The key commands will deal with the arrow keys.
  10. Reopen the room and put in one of each tank.
  11. Now test the game to make sure everything is working correctly.

Firing Shells

We will start to build the shells for the tanks to shoot at each other. We will record the amount of damage for each tank and once it reaches 100, the tank is destroyed. We will use 2 global variables called global.score1 and global.score2 to record the kills each tank made.

Recording the player’s score in the controller object:

  1. Create a font called font_score and select Arial with a size of 48 and Bold enabled. Click Digitsbutton so we only see numbers.
  2. Reopen the controller and select the Game Start event. Include a Set Variable action with Variable set to global.score1 and Value to 0. Include another SetVariable action with variable set to global.score2 and Value set to 0.
  3. Add a Draw event and include the Set Font action. Set font to font_score and Align right. Include a Set Color action and choose dark red.
  4. Include a DrawVariable action from the Control tab. Set Variable to global.score1, X to 300 and Y to 10.
  5. Include another Set Font action with Font set to font_score but set Align to left. Include a Set Color action and choose dark blue.
  6. Include a Draw Variable action with Variable set to global.score2, X to 340 and Y to 10.

Creating the large explosion object:

  1. Create a sprite called sprite_explosion_large using Explosion_large_strip7.png and Center the origin.
  2. Create a sound called sound_explosion_large using Explosion_large.wav.
  3. Create a new object called object_explosion_large using the large explosion sprite and set Depth to -10. Add a Create event and include the play sound with sound_explosion_large set Loop to false.
  4. Add an Other, Animation End event and include the Restart room action.

Create the small explosion object:

  1. Create a sprite called sprite_exlosion_small using Explosion_small_strip6.png and Center the origin.
  2. Create a sound called sound_explosion_small using Explosion_small.wav.
  3. Create an object called object_explosion_small. Use the Explosion_small sprite and set Depth to -10. Add a Create event and include the Play sound action with sound_explosion_small and Loop to false.
  4. Add an Other, Animation event and include the Destroy Instance action.

Adding damage mechanism to parent tank object:

  1. Reopen object_tank_parent and select the Create event. Include a SetVariable action with Variable set to damage and Value set to 0.
  2. Add a Step, Step event and include a Test Variable action. Set Variable to damage, Value to 100 and Operation to smaller than. Include an Exit Event action so no actions executed if damage is smaller than 100.
  3. Include a test Variable action with Variable set to object_index, Value to object_tank1 and Operation set to equal to. Include a Set Variable action with Variable set to global.score2, Value to 1 and Relative enabled.
  4. Include an Else action followed by a Set Variable action. Set Variable to global.score1 and Value to 1, enable Relative.
  5. Include a Create Instance action with Object set to object_explosion_large and Relative enabled.
  6. Include a Destroy Instance action.

Adding a draw event to the parent tank object to draw health bars:

  1. Add a Draw event for the parent tank object.
  2. Include a Set health action (score) and set Value to 100-damage.
  3. Add a Draw health action. Set X1 to -20, Y1 to -35, X2 to 20 and Y2 to -30. Enable Relative. Do not change the other settings.
  4. Reopen object_tank1 and select the Draw event. Include a Call Parent Event (control) at the end of the actions for this event. This makes sure the Draw event of the parent tank object is executed.
  5. Reopen object_tank2 and select the Draw event. Include the Call Parent event at the end of the list of actions for this event.

Creating the parent shell object:

  1. Create a sprite called sprite_shell using shell_strip60.png and Center the origin. Enable the Separate collision marks option.
  2. Create a new object called object_shell_parent and do not assign a sprite.
  3. Add a Create event and include a Set Alarm action. Set Number of Steps to 30 and use Alarm 0.
  4. Add an Alarm, Alarm 0 event and include a Destroy Instance action.
  5. Add a Step, End Step and include a Change Sprite action. Set Sprite to sprite_shell, Subimage to direction/6 and Speed to 0.
  6. Ad a Collision event with object_wall1 and include a Create Instance. Set object to object_explosion_small and enable Relative. Include a DestroyInstance action to destroy the shell.
  7. Add a Collision event with object_wall2. Include a Create Instance with Object set to object_explosion_small and Relative enabled. Include a Jumpto Position with X and Y set to 100000. Select Other object for Applies to so wall is moved rather than the shell.
  8. Include a Set Alarm action and select Other object for Applies to it sets an alarm for the wall. Select Alarm 0 and set Number of Steps to 300. Include a Destroy Instance action to destroy the shell.
  9. Add a Collision Event with object_shell_parent and include a Create Instance action. Set Object to object_explosion_small and enable Relative. Include a Destroy Instance to destroy the shell.

Editing the destructible wall object to make it reappear:

  1. Reopen the object_wall2 object and add an Alarm, Alarm0 event. Include a Check Empty action with X set to xstart,Y set to ystart and Objects set to ALL. Include a Jump to start action.
  2. Include an Else action followed by a Set Alarm action. Select Alarm0 and set Number of Steps to 5.

Creating the players’ shell objects:

  1. Create a new object called object_shell1. Use the shell sprite and set Parent to object-shell_parent.
  2. Add a Collision event with object_tank2 and include a Set Variable action. Set Variable to damage and Value to 10, enable Relative. Also select Otherobject for Applies to so tank’s damage is changed.
  3. Include a Create Instance action with object set to object_explosion_small and enable Relative. Include a DestroyInstance action.
  4. Repeat steps 1-3 to create object_shell2 using a Collision event with object_tank1 instead of object-tank2.

Adding Events to make the tank objects fire shells:

  1. Reopen parenttank and select the Create event. Include a SetVariable action with Variable set to can_shoot and Value set to 0.
  2. Select the Step event and include the SetVariable action at the beginning of the list of actions. Set Variable to can_shoot and Value to 1, enable Relative.
  3. Reopen object_tank1 and add a Key Press, <Space> event. Include a TestVariable action with Variable set to can_shoot, Value to 0 and Operation to smaller than. Include an Exit Event action so other actions will execute when can_shoot is larger or equal to 0.
  4. Include a CreateMoving action. Set Object to object_shell1, Speed to 16,Direction to direction, and enable Relative. Include a Set Variable action with Variable to can_shoot and Value to -10
  5. Repeat steps 3-4 for object_tank2, using Key Press <Enter> and object_shell2 for the Create Moving action.

Secondary Weapons

Creating the pickup object:

  1. Create a sprite called sprite_pickup using Pickup_strip4.png.
  2. Create a new object called object_pickup and assign pickup sprite.
  3. Add a Create event and include the Set Variable action. Set Variable to kind and Value to choose (0,1,2,3)
  4. Include the Set Alarm action for Alarm 0 and set Number of Steps to 100+random(500). Include a Jump to Random action. Do not change the default settings.
  5. Add an Alarm, Alarm 0 event and include the Set Variable action. Set Variable to kind and Value to choose(0,1,2,3).
  6. Include the Set Alarm for Alarm 0 with Number of Steps set to 100+random(500). Include a Jump to Random action.
  7. Add a Collision even with object_tank_parent and include a Jump to Random.
  8. Add a Draw event and include the Draw Sprite action. Set sprite to sprite_pickup, Subimage to kind and enable Relative.

Reopen the room and add a few instances of the pickup object. Test the game to make sure that the pickups have different images that change their type and position periodically.

Editing the parent tank object to record pickups:

  1. Reopen object_tank_parent and select Create event.
  2. Include a Set Variable action with Variable set to weapon and Value set to -1. Include a secondSet Variable action with Variable set to ammunition and Value to 0.
  3. Add a Collision event with object_pickup and include a Test Variable. Set Variable to other.kind, Value to 3 and Operation to equal to. Include a StartBlock
  4. Include a Set Variable action with Variable set to weapon and Value to -1. Include another Set Variable action with Variable set to damage and Value to max(0,damage-50). This will subtract 50 from damage but won’t make it smaller than 0. Include an End Block.
  5. Include an Else action, followed by a Start block.
  6. Include a Set Variable action with Variable set to weapon and Value to other.kind. Include another Set Variable action with Variable set to ammunition and Value set to 10.
  7. Include an End Block.

Displaying the secondary weapon in the parent tank object:

  1. Create a new sprite called sprite_weapon using Weapon_strip3.png
  2. Create a font called font_ammunition. Keep the default settings.
  3. Select the Draw event in object_tank _parent and include a test Variableaction. Set Variable to weapon, Value to -1 and Operation to larger than. Include a Start Block.
  4. Include the Draw Sprite action and select sprite_weapon. Set X to -20, Y to 25 and Subimage to weapon. Enable Relative.
  5. Include the Set Color action and choose black. Include a Set Font action, selectfont_ammunition and Align Left.
  6. Include a Drawvariable action with Variable set to ammunition, X set to 0, Y set to 24 and Relative enabled.
  7. Include an End Block.

Creating the parent rocket object:

  1. Create a sprite called sprite_rocket using Rocket_strip60.png and Center it. Enable Separate collision masks.
  2. Create a new object called object_rocket_parent and set Parent to object_shell_parent.
  3. Add a Create event and include Set alarm. Set Number of Steps to 60 and Alarm 0.
  4. Add a Step, End Step and include a Change Sprite action. Chose the rocket sprite, set Subimage to direction/6 and Speed to 0.

Creating actual rocket objects:

  1. Create a new object called object_rocket1 and use the rocket sprite. Set Parent to object_rocket_parent.
  2. Add a Create event and include the Move Towards action. Set X to object_tank2.x, Y to object_tank2.y and Speed to 8.
  3. Add a Collision event with object_tank2 and include a Set Variable action. Select Other from Applies to, set Variable to damage and Value to 10, enableRelative.
  4. Include a Create Instance action, selecting object_explosion_small and enable Relative. Include a Destroy Instances.
  5. Create object_rocket2 in the same way but move toward object_tank1 in the Create event and add a Collision event with object_tank1 for actions in steps 3 and 4.

Adding events to shoot rockets for the tank objects:

  1. Reopen the first tank object and add a Key Press, <CTRL>. Include a TestVariable action with Variable set to can_shoot, Value set to 0 and Operation set to Smaller than. Include an Exit Event so remaining action only execute when can_shoot is larger than or equals 0.
  2. Include a Test Variable action with Variable set to weapon, Value set to 0 and Operation set to equal to. Include a Test InstanceCount with object set to object_tank2, Number set to 0 and Operation set to larger than. Add a Create Instance for object_rocket1 and enable Relative.
  3. Include a Set Variable action with Variable set to ammunition, Value set to -1 and Relative enabled. Include a Test Variable action with Variable set to ammunition, Value set to 1 and Operation set to smaller than. Include a SetVariable action with Variable set to weapon and Value set to -1.
  4. Add a Set Variable action with Variable set to can_shoot and Value set to -10.
  5. Repeat steps 1-4 for object_tank2 using Key Press, Others, <Delete> and creating object_rocket2.

Creating a bouncing bomb object:

  1. Create a sprite called sprite_bouncing using bouncing_strip60.ong and Center the origin. Enable Separate Collision masks.
  2. Create a new object called object_bouncing_parent, setting Parent to object_shell_parent.
  3. Add a Collision event with object_wall1 and include the Bounce action. Select Precisely and set Against to solid objects.
  4. Add a similar Collision with object-wall2.
  5. Add a Step, End Step and include a Change Sprite action. Select sprite_bouncing, set Subimage to direction/6 and set Speed to 0.
  6. Create a new object called object_bouncing1 and assign bouncing bomb sprite. Set its Parent to object_bouncing_parent.
  7. Add a Collision event with object_tank2 and include a Set Variable action. Select Other from Applies to, set Variable to damage, set Value to 10 and enable Relative. Include a Create Instance action for object_explosion_small and enable Relative.
  8. Include a Destroy Instance.
  9. Repeat steps 6 and 7 to create object_bouncing2 using a Collision event with object_tank1.

Editing the parent tank object to support shields: