Basic Physics Platformer Controls

tagwolf

Member
GM Version: GMS2
Target Platform: ALL

Summary:
I had made a platform control tutorial that is a bit more advanced than this one as it does not use any of gamemaker's built in physics engine. However someone suggested that I also do a physics one so here it is!
If you're interested in the non-physics version it is available here: https://forum.yoyogames.com/index.p...fer-air-control-diagonal-collision-etc.65684/

This tutorial is scaled for a 32x64 player, but please play around with gravity, friction, dampening, etc in order to get the right feel for your game!

Features:
  • Uses GMS2 physics
  • Jump input buffering
  • My other tutorial has a lot more goodies to it, there are sometimes benefits to using the built in physics engine, especially for particular types of games, but if you want much tighter controls and such you should look at my other tutorial linked above. Still wanted to write this up in case it's useful to your use-case!
Todo:

This probably needs some adjustment to get the feel right and scale. Pixels to Meters is not working how I'd hoped. But this should get you most of the way there. Upping physics evaluations to 60fps will probably help a lot too if you need the responsiveness at the cost of cpu.

Tutorial:
Things to create
  • spr_Player (32x64 pixel, just fill it in with a solid color for now)
  • obj_Player
    • Check the boxes for Solid and Uses Physics
    • Density to 1, Restitution to 0, Linear Damping to 1, and you can leave the other stuff default.
  • obj_Block
    • Check the boxes for Solid and Uses Physics
    • Under the physics settings, change Density to 0. This will make the blocks immune to gravity. (Not sure why kinematic doesn't work for this purpose but hey. This works.
    • Also set Restitution to 0. (We don't want blouncy floors.)
  • rm_default
    • Create a room or in the default one, turn on physics, set Gravity to 100.
In your room, place several obj_Block's to paint a basic level and place your player above the blocks. You don't have to put them on the ground, just make sure they won't fall forever.

obj_Player - Collision Event (obj_Block)
*** This blank event must exist or GameMaker will not register a collision between you and the blocks. ***
Code:
/// @description Placeholder

// So GameMaker registers the event.
obj_Player - Create Event
Code:
/// @description Init Vars

// Forces and Speeds
// Acceleration and jumping forces
x_force = 1000;
y_force = 1000;
// How fast player can move (pixels/second)
max_x_speed = 4;
// Jumping is limited by y_force and gravity room setting

// Input buffering
// Adding a buffer in frames to make jumping more forgiving
jump_buffer = 10;
// Count placeholder (should be 0 here)
jump_buffer_count = 0;

// Controls
control_left = ord("A");
control_right = ord("D");
control_jump = vk_space;

// Prevent player from falling over.
// Disable this if you're making a face dragging game.
phy_fixed_rotation=true;
obj_Player - Step Event
Code:
/// @description Player Movement

// Move right
if keyboard_check(control_right)
{
   physics_apply_force(x, y, x_force, 0); 
}

// Move left
if keyboard_check(control_left)
{
   physics_apply_force(x, y, -x_force, 0); 
}

// Jump Input
if keyboard_check_pressed(control_jump) && jump_buffer_count >= jump_buffer
{
   jump_buffer_count = 0;
}
// Check / increment jump buffer
if jump_buffer_count < jump_buffer
{
   jump_buffer_count++;
}

// Player is standing on ground and account for jump_buffer
if place_meeting(x, y + 1, obj_Block) && jump_buffer_count < jump_buffer
{
   // Jump!
   physics_apply_impulse(x, y, 0, -y_force);
}

// Clamp movement speed so we don't accelerate forever
phy_speed_x = clamp(phy_speed_x, -max_x_speed, max_x_speed);
 
Last edited:
B

babfoxj

Guest
I like what you did. These is very simple code, and sometimes that the best approach. I noticed you use the A/D keys for left/right respectively, then Space for jumping. Is this a common setup for computer-based 2D platform games? Or is this your personal preference?
 

rIKmAN

Member
I like what you did. These is very simple code, and sometimes that the best approach. I noticed you use the A/D keys for left/right respectively, then Space for jumping. Is this a common setup for computer-based 2D platform games? Or is this your personal preference?
WSAD keys are the accepted standard for movement in keyboard controlled games, and when you have your left hand over these keys your thumb is handily pisitioned right near the Space Bar so it makes sense to use it.

Not good for lefties though so it's usually best to add in additional controls methods such as arrow keys for movement, or even better allow the player to rebind them.
 
B

babfoxj

Guest
WSAD keys are the accepted standard for movement in keyboard controlled games, and when you have your left hand over these keys your thumb is handily pisitioned right near the Space Bar so it makes sense to use it.

Not good for lefties though so it's usually best to add in additional controls methods such as arrow keys for movement, or even better allow the player to rebind them.
Thank you for the reply! I do plan on adding functionality for defining custom controls, but at this point I only need to define defaults for my platforming game. I’m looking for a setup ideal for a classic Megaman-style game. Would you have anymore suggestions for something like that?
 

rIKmAN

Member
Thank you for the reply! I do plan on adding functionality for defining custom controls, but at this point I only need to define defaults for my platforming game. I’m looking for a setup ideal for a classic Megaman-style game. Would you have anymore suggestions for something like that?
I'd recommend taking a look at this input library by @Juju.

It will let you bind multiple inputs (including gamepads) to single checks in your code and is really simple to use.
 

rIKmAN

Member
Thanks @rIKmAN! I'm always improving and maintaining my libraries, all suggestions and bug reports are welcome.
You're welcome mate, all the thanks should go to you as it's an awesome little library that does exactly what it says on the tin with zero fuss and is really easy to use! :)
 
D

DayCamp

Guest
Question for you tagwolf. Can you reexplain what phy_fixed_rotation does/means? Additionally, how does this variable translate into moving the player left or right? I have only done basic player movement inputs (such as the ones you have in your code) but have never used phy_fixed_rotation before.
 
Question for you tagwolf. Can you reexplain what phy_fixed_rotation does/means? Additionally, how does this variable translate into moving the player left or right? I have only done basic player movement inputs (such as the ones you have in your code) but have never used phy_fixed_rotation before.
I've not used physics yet myself in GMS:2 but I'm guessing that it's pretty much the same/similar to standard Box2D physics.
If this is the case then when a dynamic physics object is hit by another physics object/force then the object hit will spin around its origin. Imagine if you had a toy car and you were to tap it near one of the corners the car would spin around, the speed and amount it spins dependant on exactly where you tap it and how hard.
By setting phy_fixed_rotation to true then the object will not spin and if you want to change the rotation/angle of the object you have to set it manually.
Hope that makes sense.
 
I'm pretty late to this, but I based a good bit of the physics in a little game I'm making off of this, and I was just wondering if anyone knew if it would be possible to make the y_force get higher the longer you held the spacebar up to a certain point so that you could control your jump height? It's sort of bugging me about this and it'd be so perfect if it had more refined jump control, but I just can't seem to figure it out myself... I'm not super experienced

EDIT: I've tried some tutorials for platformers that do all the physics manually and just sort of interpreting it into the built-in physics variables, but the best I can do is hard-capping the vertical speed when you let go of the button. Not a good solution when a full jump goes in a nice arc like you want lol
 
Last edited:

LiteProg

Member
Would recommend using
if !place_free (x, y+1)
instead of
if place_meeting(x, y + 1, obj_Block)

This way the player can jump when stood on any object, so if you make a different floor block then you can still jump off it
 
Top