Let’s Make: Traffic Department 2192 – Part 25

Prototyping - Programming Ship Actions & Collisions

It's time to implement the ship controls based on our design from part 23. We'll focus on the player ship since most of our work will apply to the NPC ships too. In addition to controls, we'll add some explosion effects that trigger when shots hit a target and ships are destroyed.


We can implement the ship functions with four objects:

Concept Object Notes
Ships obj_ship The object that we'll use for all game ships, player and NPC
Weapon shots obj_fire The protoype object for all weapons
Explosions obj_explosion Single explosion effect used for weapon hits and ship destruction
Screen flash obj_flash An object that makes the screen flashing effect when a ship is destroyed


GML Code

We'll create the four objects in GameMaker and modify our camera object from last time to focus on the player ship

obj_ship: Create 1

Register keyboard and set references. Note that the ai reference will be null because it doesn't exist yet. The parent object will manually associate it


obj_ship: Create 2

Creates the targets priority queue used to hold valid targets for AI and HUD


obj_ship: Create 3

Sets the four enum types used in ship objects. Note that actions are handled as bit flags.


obj_ship: Create 4

Ship variables set up for the default ship used by the player. I'll leave this in it's final form but we'll make some changes during testing.


obj_ship: Destroy 1

Ships explode when destroyed.


obj_ship: Destroy 2

Remove keyboard reference and free data structures.


obj_ship: Step 1

Process input for ships. This time, I'll demonstrate a bitfield to set actions. Essentially, one interger variable represents the collective combination of keyboard inputs. This method was ubiquitous in the era of Traffic Department and is still somewhat common in lightweight solutions like embedded systems.


obj_ship: Step 2

Handle movement turning commands by reading from the bitfield



obj_ship: Step 3

Handle movement speed changes


obj_ship: Step 4

Ship firing of various weapon types. I'm going to fill out the code block here as it is in the final version of the prototype. We don't actually add the weak weapons until the final video.


obj_ship: Step 5

Weapon changes, self destruct, and afterburners. We won't build a case for the final just yet. Since it doesn't appear in mission 1, we may not get to it at all in this demo


obj_ship: Step 6

Check for collisions by checking the point at exactly the front and back of the ship. If the points are asserted in the collision map, then we reverse the speed. Note that I used the absolute value, whch seem redundant, but this is actually critical to keep the direction of the ship correct in subsequent frames. In a nutshell, the front point should always force a negative speed, while the rear point a positive speed relative to the dircetion vector (re +velocity). Refer to the video for a detailed explanation of why this works.


obj_ship: Step 7

Check the ship for damage or death


obj_ship: Begin Step 1

Iterate timers and apply our friction loss factor


Script: map_pos

Calculate the ships absolute pixel position to a grid coordinate on our 201x201 map. We use this for lookups


obj_camera: Room Start 1

In the last video, we had the camera locked to itself. Now we want it to always lock to the player ship.


Script: find_player_ship

Returns a handle (object id) to the player ship


obj_fire: Create 1

Set object references


obj_fire: Create 2

Variables for the shot including who, and how much damage


obj_fire: Step 1

Update the map position


obj_fire: Step 2

Check for hits. If a ship is hit, we make explosions and transfer damage. The 'trick' here is that all damage is applied to the shields and any negative value rolls over to the armor at half rate (shields reset to 0 if negative).


obj_fire: Step 3

Update life timers, which gives the shots a limited range


obj_fire: Room start 1

I'm going to use this event to hold creation polymorphic events. This would probably be best in a custom event, which I'll do for ships. Technically no obj_fire objects exist when the room starts so this will never run by itself. I'll call it manually.


obj_fire: Draw 1

Draws the shot


Script: fire_shot

Creates a single volley based on the ship and weapon. Most have two but some have four. Shots appear on points some distance in front of the ship.


obj_explosion: Create 1

Sets the explosion timer.


obj_explosion: Step 1

Iterates the timer


obj_flash: Create 1

Sets the flash timer


obj_flash: Step 1

Iterates the timer


obj_flash: Draw 1

Draws a yellow box on the screen with a partial alpha and fades out in 10 frames.