Video version:

Game Maker tutorial series

Hello, I’m Syndelis and I’m going to be making this GameMaker Studio (1.x and 2) series focused on recreating old games, as suggested by my friend Devon. Throughout this series, you’ll hopefully have learned how to make games on an array of different styles as well as gain some ideas on how to develop your own.
For the first ever tutorial, you’ll be going to learn how to code a clone of Breakout. This is a very interesting game to start off because it’s quite simple to make and teaches a lot about collisions and drawing events.I’ll also be teaching you how to modify the game in any way you want and leave some challenges for you to complete on your own.
Also, if at any moment you feel that you don’t understand something, I recommend watching the “companion” video that was released alongside this tutorial.
Without further ado, let’s code something.



_____________________The Player_____________________


Alright, create a new project called whatever you want (Don’t take that too literally). Right-click the Objects folder and create a new one.You may name it whatever you want, just take in consideration the Naming Conventions (If you don’t know what that means, I recommend checking out my Tutorial #0 at Eluvious). I’ll be calling mine “o_pad” since it accurately represents what the object is gonna be; a pad(Controlled by the player). Add a Create Even

OBS: GameMaker: Studio 1.x users will also have to go to the control tab, on the right of the object window, and drag a “Piece of paper” under Code to the Create Event’s Actions.

The Create Event runs only once per object instance, so we can use it to set some variables.
Here we’ll be setting the width and height of the player’s pad, as well as defining where in the room we’re gonna start at.

w = 200/2 h = 20/2 y = room_height - 50 x = room_width/2

Now the explanation of the code:

  • LINES 1 & 2: We are setting the variables `w` and `h`, which represent width and height respectively. The reason why we’re dividing those by 2 is that the rectangle is going to be drawn centered on the player’s (`x` , `y`) coordinates. If you didn’t understand, no worries, you’ll see what I mean later on.
  • LINES 3 & 4: Here we are defining the player’s (`x` , `y`) coordinates starting points. Since we want it to start at the horizontal center of the screen and just a little above the screen’s bottom edge, we set its `x` to be half of the room size, which on this game is also the size of your screen, and `y` to be a little less than the room’s height, which means it’ll be slightly above the edge of the screen (Since `y` is counted from top to bottom).

Now that we got the player’s starting position and sizes, we will be drawing it to the screen. Create a Draw Even. Those events are capable of interpreting the code as fast as you want (FPS), but do take quite a lot of processing power since they can run Drawing functions. On it, we want to draw a rectangle with the player’s sizes and luckily for us, GameMaker has a function that draws rectangles called draw_rectangle().



  • LINE 1: The function draw_rectangle() requires 5 arguments, the Top Left and Bottom Right corners along with whether it should be just an outline or not. The top left corner would be our X position less the width we’ve set along with our Y position less the height we’ve set (x-w,y-h). The same logic goes to the right bottom corner, except this time we’re adding instead of subtracting both width and height(x+w,y+h). I chose to make it just an outline because it looks better in my opinion, but you may change that “true” to “false” if you disagree with me.

Now, let’s try the game, shall we? Create a Room (if there’s none already) and put the player inside it (See the video if you don’t know how to do so). I recommend setting the Background to be a dark color – since our rectangle is gonna be drawn white – and setting the room’s speed to 60.
If you’ve done everything right, you should see the borders of a rectangle on the bottom middle of the screen. It’s not bad, but it would be way cooler if we could actually control the player, no?

Close the game and create a Step Event for our pad object. They are just like Draw Events, except they can’t run any drawing code whatsoever, which makes them a lot “lighter” to the computer. There, we’ll be putting the player’s movement logic so that it actually moves when we press something. In order to check if a key is not being held down on your machine, we can use GameMaker’s keyboard_check(). That function will be returning _true_ or _false_ depending on the state of the desired key.

Type in this:

if keyboard_check(vk_left) {    x = x - 5} if keyboard_check(vk_right) {    x = x + 5} if x - w < 0 { x = w } if x + w > room_width { x = room_width - w }


  • LINES 1 to 3: On those lines, we check whether the Left arrow key is being pressed or not and, if it is, we subtract from our x coordinate, which defines where we are horizontally (Counted from left to right).
  • LINES 4 to 6: Same as above, except this time we are checking for the Right arrow key and if it is being pressed, we add to our Xcoordinate.LINES 7 & 8: These lines make sure that the player pad won’t go outside of the room.
  • LINE 7: “If the center of the pad subtracted by its width (x-w) is more to the left than the actual screen (<0), make sure the center is at least “width” distanced from the left side of the screen (x = w).
  • LINE 8: “If the center of the pad added to its width (x+w) is more to the right than the actual screen (>room_width), make sure the center is at least “width” distanced from the right side of the screen (x = room_width-w)”

OBS: x is counted from Left to Right, starting at 0 on the left-most edge of your room and going up to room_width, which is the right-most part of it.
Now, if you run the game, you should be able to move the pad horizontally using the arrow keys. Okay, that is fancy and all, but we still need a ball to play around with.



_____________________The Ball_____________________

Create a new object and, again, call it whatever you want, but I’m calling mine “o_ball”. On the Create Event, you’ll want to put this:

r = 10x = room_width/2 y = room_width/2 + 50 speed = 10 direction = random(360)


  • LINE 1: We’re setting the variable that will be serving as the ball’s radius.
  • LINES 2 & 3: Here we set the starting position of the ball. It’s just a little above the exact middle of the room.
  • LINES 4 & 5: Here we are seeing some new built-in variables. Speed and Direction are two variables that are always going to be working together. speed defines how fast a given object is going to move every frame, while direction says where should the ball be moving to (Counted on degrees). For the direction, we will be giving a random number between 0 and 360 (random(360)), which basically means that it can go anyway it wants to.

With just that, the ball will move wherever it chose to, with no Step Events or anything required. The only problem here is that we can neither see the ball or make it stay inside the game’s room. To fix that, create both a Step Event and a Draw Event.
On the Step Event, put this:

if x+hspeed > room_width or x+hspeed < 0 { hspeed = hspeed * -1 } if y+vspeed < 0 { vspeed = vspeed * -1 }


  • LINES 1 & 2: hspeed and vspeed are the horizontal and vertical vectors of the whole speed thing, accounting for the “direction”.You can say that hspeed = speed * cos(direction), vspeed = speed * sin(direction) and that speed² = hspeed² + vspeed² (With the latter not being actual code). Multiplying by -1 whenever the ball is gonna go outside of the room makes its corresponding direction to be inverted.
  • LINE 1: If our next x (x + hspeed) is going to be more to the right or more to the left of the screen (> room_width or < 0), invert our horizontal speed so that we don’t actually go out of bounds.
  • LINE 2: If our next y (y + vspeed) is going to be over the screen (< 0), invert our vertical speed so that we don’t actually go out of bounds. The reason we don’t care for the ball to go under the screen is that when the ball does so, the player should actually lose a life.

OBS: The angulation of direction is not inverted. That would only happen if we were to multiply both hspeed and vspeed by -1.

And on the Draw Event, put this:



  • LINE 1: the draw_circle() function takes 4 arguments; The x and y positions to be drawn at, the radius and whether it’s just an outline or not (which would be a full circle).

If we were to run the game right now, we would see that the ball indeed does bounce, but only when its collision is not with the bottom-most part since when the ball goes past that part the player should lose a life and the ball’s position should be reset. Also, the ball can’t collide with the pad just yet.
To fix those problems, firstly we’re gonna add these lines to the ball’s Create Event:

// The code before it [...]. You don't actually need to add this line, this just represents that the following lines are the last ones. xstart = x ystart = y

and then, on the Step Event:

// The code before it [...] if y > room_height { x = xstart y = ystart direction = random(360) // add scoring here later }


  • LINES 2 & 3 of Create Event: These set the built-in variables xstart and ystart so later we can call them on the Step Event.
  • LINES 2 to 6 of Step Event: These reset the ball’s position to its original after going below the bottom edge of the screen as well as giving it a new direction.

Now that the ball-going-bellow problem has been fixed, let’s add some collision between the pad and the ball. In order to achieve that, we will be using the rectangle_in_circle() function, which checks whether a given rectangle is inside of a given circle. On our case, the rectangle is the pad and the circle is the ball.

On the ball’s Step Event, type in this:

// Code above [...] if instance_exists(o_pad) { p = o_pad if rectangle_in_circle(p.x-p.w,p.y-p.h,p.x+p.w,p.y+p.h,x,y,r) { vspeed = -vspeed } }


  • LINE 2 & 3: We check whether there is a pad on the room and if there is, we create a variable to reference it called p so we don’t need to type “o_pad” every single time.
  • LINES 4 to 6: We check whether the next position of the ball is going to be inside the pad and, if that’s true, we invert its vertical speed so it goes up rather than down.

Ok, the ball and the pad are working quite nicely now, but the ball physics aren’t even close to what they feel like on the Breakout games. Usually, the ball gains or loses some angulation on its direction on that kind of games whenever it hits something, so we could try using some math to mimic it a lot better. Btw, don’t forget to put the ball in the room.

ATTENTION! The following Subtitle, ADVANCED BALL, is going to feature a lot of angle maths that might be a little confusing for some people, so I recommend skipping to ONE LAST CHANGE TO IT if you are not very familiar with them/are already happy with how the physics behave. So, again, it’s optional.


Advanced Ball

Alright, if you’re reading this it means that you’re ready to take on the math stuff. Before continuing on, I want you to know that the math used to reflect an angle from the 3rd quadrant to the 4th and vice-versa can be represented by the function R(i) = 360 - i, where i is the incident angle and R is the resulting angle (This is like saying vspeed = -vspeed). But that’s not everything we need to do; we also need to add some slight variation on the angle based on where on the pad the ball bounced. To do that, we’re gonna subtract thepad’s position (p.x) from the ball’s next position (x+hspeed).
Firstly, go back to the collision code between the pad and the ball that we just made. When you’re there, remove the vspeed =-vspeed and put this where it used to be:

// Collision code and code before it [...] direction = 360-direction - ((sign((x+hspeed) - p.x)) * 20)*(sign(vspeed)) direction = clamp(direction,20,160)

Ok, so before you regret going to this section, here’s the Explanation:

  • LINE 2: Here we bounce the angle, as discussed before, and then add some slight variation to it based on where the ball is going to touch.
  • LINE 3: the function clamp() makes sure a given value is the second argument and the third. On this case, we make sure the direction of the ball is not bigger than 160 and is not smaller than 20, since sharper values would make for a really slow moving ball.

One last change to the ball

Okay, let’s make one change to the ball. Wherever you find direction = random(360), change that to direction = random_range(-60,60) *choose(-1,1).  random_range()will select a random number between the given values whilechoose()` will randomly, well, choose one of the arguments out of up to 15 of them. That will make sure the angle of the ball doesn’t turn out to be too close to 90, which wouldn’t make for a funny ball in my opinion.




Now, the only thing that is really missing is the bricks. They can easily be achieved by creating some kind of immobile pad, but with significantly reduced width and height. In order to make that, we can Right-Click the pad object, duplicate it and delete its Step Event afterward, since we don’t want the bricks to move (I guess). Also, open its Create Event and change the width and height of it, I’ll be using 25 as the width and 5 as the height myself.


Placing Bricks Automatically

After you’re done with it, we’re gonna make the game place the bricks inside the room automatically. Go to the main room of the game and click on the Creation Code. This is basically them room’s version of a Create Event, as in it only runs once. There, we’ll put some logic for the game to nicely put the bricks inside of the room.
For that to be achieved we’re gonna be using what is called a for loop. It is a special kind of statement that keeps repeating itself while something is true and that adds to a variable for every cycle it does. With this, we can use some math to find where each brick should be placed at. I’ll post the code and explain it afterwards since it will be easier:

for (var yy = 0;yy < 5; yy++) { for (var xx = 0;xx < room_width/(50+20); xx++) { // if on GameMaker:Studio 1.x type in the following line: instance_create(25+xx*(50+20),100 + 30*yy,o_brick) // else, if on GameMaker Studio 2, type in this: instance_create_depth(25+xx*(50+20),100 + 30*yy,depth,o_brick) } }


  • LINE 1: We create the local variable yy (hence why it has var before it). The loop will run 5 times because it does so while yy is less than 5 (yy < 5) and every cycle it adds one more (yy++).
  • LINE 2: We create the local variable xx which will make the loop run while it’s under room_width/(50+20). This division was made to find out how many 50 pixels long we can fit with 20 pixels of space in between them.
  • LINE 4 or 7: Creates a brick at a position defined by the constantly adding variables that were created by the loop.

Now that we got the brick spawn system working, we just need to make the ball collide with them. Put that on the ball’s Step Event:

// Code above [...] if instance_exists(o_brick) { b = instance_nearest(x,y,o_brick) if rectangle_in_circle(b.x-b.w,b.y-b.h,b.x+b.w,b.y+b.h,x,y,r)  { vspeed = vspeed * -1 with b { instance_destroy() } } }


  • LINE 2: Checks whether there are any bricks left on the game.
  • LINE 3: References the nearest instance of “o_brick” as b since just saying b = o_brick would reference the first brick ever to be placed on the room. That makes sure we’re checking for the actual nearest brick.
  • LINE 4: Checks whether we’ve collided with said brick or not.
  • LINE 5: Inverts the vertical speed to reflect the ball from it.
  • LINE 6: Runs instance_destroy(), which destroys the instance calling it, inside of the brick’s code. Every time a with is being used, that means the following code is actually being executed by the other instance.


Coloring the bricks

Now the ball should hopefully be colliding with bricks as well as the pad.
For the last thing we’re gonna be doing here, go back to the brick’s Create Event. This time around we’re gonna be giving random colors for each different brick so that they don’t look boring white.

color = make_color_rgb(random_range(60,255),random_range(60,255),random_range(60,255))


  • LINE 1: We are creating a variable which will hold the color value created by the function make_color_rgb(). This functions takes 3arguments, “RED, GREEN, BLUE” and mixes them to create a new color. The reason why we’re using random_range() is because if the values are too small, the color is going to be too dark, which is not good considering we have a black background on the game.

We got a color variable working now, but that won’t change the actual color of the brick by itself. What we need to do is change the function draw_rectangle() on the brick’s Draw Event to draw_rectangle_color().



LINE 1: When compared to draw_rectangle(), draw_rectangle_color() takes 4 more arguments, which are all colors for each different corner of the rectangle. Since we want the whole rectangle to be the same color, we just set all of the 4 new arguments as color.


That was it, folks. As always, if you need any help still, you can find me on my twitter (, at Eluvious’ discord ( or at GDN’s discord ( Thanks for reading!

Source Code:

Author Syndelis
Categories Gamemaker Tutorials
Views 428


No Comments

Leave a Reply


RT @discordapp: Congress can overrule the FCC using the Congressional Review Act (CRA) and we need just #OneMoreVote to win in the Senate.…
The new Eluvious site will be launching soon! Stay tuned everyone.
Haven’t tweeted in a while. What’s up people?


32 User(s) Online Join Server
  • Awertnex
  • TheSalami
  • Xero_Root
  • TheSomeoneXD
  • Jigglyking20
  • lightprincess98