Make Your First Car Game


Make Your First Car Game

This tutorial was created by Josia Roncancio as part of the GameMaker Coaching program. You can view a recording of the live webinar here.

In this tutorial, you'll make a car parking game from scratch, using visual programming in GameMaker. Don't worry, it's a lot easier than learning to parallel park in real life.

This is what the final product will look like:

undefined

We'll be using some premade assets to make this game, which you can download here. You can also download the final project.

Create Your Project

Let’s create a new project.

Start GameMaker, click on “New”, and select the “New Blank” template.

Enter a name for your game (e.g. “ParkingPanic”) and click “Let’s Go!”.

undefined

After creating the project, the main GameMaker IDE will open up, which consists of two main parts: the Workspace on the left side, and the Asset Browser on the right.

In the Asset Browser, you'll find a list of all the assets that make up your game. The Workspace is where different editors will open, allowing you to edit your assets and program your game. 

undefined

Loading the Car Image

Sprites will usually be the first thing you add to your project since they're the visual components of your game. Any image or animation is saved as a Sprite in GameMaker.

Let’s start by creating a new Sprite. Right-click on the “Sprites” folder in the Asset browser, and select “Create -> undefined Sprite” in the pop-up menu.

undefined

This will create a new Sprite Asset and open up an editor for it in the Workspace.

To import our own images into this Sprite, click the "Import" button and navigate to the “Sprites” folder of the assets that you downloaded.

Now select the two images called “spr_car_right0.png” and “spr_car_right1.png”, and press "Open".

undefined

Opening multiple image files will turn them into an animation, which you can preview by pressing the little play button below the sprite. To adjust the animation speed, change the number next to “Fps” on the top left to a speed that looks good (e.g. 3).

Last but not least, let’s give the Sprite a proper name. This is important because as you add more and more Assets to your game, you'll need to be able to identify which Sprite contains which image. A typical naming convention for GameMaker is to start with a prefix (“spr_” for Sprites), so let’s name this one “spr_car_right”.

undefined

GameMaker also has a built in Image Editor that you can use to draw your own Sprites or modify existing ones. You can open it by clicking “Edit Image” if you wish to create your own art or modify the images you get from this tutorial.

Program Your Car

The next asset we'll need is an Object. Objects are the components of our game that have any kind of behaviour. Anything that moves around on screen, or can be interacted with in some way, is an Object.

Before our parking game is finished, we'll have three Objects:

  • The player car that drives around

  • The parked cars that the player has to avoid

  • The parking spot that the player tries to reach

An object consists of a Sprite, a list of properties, and a list of Events and Actions that define its behaviour. We'll get into what exactly that means in a little bit.

For now, let’s create an Object by right-clicking the Objects folder in the Asset browser and selecting “Create -> undefined Object” and naming it “obj_car”.

Assign the car Sprite to the object by dragging it from the Asset browser into the “Sprite” field of the Object. This will tell our Object what it should look like in the game.

undefined

Adding Objects to a Room

The last thing we need to do for our car to show up in our game is place an instance of it in a Room.

Rooms are the different screens that your game is presented on. In our case, these will be the different levels of the game, but rooms can be used in all sorts of ways, like game menus or inventory screens.

Let’s open “Room1” in the Rooms folder of our Asset Browser by double-clicking it. This will open up the Room Editor.

Add an instance of your car Object to the room by dragging it from the Asset Browser.

undefined

Some editors like the Room and Sprite editor will open in a new tab next to the main Workspace. You can switch between them by clicking on the different tabs at the top.

undefined

Congratulations - you just added your first Object to your game!

You can now play the game by clicking the little undefined Play button above the Workspace (or F5 on your keyboard), and after a couple of seconds, you should see your animated car show up in an empty room.

How to program Objects

Now let’s go back into our car Object and figure out how to actually make it move. As mentioned earlier, an Object’s behaviour is defined by a combination of Events and Actions. Actions tell our Object what to do, while Events tell it when to do it.

For example, if we want our car to start driving when the player presses the spacebar, we would need an Event (Press Spacebar) and a corresponding Action (Start Moving).

To implement this, open up your car Object by double-clicking on it. Now click the “Add Event” button in the Events window. Navigate to “ undefined Key Pressed -> Space”.

This will create the “Key Press - Space” Event and open up a new window for this Event.

undefined

You may be asked to choose between GML Code and GML Visual. Select the Visual option, which this tutorial covers.

Enable “Don’t ask again for this project” and hit “OK”:

undefined

