8 Directional Movement: Sprites | GMS2 [2]
Вставка
- Опубліковано 8 лют 2025
- We continue on from our previous tutorial and hook up our sprites to our movement system.
Sprites download:
1drv.ms/f/s!Am...
Sprites credit:
Adapted from TheNess "RPG sprite - 8 direction human male 16x16": opengameart.or...
Here I am in other places:
FriendlyCosmonautDev channel: / @friendlycosmonautdev8040
Twitter: / friendly_cosmo
Patreon: / friendlycosmonaut
I'm going to be a bit busy in January, but did plan to do another follow-up to this, showing how to use a single sprite sheet (similar to the system used in the Farming RPG). This will be a full video with explanations when I have the time, but for those interested now, here is the code for it:
pastebin.com/RRUP4Yzv
And Happy Holidays, everyone!
It's March now please upload a video.... you're my only support in my game development...
PLEASE... 😟
This question has just been floating around in my head for a long time now. You know so much about GML, what is your story with GML? How did you learn how to code with it? Because after such a long time looking, you are still the only reliable source and teacher for learning this stuff.
@Douglas Kian bruh this is a year old comment...
@@bunjoe09 2 years ;)
@@simaogoncalves07 Even better.
There's not much stuff to learn, GML is just your basic programming language like GDScript
4 Years
For anyone watching this 5+ years later:
To get your Idle sprites working, I used "sprite_index" in my second switch statement instead of "dir" and it works just fine. Here's an example:
(Please note: I used "image_xscale" to swap sprite directions)
//Idle Animation
switch(sprite_index)
{
case(spr_player_walk_down): sprite_index = spr_player_idle_down; break;
case(spr_player_walk_side): sprite_index = spr_player_idle_side; break;
case(spr_player_walk_side):
{
if (image_xscale = -1) //This check if the player is facing the other direction (180 degrees)
{
sprite_index = spr_player_idle_down;
image_xscale = -1;
}
break;
}
case(spr_player_walk_up): sprite_index = spr_player_idle_up; break;
}
I'm watching this 5 years later, and you helped me 3 weeks after writing that out so thank you.
@@DaniRevOfficial of course!
You are such a life saver!!
Omg thanks... But I still have an issue : it is working for me, but randomly, and much better below 20 FPS... At 60 FPS, when my player stops, it automaticaly turns in the nearest direction between one of thoses directions : 0, 90, 180, 270. So I can never see my spr_player_idle_up_right etc... :/ Does somebody know why ?
thank you so, SO MUCH! I learned more from this than the other 500 videos I watched on GMS2.
Your tutorials are awesome, you explain each step with visual examples!! Thank you!!
Spent all day tryingto figure this out, finaly found your video, ist perfect, thank you.
I have been struggling with this all weekend with no answers. I'm more of a visual learner, you are a life saver ;-;
Will you do a collision tutorial for this type of movement?
I have already made a type of collision but it is not quite good, since sometimes you get stuck in the corners of the walls, I would like to know if you have planned to do it. You do very good tutorials by the way :P thanks for sharing your work with all of us!
It's a little late, but you can try this:
Remove the "x += moveX" and "x += moveY" from the code and put this on its place:
// Colision for X axis
if(!place_meeting(x+spd, y, obj_Collision) && hInput == 1){
x += moveX;
}
if(!place_meeting(x-spd, y, obj_Collision) && hInput == -1){
x += moveX;
}
// Colision for Y axis
if(!place_meeting(x, y+spd, obj_Collision) && vInput == 1){
y += moveY;
}
if(!place_meeting(x, y-spd, obj_Collision) && vInput == -1){
y += moveY;
}
If you need to check more than one collision object, create a single object to check for collision and then parent it to all the other collision objects you want to have.
Thanks for the tutorial! I really like your video, keep it up!
Tight tutorial. Well edited/voiced. Thanks a lot!
Every video I watch of yours... So good O.o
A collision tutorial for this video would be AMAZING.
It's a little late, but you can try this:
Remove the "x += moveX" and "x += moveY" from the code and put this on its place:
// Colision for X axis
if(!place_meeting(x+spd, y, obj_Collision) && hInput == 1){
x += moveX;
}
if(!place_meeting(x-spd, y, obj_Collision) && hInput == -1){
x += moveX;
}
// Colision for Y axis
if(!place_meeting(x, y+spd, obj_Collision) && vInput == 1){
y += moveY;
}
if(!place_meeting(x, y-spd, obj_Collision) && vInput == -1){
y += moveY;
}
If you need to check more than one collision object, create a single object to check for collision and then parent it to all the other collision objects you want to have. It also works for corners if you're in a pinch, but the character won't slide on it.
Tysm, FriendlyCosmonaut
Great video thank you! Can we get a video with collisions and this type of movement?
Im SOOO confused with the idle sprite part its not working when i put the same switch thing but then make it "idle" instead of right
using the point_direction was very cool!
Creat teaching! Really helps! Thank you!
WOW so much awesome this helped me a lot
Aaaaand I'm subscribed.
Thanks, if i ever able to publish my game i mention you in my credits,your coding is easy,so i can do coding and im just 11 years old
yes, brilliant!
Does anyone know why my sprite stopped it's idle animation when it's not moving? And could anyone help me fix it?
I have the same issue...
What exactly do you mean (3:46) by "Note: if you have idle sprites , you would put another switch statement here instead, in the same format as before!" . I'm struggling to get the idle animation working with your tutorial.
if (hinput == 0) and (yinput == 0){
sprite_index = Idle;
}
else
{
THE SWITCH STATEMENT;
}
@@JohanKarlemo thank you
@@JohanKarlemo I'm having the same problem. This doesn't work for me. My character continues plays his run animation or spins in circles playing the idle animation depending on how I do it. Why does she add the idle code after the switch statement and you do it before? Would you mind explaining further?
@@anthonypismarov Have you set image_speed to 0 when you change into the idlesprite?
I have idle animations for all 8 directions and this doesnt work for me. i tried all sort of combinations to get it to idle... none are working. Would it be better to have each instance of movement have the walk sprite activate, like
if (keyboardcheck_pressed(vk_right)) {Sprite_Index = player_walk_r}
if (keyboardcheck_released(vk_right)) {Sprite_Index = player_idle_r}
??
thanks your are genius
I'm having difficulties with the code. I am trying to use some sprites I made for when you are idle, but the game won't run. How exactly would it look to make it with other idle sprites? (Just so I can fix my problem)
Would love to know an answer to this too
3:47
@@runabyt3 3:47
my left dir didn't work, it would take whatever sprite I was just on like if I was going right and would just in essence moonwalk and I can't fix it
Same happened to me. Any idea how to fix it?
@@TheGrunto Works here. Re-check your code.
Add to the switch statement 'switch round(dir){.......'
The 180 direction is 180.00 for some reason. Adding the 'round(dir)' allows it to round to 180.
@@stu5632 Thanks this did the trick! I had a janky keyboard_check right before to patch the problem, but that seemed like poor code.
is there a way to make the direction follows the mouse coordinates?
I love the results from this code but desperately needs a collision counter part.
My character in case 180, wont move to the left using the spr_l, insted it will move to the left with the spr_r. Any help?
great video.
Hot tip and nicely explained. Now how do I assign a different idle animation to every direction once my character is stationary?
@tape stuff
I'm just a beginner but here's how I've done it. In the else statement of if hInput != 0 || vInput != 0 I've put sitch statement that's looking for sprite_index. So based on her video, the example code would look like this:
switch (sprite_index) {
case spr_r:
sprite_index = spr_idle_r;
break;
case spr_ur:
sprite_index = spr_ur_idle;
break;
(...) And so on :)
@@MierzejX I tried that but for some reason it's not working for me... Can you help me out?
Here's what I did... it's working so far. No idea if this method will have issues down the line. It seems to work though.
//Set Sprite
switch round(dir)
{
case 0: sprite_index = spr_player_right; break;
case 45: sprite_index = spr_player_right_up; break;
case 90: sprite_index = spr_player_up; break;
case 135: sprite_index = spr_player_left_up; break;
case 180: sprite_index = spr_player_left; break
case 225: sprite_index = spr_player_left_down; break;
case 270: sprite_index = spr_player_down; break;
case 315: sprite_index = spr_player_right_down; break;
}
}
//Idle Sprites
if(hInput = 0 and vInput = 0)
{
switch round(sprite_index)
{
case spr_player_right: sprite_index = spr_player_idle; break;
case spr_player_right_up: sprite_index = spr_player_idle; break;
case spr_player_up: sprite_index = spr_player_idle; break;
case spr_player_left_up: sprite_index = spr_player_idle_left; break;
case spr_player_left: sprite_index = spr_player_idle_left; break
case spr_player_left_down: sprite_index = spr_player_idle; break;
case spr_player_down: sprite_index = spr_player_idle; break;
case spr_player_right_down: sprite_index = spr_player_idle; break;
}
}
@@DylpickleA I was wondering about the same thing. Works for me, thank you!!!
Cousmonaut Lady is back wahoo
Could you add mouse click and movement? Then add shooting with right mouse button?
It’s possible yeah!
Hey guys I need some help so I followed along and I have everything down verbatim but my sprites are coming up as blue instead of red like hers during the switch(dir) function and I was wondering what am I doing wrong ? It says error ( not set before reading it) I’m new to GML so idk what this means.
you are seriously a fucking legend, thank you
Using this code for four directional movement but for some reason if I'm moving diagonally and switch to the opposite diagonal direction the sprite wont change and it looks like the player object is moonwalking. Any idea why this might be happening?
post your code so we can see what is happening
im having the same issue did you ever fix it
One thing I’m curious about is your switch statement. It reads to me the cases only hit if the direction is exactly at those degree values. Wouldn’t that mean it only changes sprites if you hit those exact values? I’m sure I’m missing something though.
I guess it will change sprites with those exacts values, but in that case the previous code just makes it possible to have those values. If you got a system that makes it possible, like mouse controled direction, i guess you can arrange this code with "0 degrees < dir value < 45 degrees" kind of stuff
I use unity, I know how to program, I'm just here because the sprites looked nice even though I don't like pixelart at all but really good and nice video.... and oh my gosh, gml looks so damn easy cO and I thought c# is easy...
Thank you😭
how can i do this with the mouse in game maker 1.4? I'm looking to make a top down shooter so that the player looks in 8 directions according to the position of the mouse
I used WASD instead using this code:
hInput = (keyboard_check(ord("D"))) - (keyboard_check(ord("A")));
vInput = (keyboard_check(ord("S"))) - (keyboard_check(ord("W")));
SPRINTING:
I then added an extra variable called
toSprint = (keyboard_check(vk_shift));
Then inside the Movement If statement I added an If/Else statement to check if the Shift key is being pressed and changed the spd and image_speed to a larger number, or setting it back to lower values if not being pressed.
if (toSprint) {
spd = 1.4;
image_speed = 0.50;
} else {
spd = 0.75;
image_speed = 0.25;
}
COMPLETE CODE for copypasta:
hInput = (keyboard_check(ord("D"))) - (keyboard_check(ord("A")));
vInput = (keyboard_check(ord("S"))) - (keyboard_check(ord("W")));
toSprint = (keyboard_check(vk_shift));
if (hInput != 0) || (vInput != 0) {
dir = point_direction(0, 0, hInput, vInput);
moveX = lengthdir_x(spd, dir);
moveY = lengthdir_y(spd, dir);
x += moveX;
y += moveY;
//Sprinting
if (toSprint) {
spd = 1.4;
image_speed = 0.50;
} else {
spd = 0.75;
image_speed = 0.25;
}
//Set Sprite
switch(dir) {
case 0: sprite_index = spr_r; break;
case 45: sprite_index = spr_ur; break;
case 90: sprite_index = spr_u; break;
case 135: sprite_index = spr_ul; break;
case 180: sprite_index = spr_l; break;
case 225: sprite_index = spr_dl; break;
case 270: sprite_index = spr_d; break;
case 315: sprite_index = spr_dr; break;
}
} else {
image_index = 0;
}
thanks for this!
@@jakeq3530 not sure if you will reply after this long but how would I add in my idle animations? I was trying to add them in like it says in the video but it keeps giving me errors.
Hi! First of all thanks a lot for your amazing job, you're great!
Second: I was trying to implement this code in the same code we used for the farming RPG tutorial, but I the collisions just don't work, how can I fix it?
how do I shoot in the direction I'm facing (without a mouse)
How do we add collisions with a wall object with this code? every tutorial I see adds movement and uses different variables and makes it a bit confusing with this coding.
@@KennedySilva06 He has a good question because her code for the collisions in her RPG video doesn't work with this code.
Kennedy is right, the code will looks something like this. Although this probably doesnt work since i havent test it. but i hope you get the gist out of it.
if ! place_meeting(moveX,moveY,YourSolidObjectName) {
x += moveX;
y += moveY;
}
Yeah I have something like this, but the player gets stuck in corners and I'm not sure why 😐🤔
Thanks for all the comments! I think I kinda got it, but now my enemies collide with walls just fine, but when they collide with each other, they get stuck and it looks stupid lol
@@raymond4445 it could be your player's hitbox getting moved between sprites, make sure your hitbox is consistent throughout all your 8 directional srites
Why use this dir variable with point_direction instead of the built-in direction variable?
I'm having trouble getting these scripts to work with a following object, and that might be part of my problem.
Hey. It happened so that I'm now reading manual and... Well, probably that's why: "Direction is one of those properties and can be used to set the direction of movement of the instance when the instance has a speed other than 0." And we don't use speed here, but instead, manipulate x and y directly.
And I suppose we do this because it's more
accurate, thus more reliable way to get what we want here.
Since you wrote this comment 2 months ago, I assume, you most likely already figured out, what's wrong.
How to set up 8 directional AI? I ain't sure what coding its on? even though I am still gml
Great tutorial! Can this system work with a top down zelda type game? And if so, what's the logic you would use to code the attack animations? I'm having a little trouble with that part.
😮
Is there a way to make it WASD instead of the arrow keys
yes, just replace (vk_right/left/up/down)
hInput = (keyboard_check(ord("D"))) - (keyboard_check(ord("A")));
vInput = (keyboard_check(ord("S"))) - (keyboard_check(ord("W")));
you are like Jesus basically
Hi my name is Cyril! I am your subscriber from Ukraine on UA-cam channel.
I am writing you with help. When writing a game Rpg ran into a problem.
My hero has a lot of weapons,
I don’t know how to transfer the damage value of a weapon to a character
(when he picks it up at the click of a button)
I’ve already done pressing a button and a weapon appears in my hand.
Have you encountered such a code or do you know any source that could help me ????
I translated this text using google, do not laugh)))))))
ım sliding help