Let’s Make: Traffic Department 2192 – Part 16

Prototyping Top-Level Design & Programming

We'll get started with development by addressing the high level concepts including rooms, and objects that provide control throughout the entire game.

Rooms

Back in part 2, we played through the first mission and broke down the game flow in to a series of distinct segments. These segments are analagous to rooms in GameMaker, so we'll create a room for each with the handle rm_*. We'll set the dimensions of each room to roughly 3 size of the original game and create views that automatically scale to fit. Our rooms will be 960x600 with a frame rate of 60. Again, here are the 5 rooms we need to define.

Translating game flow in to rooms

 

Objects

Our design includes three objects that persist through all the rooms of the game.

Keyboard Interface - obj_keyboard

This is a persistent object that reads the input at the beginning of each step and pushes appropriate commands to game objects that are listening.

Music Controller - obj_music

A persistent object that stops and starts music based on the current game room

Current Game - obj_currentgame

A persistent object that holds the data of the currently active game. It will also hold data on inactive (saved) games.

Here is the outline of our GameMaker objects

The outline for the persistent objects

 

GML Code

For each of the following objects, we'll add code to one or more of the listed events:

obj_currentgame: Create 1

This is the cosntructor event. We'll declare important data that's reference during the game and we'll also load the save data from a file. Note that the save game data only consists of a mission number and a kill count. We've created our own save game file, TD.SAV.

 

obj_keyboard: Create 1

The constructor for the keyboard event simply creates two empty data structures. The input_stack will contain the relevent input for the current frame. The target_list contains handles to other game objects that the keyboard object will push commands to. By design, we'll make listen objects register themselves with they keyboard object on initialization.

 

obj_keyboard: Begin Step 1

The first thing the keyboard object does every frame is to clear the stack and push a 'command' based on the current input. This is where we would consider adding a separate lookup map that binds keys to commands from a configuration file. As it stands, our design hard codes keys to commands so the user has no ability to change bindings. The original Traffic Department didn't have this feature either.

 

obj_keyboard: Begin Step 2

Now that we have a stack full of commands, we should distribute them to all objects that registered to listen with the keyboard object. If this were a large project, we could refactor our design to include multiple lists segmenting objects by type so that we aren't pushing commands that will never be used by certain objects.

 

obj_keyboard: Room End 1

When a room ends, the keyboard object should flush the object references. All of them are destroyed by this time anyway.

 

obj_music: Create 1

The constructor for our music controller only initializes two handles.

 

obj_music: Room Start 1

We should kick off the appropriate music depending on the room that starts. Note that current_music contains the handle to the playing instance so it can be referenced at any time.

 

obj_music: Room End 1

All sound and music should cease when a room ends