Even better (high speed) moving platforms
Some adjustments required for GameMaker Studio 2.3
The following article is for pre 2.3 versions of GameMaker Studio 2. It doesn’t take advantage of functions, chained accessors, structs and other new features of GML/GMS2.3+ IDE. Unfortunately I’m unable to update the series for the foreseeable future, but downloading and importing the final project inside the new IDE should trigger the conversion.
It will run correctly. From there you could refactor and clean the code a bit to suit your taste, I guess.
There’s an oversight in my previous article (i.e. there’s a bug) where if you increase the xvel
or yvel
of the moving platforms above 1
, strange things start to happen. Let’s fix high speed moving platforms.
Why is this happening
This is happening because, as I said in the article, xprevious
and yprevious
get automatically set before the begin step event and they get set just once, never to be updated with the new positions we give to the players during the platform’s moving cycle.
So if the platform is cycling 10 times to move upward (yvel = -10
, cycling pixel by pixel) and it stops right after the 5th cycle iteration (due to a collision like in the image above), it resets the players position back to where they were at the very beginning of the cycle, even if they successfully moved for 5 whole cycles, effectively putting the instances back inside the platform itself.
That’s because we forgot to update the xprevious
and yprevious
upon each successful movement cycle completion.
How to fix it
Let’s create a simple script called instances_update_previous_position
, very similar to instances_reset_position
.
///@func instances_update_previous_position(instances_to_move)
var instances_to_move = argument[0]
var num_of_instances = ds_list_size(instances_to_move)
var index = 0
repeat(num_of_instances)
{
var instance = instances_to_move[| index]
instance.xprevious = instance.x
instance.yprevious = instance.y
index++
}
This script accepts a list and it cycles the list to update the xprevious
and yprevious
variable.
Now inside the move_platform_y
and move_platform_x
scripts, just before destroying the ds lists, call this script passing a list of successfully moved objects. In our case we should already have one. It’s called instances_to_move
but if you look into the code you’ll realize that, at this point in the code, it holds the instances that successfully moved. Instances for which we should update the xprevious
and yprevious
variables.
This should really give us pixel perfect movement. If you find any other bug, please don’t hesitate to leave a comment. Thanks for your patience 🙂
Good tutorial! I’ve modified the moving platform code to follow paths and move in a circular motion – I’m curious to see how you’d implement such cases. Where can you go from here with the series?
Well you just gave me two interesting ideas to explore. I am still experimenting with moving blocks (pushables) but I’m not satisfied with the results so I’ll take a break from that topic and explore these circular/path following platforms instead. Then I guess it’s time to implement some input mapping, game mechanics, enemies, doors, pickups/powerups, world design, a proper camera, room transitions and more. I’ll probably start to use some graphics as well (very soon indeed). I know this doesn’t sound like a plan, but I want to make a simple action/adventure platformer people can use as a base to build their own games from. Nothing really complex but I’d love to give it a polished feel with menus and so on. Sounds cool?
Btw, thanks for your support! You just made my day!
No worries, the least I could give. You’ve done the majority of the hard work needed for the base of a platformer so everything on top of this is just a bonus really. I look forward to seeing where you’re going with all this
Thank you so much for these amazing tutorials. You have no idea how much this has helped an amateur like me who declared moving platforms the bane of my existence, despite being essential to a proper 2D-platformer (imo). As Luke mentioned, this is definitely a solid base for a good platformer and everything else will be a very appreciated bonus.
Keep up the amazing work.
Hi and thanks for your tutorial! They’re very useful and helped me a lot. As Luke said, it truly is a solid base for a proper 2D-platformer and anything extra would be an appreciated bonus.
Keep up the great work!
I do have one question though: How would I proceed to implement friction (acceleration/deceleration) to the player’s movement?
I understand if this is not the place to ask for such things but I wanted to try and ask anyways.
Good day.
Thanks for your support and for your kind words. I’m glad these posts helped you.
About accelerations and deceleration, I’ll have a new post in a couple of days specifically about that but to give you an idea it works like this: wherever you set the speed of your player, you’d use a
lerp
function or anapproach
script (link) to set the x velocity, instead of setting it directly to the maximum. Basically you want the x velocity to “approach” the maximum speed by a given value over a short period of time (the greater the approach value, the faster the acceleration). The same is valid whenever you set the x velocity to zero; you’d want the velocity to “approach” zero to simulate deceleration.Hope this helps but anyway I’ll write a post about it very soon!
Again, thanks for your support!
Thanks for the quick reply and sorry for the double message (had some trouble with the spam filter)! I got it to work using lerp but I am still excited to see how you’ll do it and will be looking forward to anything you post in the future. Really great content!
Have a good day.
Hi thank you for this amazing tutorial!
But i have a problem, how to scale up this project?
Hey Savernish, thanks for the kind words.
What do you mean by scale up? If you’re looking into expanding the engine into a game, there’s a lot of stuff to consider such as adding multiple levels (and connecting them), adding graphics and animations, sounds, menus, gamepad inputs, game mechanics such as saving/loading/spawning/restarting, enemies and lots of different things. There’s a great course on udemy that covers A LOT and it’s really well made: How to Make Tile Based Platform Games in Gamemaker Studio 2. Most of the time it’s heavily discounted (like 80-90% off). It uses tile based collisions but you could switch the collision system easily once you understand the underlying mechanics.
If Udemy’s not your thing, there’s a lot of complete platformer courses on youtube as well. I went through most of them myself and they’re good!
There’s really a lot to cover and right now it’s impossible for me to write about each aspect involved in making a full scale game (especially now that I got less and less time to do gamedev AND write about it), but I hope I gave you some direction. If not, feel free to get in touch directly (even via twitter, I have my DMs open) 🙂
Having said that, I really hope I can find some time on weekends to get back to this series and write new stuff. Until then, let me know if you found the links useful. Cheers!
Really looking forward to the 2.3 update, my current platformer is a bit clunky and I’d love to get the mechanics smoother. Any chance you could cover ladders in the future?
Hey Ian, I’m porting this engine to GameMaker Studio 2.3. Not much going on, just converting the scripts into functions. Pretty much everything else is applicable to GMS2.3 – you might give it a try. I will definitely cover ladders in the future as I’m planning to make a series about state machines and ladders are, indeed, just a separate player’ state (like water, air, ground…) in which you enable/disable certain physics features (e.g. no gravity). Hit me up via contact form/twitter if you need immediate help with this. Cheers 🙂
When will the new version of the tutorial be released?
I’m looking forward to some vacation time around mid August to sit down and get this done.
Alright thank you for replying!