Now that we've told our Object when we want it to do something, we need to tell it what we want it to do.

We do this by using the GML Visual Actions from the Toolbox on the right part of the window. You can see a description of what each of the Actions does by hovering over it with your mouse.

undefined

For now, let’s find an Action called “ undefined Set Speed” in the Movement section of the Toolbox. We can add an action to our event by dragging it into the empty space on the left with our mouse.

undefined

The little Action Icon will turn into a bigger box with some customizable options. Here, change the “Speed” parameter to five. This will tell our object to start moving across the screen by five pixels each frame.

To see if it worked, start your game again by pressing the undefined Play button. The car will start out standing still again, but once you press the spacebar, it should move across the screen to the right.

Driving the car

Good job on getting your car to move! You're one step closer to crashing it into a row of parked cars.

Let's see if we can spare you a fender-bender and talk about how to change the direction of the car.

To do this, add another Event to your object. This time, pick “undefined Key Pressed -> Left” for the left arrow key.

Then, find the “ undefinedSet Direction Fixed” Action in the “Movement” Section and add it to the Event.

You can use the Search bar on top of the Toolbox to quickly find Actions instead of scrolling through the whole list!

This action allows us to change the direction the car is moving. Select the left-facing arrow to indicate that we want the object to move left.

undefined

Repeat the same process for the other arrow keys as well. Select a different direction to move in, depending on the Event you are in.

undefined

You can open an event by double-clicking on it in the Events list.

When you've assigned your directions, you can start the game again. After pressing Space to start the car, you should now be able to change its direction with the arrow keys.

undefined

If you've ever seen a car before, though, you'll probably notice something's amiss: the Sprite is always facing right, no matter which direction it's driving in. Let's fix that.

4-Directional Animation

We need to create a “4-directional” animation for the car, so its Sprite changes to face down, left, right and up.

Create three more Sprites for the other directions that our car can face in (down, left, up). Import the images from your disk using “Import”, adjust the Animation Speed in the “Fps” field, and name the Sprites accordingly:

undefined

Once this is done, go back to your car Object. We can now go back into the Arrow Key Events that we added before and add more Actions to them.

Open the “ undefined Key Press - Left” event.

To change the Sprite that's assigned to an Object, use the “ undefined Set Sprite” action, which you can find in the “Instances” section of the Toolbox.

Add this action to the event. We’ll tell this action which Sprite we want to use by dragging the correct Sprite (“spr_car_left”) into the “Sprite” field of the action.

undefined

Repeat this in the other three Events with the other three Sprites. If you run the game now, you’ll see that the car Sprite faces the direction it’s driving in:

undefined

And just like that, our basic car movement is all done! You can now drive better than three-quarters of British motorists.

Parked Cars and Collisions

The second object we need for our game is a parked car that the player has to avoid crashing into. Let’s get started by importing the two Sprites called “spr_car_parked” and “spr_car_crashed”.

To quickly import single-frame Sprites, you can also drag them from your file browser into GameMaker’s Asset Browser:

undefined

Now create an Object called “obj_car_parked”, and assign the Sprite “spr_car_parked” to it.

Then open “Room1” and drag a few parked cars into the room. Don’t worry about designing a proper level with them yet, we will get to that later.

For now, our player car will just drive through these parked cars. We'll have to expand the car Object’s behaviour for it to crash into them instead.

To do this, we can use a Collision Event, which runs whenever two objects touch each other on-screen.

So let’s add a new Event to our obj_car. In the Event selection menu, navigate to “ undefined Collision -> Objects -> obj_car_parked”:

undefined

This will create a Collision event between our player car (obj_car) and the parked car (obj_car_parked).

In this Event, we want our player car to stop moving, which we can achieve with the same Action we used to move it: “ undefined Set Speed”.

Add this Action to your Event, but this time, let’s leave the “Speed” field at 0 so that the car stops moving.

Let’s also add another Action called “undefined Set Animation Speed” (found in the “Instances” section) with a Speed of 0 to stop the Object’s animation from playing after we crash.

undefined

The last thing we want to happen when we crash into a parked car is to change its Sprite into a crashed car.

Since this is something that doesn’t affect the player car, we’ll go to our obj_car_parked, and add a Collision Event with obj_car to it.

Add a “ undefined Set Sprite” Action in this event to change the Sprite to “spr_car_crashed”:

undefined

Play the game again, and you'll see that you can crash into the parked cars!

undefined

Parking Spots

The last Object we need before we can begin designing our levels is the parking spot that the player has to reach to complete a level.

