Legacy GM Simple Infinite Platform Runner (1 Button Game)

M

Maximus

Guest
GM Version: GM Studio
Target Platform: ALL
Download: (see code examples below)
Links: NA

So, I decided to made a quick infinite platform runner (like if flappy bird was called jumpy square) and it was so easy I thought I'd post it here.

How it works:
The player is stationary in the room and platforms fly in at random positions and sizes from the right and are destroyed when they leave the room on the left. 1 button, you can jump. If the player goes outside the bottom or left edge of the room the room restarts.

3 objects:
obj_player
obj_platform
obj_platform_spawner
2 sprites:
spr_player: 32 * 32 pink square (must be pink or it doesn't work) origin at (16,16)
spr_platform: 32 * 32 origin at (0,0)
1 room

Lets start with the player object

Information about object: obj_player
Sprite: spr_player
Solid: false
Visible: true
Depth: 0
Persistent: false
Parent:
Children:
Mask:
No Physics Object

Create Event:
execute code:
Code:
/// Initialise Variables
grav = 0.2;
hsp = 0;
vsp = 0;
jumpspeed = 7;
x_pos = floor(0.25 * room_width);
In the create event of the player we initialise the variables:
grav: the vertical speed that will be added every step
hsp: a container for the horizontal speed of our player
vsp: a container for the vertical speed of our player
jumpspeed: initial speed of the players jump
x_pos: the horizontal position in the room the player will try to stay at. I've set it to 1/4 of the way in from the left and floored the value (rounded to lowest whole number). You could just say x_pos = 100 or something like that, but the thought was 'I want my player 1/4 of the way in from the left' and that's probably going to stay the same even if I decide to change the room dimensions later on.

A bit more happens in the step event so I'll break it up a bit.
Step Event:
execute code:
Code:
key_jump = mouse_check_button_pressed(mb_any);
with the use of mb_any, if the player gets frustrated enough that they just start bashing their head agaist the mouse, it still works.
Code:
// move back to position if pushed back
hsp = x <  x_pos;
comment says its all. horizontal speed will be 1 (right direction) if the player is to the left of x_pos (the oh 💩💩💩💩 oh 💩💩💩💩 oh 💩💩💩💩 zone)
Code:
// v speed
vsp = min ( 10, vsp + grav );
the min() function returns the smallest of its arguments. So this means the maximum falling speed is 10.
Code:
if (key_jump && place_meeting(x,y+1,obj_platform))
{
   vsp = -jumpspeed;
}
If the player has pressed the jump button and is on a platform, set the vertical speed to negative jumpspeed.


below code checks for collisions and moves the player by the amount of its hsp and vsp.
Code:
// Horizontal Collision
if place_meeting(x+round(hsp),y,obj_platform) // are we about to hit a wall?
{
    while !place_meeting(x+sign(hsp),y,obj_platform) // can we move 1 pix without hitting the platform?
    {
        x += sign(hsp); // move closer by one and check again
    }
    hsp = 0; // you've hit a wall, stop.
}
else // ain't nuthin' gonna break my stride
{
    x += round(hsp);
}
// Vertical Collision
if place_meeting(x, y + round(vsp), obj_platform)
{
    while !place_meeting(x,y+sign(vsp),obj_platform)
    {
        y += sign(vsp);
    }
    vsp = 0;
}
else
{
    y += round(vsp);
}
(pretty much the same as in Shaun Spaulding's platformer tute)


Last thing for the player, the kill condition.
Code:
// restart if outside room
if (( bbox_right < 0 ) || (bbox_top > room_height))
{
    room_restart();
}
I used bbox so only when the whole sprite (the collision box at least) is outside the room will it restart. I don't check if we leave on the right as this wont happen and I don't check the top because you don't want the room to restart just because you jumped too high (We should design the game to avoid this however as it doesn't look good, which we do later by giving the platforms a max spawn height less than the jump height).
The player is done. Let's make the platform object now.

Information about object: obj_platform
Sprite: spr_platform
Solid: false
Visible: true
Depth: 0
Persistent: false
Parent:
Children:
Mask:
No Physics Object
Step Event:
execute code:
For the platform, all it needs it to do is move left and not give a 💩💩💩💩 who gets in its way. So, if is going to hit the player, it just does what it wants and pushes the player out of the way.
Code:
x += hsp; // move
var player = instance_nearest(x,y,obj_player); // get the player instance
while (place_meeting(x, y, obj_player)) // if player is in our way
{
   player.x--; // push it to the left hand side
}
Other than that, we just need to destroy it if it's outta sight.
Code:
if (bbox_right < 0)
{
    instance_destroy();
}
Notice that we have not initialised hsp, but we use it in the step event. Won't that throw an error? Well, if you placed it in the room manually yes but we aren't going to do that. Instead, we are going to create the platforms dynamically with a spawner object and set the variables there. Why not just put default values in anyway? I want my objects coming out of the spawner. if they came from somewhere else, that was a mistake. I'd rather get an error than have something I didn't intend to happen, happen.

Now the spawner, an object that hides in the background and spits out a new platform whenever we need it aslo increasing the speed at regular intervals.
Information about object: obj_platform_spawner
Sprite:
Solid: false
Visible: false
Depth: 0
Persistent: false
Parent:
Children:
Mask:
No Physics Object
Create Event:
In the create event for the spawner, we use the variable 'platform_inst' to store the id of the last platform we created. We can then refer to this later to check if we need a new one.
execute code:
Code:
platform_speed = -4; // initial platform speed
tile_size = 32; // grid size for placing the platforms
max_platform_height = 5 // max spawn height of platforms (* tile_size)
max_x_dist = 6; // max horizontal distance between platforms
min_x_dist = 2; // min horizontal distance between platforms
max_y_dist = 3; // max vertical distance between platforms
platform_inst = instance_create(0, tile_size * ceil (0.5 * (room_height / tile_size)), obj_platform);
platform_inst.hsp = platform_speed;
platform_inst.image_xscale = ceil(room_width/tile_size); // stretch the first platform so we have time to prepare for the first jump
platform_inst.image_yscale = room_height div tile_size; // stretch it downwards out of the screen
lvl_timer = 0; // counter to keep track of when to increase difficulty
lvl_time = 300; // interval for increasing difficulty (steps. for time, use room_speed * seconds)
Step Event:
execute code:
First part of the step checks whether the right end of platform_inst is about to enter the room. If so, it creates a new platform, replacing the id in platform_inst with the new one.
Code:
if (platform_inst.bbox_right < (room_width + tile_size))
{
    // get random x distance
    var x_distance  = tile_size * irandom_range(min_x_dist, max_x_dist);
    // add random distance to last platform's x value
    var x_spawn     = platform_inst.bbox_right + x_distance;

    // get random y distance
    var y_distance  = tile_size * irandom_range(-max_y_dist, max_y_dist);
    // get min y value
    var min_y_spawn = tile_size * max_platform_height;
    // get max y value
    var max_y_spawn = tile_size * floor(room_height/tile_size);
    // add random distance to last platform's y value and keep within range
    var y_spawn     = clamp( platform_inst.y + y_distance, min_y_spawn, max_y_spawn);

    // Create new platform and replace the id stored in platform_inst with the id of the newly generated platform
    platform_inst = instance_create(x_spawn, y_spawn, obj_platform);
    // Give new platform the current platform speed
    platform_inst.hsp = platform_speed;
    // Give the platform a random length
    platform_inst.image_xscale = 1 + irandom(10);
    // stretch the platform so it extends below the bottom of the room
    platform_inst.image_yscale = room_height div tile_size;
}
Last bit for the spawner step is incresing the difficulty.
Code:
if (lvl_timer > lvl_time)
{
    lvl_timer = 0;
    platform_speed--;
    with (obj_platform) // using 'with' and the object index, the action is done for every instance
    {
        hsp--;
    }
}
else
{
    lvl_timer++;
}

Now all we need to do is throw these objects in a room and see what happens. Create an empty room, leave everything default and add these 2 lines to the room creation code:
Code:
instance_create(100, 100, obj_player);
instance_create(-100,-100, obj_platform_spawner);
Done. Run the game and you should have a solid starting point for creating your own infinite jumpy game thing.


Edit: Spread random spawning code across more lines for clarity and added code to increase each platform's image_yscale (just looks better, IMO).
 
Last edited by a moderator:
D

Doooooli

Guest
Tried different things but never succeeded, how do I increase the player speed? :p
 

Bingdom

Googledom
Player speed as in jump height?
Easy, change the 'jumpspeed' to a higher value.

The player isn't actually moving sideways, the platforms are.
 
D

Doooooli

Guest
Player speed as in jump height?
Easy, change the 'jumpspeed' to a higher value.

The player isn't actually moving sideways, the platforms are.
haha yea I realised that aswell, thx ^^ :D
 
F

Frostix

Guest
I tried this, and it only creates 2 platforms and then stops. Please help
 
Top