How to Make a Sonic game in game maker: part 1
Hey every, It’s me the SingleShot gamer!
And Like Promised this is the first part of my text game maker tutorials.
Now while I know anyone who’s reading this has already seen my first four videos on you tube,
I’m still going to be starting from the very beginning!
Just for those people who prefer text tutorials.
It also should help anyone who watched me video and can’t follow along, or can’t copy the text
Due to any reason.
I will be formatting this is a step by step style, where I will tell you what to do in order of how
I go about doing it.
But I will also be posting complete scripts or all code at the end of the blog.
Now I recommend a intermediate knowledge of GML programming to get the most out of this
Tutorial.
Or at bare minimum a understanding of Game makers work flow.
Because if you don’t know your way around the version of game maker you're using
You will get lost!
I myself will be Working from the perspective of game maker studio 2
but I will try my best to make note of where ever the code differs!
Now With all that being said, Let’s us Begin!
So for this tutorial we will be building the bare bones foundation that every tutorial after will be
adding to or revising from.
If your using Game maker Studio 2 you want to create a GML project.
Starting out we are going to want to make two sprites for testing purposes.
nothing to crazy just a grey block to stand in for collision and a blue ball for sonic.

make the blue ball 32x32 pixels and center its origin point.

the grey blocks not to important, just make it square and origin in the top left.
now we are going to want to go down to our objects and create a group by right clicking on the folder.
call this group master Collisions.
this group will hold the parent objects for any collision type we make.
in this group create a object which we will call obj_wall
this is our base collision object, one that sonic (or whoever your main character is!)
will be colliding with always.
now we will be creating two more objects,
first will be obj_player
this will be our player object, the one which the player controls.
Next is obj_block
this is our first child for our collision master.
now lets give obj_player our player sprite, and obj_block our grey block sprite.
now with that all done, lets head to our player object and start coding!
first add a create event (if you are using studio 1.x or below to will want to also go to the control tab and add a execute code action. this is how you code in studio 1.x and below.)
in this we will be making some variables that we will be using a lot.
The first two variables will be called
hsp, vsp
and set them both to 0.
They are going to represent our horizontal speed and vertical speed.
next make another two called
hspl, vspl
and set them both to 16.
They are going to represent our horizontal and vertical speed limits.
Now sonic games are momentum based platformers, so sonic will slowly gain and loss speed.
For this we need to make two more variables.
acc, dcc
acc for acceleration.
And dcc for deceleration.
We will set acc to 0.046875
And dcc to 0.5
Now we will make another variable called FRC for friction.
frc
And set it to 0.046875
The same as acceleration.
This is how much speed sonic will loss when not in motion.
Now we will make another variable called grv or gravity
grv
And set it to 0.21875
This is how fast sonic will fall while in the air.
And last we will create another variable and call it ground.
ground
This we will set to false.
This will tell us if sonic in on the ground or in the air.
after this our Create Event should look like this.
/// create event
hsp = 0;
vsp = 0;
hspl = 16;
vspl = 16;
acc = 0.046875;
dcc = 0.5;
frc = 0.046875;
grv = 0.21875;
ground = false;
Now we will go scripts and create one called
player_physics
this script will handle all the physics or in other words how the player interacts with the solid objects around them.
The reason I’m using a script and not adding this directly into the step event is so I can quickly reuse this for other object, and to keep the code neatly isolated from the rest of the player’s scripts.
The first thing we will do is create the speed limits the player can act in.
To prevent him from gaining too much speed and breaking the game.
//limits
If hsp > hspl hsp = hspl;
This says if our horizontal speed is greater than it's limit, it then become equal to it.
So it can never go over.
If hsp<-hspl hsp = -hspl;
This does the same but for the opposite direction.
If vsp>vspl vsp = vspl;
This make it so the player can never fall faster that his limit.
Basically terminal velocity.
If vsp<-vspl vsp=-vspl;
And again the same for the other direction.
Now that we have limits we need to have the player move with his speed.
To do this I’m going to use for statements.
If you don’t know what that is let me explain,
for(i=0;)
so starting out it will run the first statement, making i equal to 0.
for(i=0;i<10;)
Then after that it asks a question, and if the question is a true statement 0 is in fact less than 10
It runs the expression
for(i=0;i<10;)
{
//Random code
}
Or in other words whatever is in those brackets.
And after that it runs the next statement
for(i=0;i<10;i+=1)
{
//random code
}
And after the second statement it ask the previous question again.
Now i equaling 1 is still less than 10 so it will run the expression again.
And it will repeat adding 1 to i over and over until the question is a untrue statement.
Ok so back on topic
If hsp >0
{
}
First we ask if our horizontal speed is greater than zero, if we are not standing still and moving right.
If hsp >0
{
for(i=0; i<hsp ;i+=1)
{
x+=1;
}
}
This will make the code repeat moving us right 1 pixel of our horizontal speed.
Now the reason we are using a for statement in place of a repeat statement is for this.
//h movemnt
If hsp >0
{
for(i=0; i<hsp && !collision_circle(x+16,y,3,obj_walls,true,true) ;i+=1)
{
x+=1;
}
}
So if we come into collision with a wall before we move our full distance we will stop.
now the collision_circle expression will make a small invisible circle where we tell it to.
And if that circle comes into contact with a wall it will tell us.
With the exclamation point it make it a not check.
So as long as the circle is not colliding with a wall the statement will run as normal.
Also the x is equal to the object's origin point. Or where it is in the room.
now after that add
Now we are just going to repeat this for the other direction.
if hsp<0
{
for(i=0;i>hsp && !collision_circle(x-16,y,3,obj_walls,true,true);i-=1)
{
x-=1;
}
}
Making the horizontal speed less than and changing some of those pluses to negatives.
//v motion
Now we are going to do the same again but this time along the vertical axis
Or going up and down .
if vsp>0
{
for(i=0;i<vsp &&!collision_circle(x,y+16,3,obj_walls,true,true);i+=1)
{
y+=1;
}
}
This will let the player move down.
Instead of tying the +16 to the x it attached to the y.
As Well as adding to the y.
if vsp<0
{
for(i=0;i>vsp && !collision_circle(x,y-16,3,obj_walls,true,true);i-=1;)
{
y-=1;
}
}
And this will let the player move up.
///wall collision
Now even though we set up single pixel movement, it's not pixel perfect.
So we need a correction script.
while(collision_circle(x+16,y,3,obj_walls,true,true))
{
x-=1;
}
What a while statement does is as long as it is true it will keep running the expression without letting the game advance.
Be careful it’s easy to freeze your game if you make a statement that's always true.
This statement will move the player out off a wall if he is inside it on the right.
while(collision_circle(x-16,y,3,obj_walls,true,true))
{
x+=1;
}
And this will move the player out side a wall if he is in it on the left.
///landing.
Now we need to make some scripts that stick the player to the ground if he is touching it.
if vsp>=0 && !ground && collision_circle(x,y+16,4,obj_walls,true,true)
{
vsp=0;
ground = true;
}
This will make it so that if you are falling or at zero velocity and the ground it below
Your your snap to it, killing all vertical speed.
And change ground to true so that the statement doesn't loop.
Plus its easier to check if we are on the ground for other questions with this.
/// leave ground
if !collision_circle(x,y+16,4,obj_walls,true,true) && ground{
ground = false;
}
And this make it so that if you not touching the ground, but you are in ground mode
It fixes it self.
///gravity
And last we need gravity, so the player doesn't just float like he is in space.
This is pretty simple.
if !ground vsp+=grv;
So as long as you're not on the ground we add you gravitation force you your vertical speed to pull you down.
And this it it for the physics. We will be adding more to this at a later date but for now we have the ground works.
Next we want to go to the player and add player_physics to the step event.
This will run the code once every frame of game play.
go to the player object and add a step event then add this code
player_physics();
Now that the player character is interacting with the world as we want him too,
We need to add a way for the player to control him.
For this we are going to create another script called
We need to add a way for the player to control him.
For this we are going to create another script called
player_move
ones you have created the script open it up.
//controls
First up we are going to make a few shortcuts
key_r = keyboard_check(vk_right);
key_l = keyboard_check(vk_left);
key_a = keyboard_check_pressed(vk_space);
This way we can type out one of the short phases instead of the long one.
Plus as a bonus, if we at any point want to change key bindings we will only need to
Change one line of code.
First up we are going to make a few shortcuts
key_r = keyboard_check(vk_right);
key_l = keyboard_check(vk_left);
key_a = keyboard_check_pressed(vk_space);
This way we can type out one of the short phases instead of the long one.
Plus as a bonus, if we at any point want to change key bindings we will only need to
Change one line of code.
also if you want to use letters instead of main keys you can use ord("");
like
key_a = keyboard_check_pressed(ord("A"));
but with that out of the way, lest move on.like
key_a = keyboard_check_pressed(ord("A"));
//player movement
This is where we will have the player's movement code
if Key_r
{
}
First we will ask if the right key is being pressed.
If key_r
{
If hsp >=0 hsp+=acc
}
Now we ask if the player horizontal speed is or greater than zero.
If it is than we will add the player’s acceleration to his speed.
If key_r
{
If hsp >=0 hsp+=acc else hsp+=dcc;
}
But if his horizontal speed is not greater than zero due to have been moving left we will have him decelerate to zero, So that he can gain speed as normal.
if key_l
{
if hsp<=0 hsp-=acc else hsp-=dcc;
}
And repeat the code for left by reversing our question around.
Now we need a way for the player to slow down if he is not being controlled.
if !key_r && !key_l
{
}
So we ask if the right key and the left key are not being held.
if !key_r && !key_l
{
if hsp > 0 hsp-=frc;
}
If the aren't then if the players horizontal speed is greater than zero or if he is moving right
Then we subtract his speed by his friction slowing him down.
if !key_r && !key_l
{
if hsp > 0 hsp-=frc;
if hsp<0 hsp+=frc;
}
We do the same for his left, adding his friction to slow him down.
Now if you haven't noticed by now, if sonic horizontal speed is zero then he is standing still.
If it’s a positive number he moving right, and if it is negative he moving left.
So with that in mind
if !key_r && !key_l
{
if hsp > 0 hsp-=frc;
if hsp<0 hsp+=frc;
if hsp <= frc && hsp >= -frc hsp=0;
}
We make it so that if his horizontal speed is less or equal to his friction
And if its greater or equal to his negative friction his horizontal speed will reduce to zero.
Other wise he could slide forever.
//jumping
Now last but not least we will make this hedgehog jump.
If key_a && ground
{
}
So if the player is on the ground and you press the A key
if key_a && ground
{
ground = false;
vsp=-6;
}
We will detach the player from the ground and set his vertical speed to -6
Making him fly up, till gravity pulls him back down.
Ok now all that is done lets add player_move to the players step event after player_physics
player_physics();
player_move();
Whelp after all that the player should be moving like we want him to!
And that's all for this tutorial, its a little long as it is.
Next time we will begin to add that 360 degree movement sonic is know for.
And all you need to know to make it work.
But until next time, this is the SingleShot gamer signing out. Thanks for checking this post out!
Peace out!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Also as promised here is all the scripts from this part in a single code file.
////////////////////// create event
hsp = 0;
vsp = 0;
hspl = 16;
vspl = 16;
acc = 0.046875;
dcc = 0.5;
frc = 0.046875;
grv = 0.21875;
ground = false;
/////////////////////////player_physics()
//limits
If hsp > hspl hsp = hspl;
If hsp<-hspl hsp = -hspl;
If vsp>vspl vsp = vspl;
If vsp<-vspl vsp=-vspl;
//h movemnt
If hsp >0
{
for(i=0; i<hsp && !collision_circle(x+16,y,3,obj_walls,true,true) ;i+=1)
{
x+=1;
}
}
if hsp<0
{
for(i=0;i>hsp && !collision_circle(x-16,y,3,obj_walls,true,true);i-=1)
{
x-=1;
}
}
//v motion
if vsp>0
{
for(i=0;i<vsp &&!collision_circle(x,y+16,3,obj_walls,true,true);i+=1)
{
y+=1;
}
}
if vsp<0
{
for(i=0;i>vsp && !collision_circle(x,y-16,3,obj_walls,true,true);i-=1;)
{
y-=1;
}
}
///wall collision
while(collision_circle(x+16,y,3,obj_walls,true,true))
{
x-=1;
}
while(collision_circle(x-16,y,3,obj_walls,true,true))
{
x+=1;
}
///landing.
if vsp>=0 && !ground && collision_circle(x,y+16,4,obj_walls,true,true)
{
vsp=0;
ground = true;
}
/// leave ground
if !collision_circle(x,y+16,4,obj_walls,true,true) && ground{
ground = false;
}
///gravity
if !ground vsp+=grv;
/////////////////player_move()
//controls
key_r = keyboard_check(vk_right);
key_l = keyboard_check(vk_left);
key_a = keyboard_check_pressed(vk_space);
//player movement
If key_r
{
If hsp >=0 hsp+=acc else hsp+=dcc;
}
if key_l
{
if hsp<=0 hsp-=acc else hsp-=dcc;
}
if !key_r && !key_l
{
if hsp > 0 hsp-=frc;
if hsp<0 hsp+=frc;
if hsp <= frc && hsp >= -frc hsp=0;
}
//jumping
if key_a && ground
{
ground = false;
vsp=-6;
}
////////////////////////player step event
player_physics();
player_move();
this is so helpful thanks single shot i had a bad time trying to see the code in my pc with my bad internet
ReplyDeleteThis comment has been removed by the author.
ReplyDelete