We’ll import the parking spot Sprite (as “spr_parking_spot”), and assign it to a new Object (called “obj_parking_spot”).

Then, go back to your obj_car and add a new Collision Event, this time with obj_parking_spot.

In this Event, find and add the Action “ undefined Go To Next Room” (under “Rooms” in the Toolbox).

undefined

When the car touches a parking spot, the game will move to the next room.

The fatal flaw in our plan, of course, is that we need actual levels for the player to progress through, which means it's time set up some parking lots!

The Room Editor

Let’s open up Room1 and take a closer look at the undefined Room Editor

On the left side, you'll find two panels: Properties at the bottom, and Layers at the top.

In Properties, you can modify options regarding the room, most notably its width and height. We don’t need to change anything here though.

In the Layers view, you'll find a list of all the layers in the room. These work similarly to layers in a drawing program and determine which elements appear above others. A room will always be created with an “undefined Instances” and a “undefined Background” Layer.

undefined

Switch to the Background layer by clicking on it, and you'll see that a bunch of new options appear below the layer list. This layer is used to add a background to the game. You can either use a solid colour, or a Sprite.

In the Asset Browser, import “spr_background” as a new Sprite. Then, just drag it into the Sprite field of the Background layer, and you'll see the background appear in the game:

undefined

You can only edit the Layer that is currently selected. If you ever end up not being able to move around your instances, make sure you have the Instances Layer selected!

Now, let’s switch to the Instances Layer. This is where you'll place the Instances of your Objects and design the layout of your levels.

Here are some useful shortcuts/tools for building your level:

  • Hold Shift and use the left mouse button to select multiple Instances at once.

  • Press Delete to remove selected Instances.

  • Press Ctrl+C and Ctrl+V to copy and paste selected Instances.

  • Use the “ undefinedToggle Grid” button on the upper right side of the editor to turn off the room grid. This will allow you to place your objects more freely.

  • After selecting an Object in the Asset browser, hold down Alt and use the left mouse button to “paint” with the selected Object. This allows you to quickly place a lot of neatly aligned cars next to each other!

undefined

Once you are done designing your first level (don’t forget to place a parking spot!), you can create a second level by right-clicking on our room and selecting “Duplicate”. This will create an exact copy of your first room, which you can rearrange to create your second level.

undefined

Creating the Win Screen

Once you're happy with your level(s), let’s add one more Room to the game. This will be your victory screen.

Right-click in the Asset Browser and select “Create -> undefined Room”, and import the last Sprite called “spr_winscreen” into the game.

Asset Layers

So far, we've been showing Sprites on the screen by creating Objects for them. However, for our victory screen, we’ll use a simpler solution.

Since we don’t need the victory screen to have any sort of behaviour, we’ll add the Sprite directly into our new room.

To do this, we need to add an Asset Layer to our Room. Click the “undefinedCreate New Asset Layer” button below the Layers list. This layer allows you to add Sprites directly into the room.

You can now drag the spr_winscreen Sprite into this layer. If you want to, you can also decorate it with some other Sprites and add a background.

undefined

Each layer can only contain a certain type of asset. You can’t put Sprites on an Instance layer, nor Instances on an Asset layer.

Once you're happy, go ahead and run the game to see if you can make it all the way to the victory screen!

Music and Sound Effects

Our main game loop is finished, but it'll feel a lot more complete once we add some sounds and music to it!

Import all of the sounds you downloaded into your project by dragging them into the Sounds group. Sound Editors will open up in your Workspace, where you can preview your audio files, and change various options for each of the sounds.

Let's start with some background music. It’s supposed to be played once at the beginning of the game, and should then keep looping.

Background Music 

To do this, let’s open obj_car and add a new Event to it: “undefined Other -> Game Start”. Add the Action “ undefinedPlay Audio” to the Event and drag “sd_music” into the Sound field.

Enable the “Loop” checkbox so the music keeps repeating and never stops.

undefined

The background music will now be playing throughout the game!

Sound Effects

You should be able to implement the other sounds yourself in a similar way by adding a undefined Play Audio Action to the appropriate Event.

Add the following sound effects in the obj_car object:

  • Play sd_honk in the “ undefined Key-Press Space” Event, which is when the car starts moving.

  • Play sd_win in the Collision: obj_parking_spot Event, which is when the car touches a parking spot.

  • Play sd_crash in the undefined Collision: obj_car_parked Event, which is when the car crashes into a parked car.

Don’t check the “Loop” option this time, since we want these sound effects to only be played once!

If you play the game now, you'll notice that all of the sounds are being played at the right times, except for one little problem: whenever you crash into a car, the crash sound keeps playing indefinitely, creating a horrible sounding effect.

Fixing the Crashing Sound

This is because of how collisions work in GameMaker: a Collision Event is triggered every frame that two Instances are touching. Since our cars don’t move away from each other after crashing, they'll continue to collide with each other for eternity, and for each frame they do, the crash sound is played.

To fix this, we’ll change the parked car into a different Object after we collide with it, which will only trigger one Collision Event!

Create a new Object called “obj_car_crashed” and give it the “spr_car_crashed” Sprite.

Now go to “obj_car_parked” and open its Collision Event with obj_car.

Instead of changing only the Sprite, we now want to change the whole Object to be a different one, so let’s remove the "undefined Set Sprite" Action and instead add the “undefined Change Object Instance” Event.

Then, drag “obj_car_crashed” object from the Asset Browser into the Object field.

undefined

Changing an Instance’s Object will change certain attributes of the Instance, like its Sprite, but keep others, like its current position in the room, scale, and movement.

You can now run the game again to see that the crash sound only plays once as intended.

Particle Effects

One easy way to make your game feel more polished is by using particle effects. Let's add a couple into our game:

  • A dust explosion that plays on crashing into a parked car

  • A dust trail that our car leaves behind while driving around

undefined

To add the dust explosion, go to obj_car_parked, and open the undefined Collision Event with obj_car.

Add the Action “undefined Do Effect” (found under “Particles”).

You can change a couple of attributes of the Effect in the Action. For this one, let’s set the “Type” to “Explosion”, “Where” to “Above Objects” and “Size” to “Large”.

The “X” and “Y” fields determine the position at which the effect will be displayed. Here, enable the “Relative” boxes next to both. This will make the effect appear at the position of our object instead of at the absolute position (0,0), which would be the upper left corner of the room.

However, we also need to add an offset to the effect, so it appears at the centre of the car and not in the upper left corner. To do this, set the “X” value to 53 and “Y” to 33 (half of the width and height of our Sprite).

Lastly, change the Colour to a light grey.

undefined

For the dust trail, let’s open obj_car and add a “ Step -> Step” Event to it. The Step Event runs for every single frame of the game while our object exists, and it’s perfect for the effect we're trying to achieve.

Add another “undefined Do Effect” Action here, and enter the following values:

  • “Type”: “Smoke

  • “Where”: “Below Objects

  • “Size”: “Medium

  • “X”: “53” (Relative enabled)

  • “Y”: “39” (Relative enabled)

Set the colour to a dark grey tone.

undefined

Our game is almost complete now, with music, sounds and particle effects.

There’s just one last tiny thing we’ll have to fix…

Bugfixing

You may or may not have noticed it already while playing, but there's actually a pretty game-breaking bug we've left unaddressed.

After you crash into a car, you can still use the arrow keys to turn around, and even press Space to start driving again!

undefined

This is because we’ve told our car that whenever we press the spacebar, it’s supposed to start driving. What we need to tell it is to only drive if it isn’t currently colliding with any other cars.

To fix this, we can use something called a condition.

Go into the “ undefinedKey Press - Space” Event of obj_car and add an Action called “undefined If Any Object At Place”.

This action works a little differently from the ones we have been using so far because instead of telling our Object to perform a specific action, it allows us to control when other actions run.

If we drag the already existing "undefined Set Speed" action to the right side of our new block, we'll see that the two become connected by a green line:

undefined

This means that the “Set Speed” action is now dependent on the “If Any Object At Place” condition. When the condition is fulfilled, the dependent action will be performed, otherwise it'll never run.

There are many different kinds of conditions. “If Any Object At Place” checks for a collision with objects at a certain place in the room.

We want to check for a collision at the instance’s own position, so we'll check the “Relative” boxes next to “X” and “Y”.

We only want to start driving if a collision is NOT found, so also check the “Not” box. (Otherwise, we would only be able to start driving if we are already colliding with something.)

We can also make the “ undefined Play Audio” action dependent on our condition by dragging it directly to the right side of it.

undefined

Now, all we need to do is add the exact same condition to our four "undefined Key-Press" events, so the arrow keys won’t turn the car once it's crashed. And voilà, our game is now bug-free!

Congratulations: you just made your first game in GameMaker!

Continue adding more levels and gameplay features, and upload it to GX.games to show off your creation to your friends and family.

If you're ready to move on to a platformer, arcade classic, or adventure game, check out our other tutorials.

Happy GameMaking!