• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker Help! Sprite Animation

C

CleanFF

Guest
So I am new with GMS and I am working on some player movement. I have used a premade sprite sheet for a place holder and have used multiple sprites for a walk animation. I did some tinkering around and I was able to get it working properly (ie when the user holds "A" the sprite moves left with a walking animation).

After doing this, I wanted the player object to move around with WASD and look towards the cursor, similar to a twin stick shooter. I was able to figure out how to get the sprite look in the direction of the cursor while moving, however I cannot get the sprite animations to work properly. As of right now, when the player object is not moving, the sprite is idle but looks in the direction of the cursor. When the player object moves, it looks as though that the sprite only goes to the first image in the sprite walk animation.

Can anyone assist me on how I can play the full sprite animation when moving?

Here is the code I've written in the Step Event:

direction = point_direction(x, y, mouse_x, mouse_y);

//Look towards mouse

var playerAngle;
playerAngle = point_direction(mouse_x,mouse_y,obj_player.x,obj_player.y);
var downAngle = (playerAngle > 45) and (playerAngle < 135);
var rightAngle = (playerAngle > 135) and (playerAngle < 225);
var upAngle = (playerAngle > 225) and (playerAngle < 315);
var leftAngle = (playerAngle > 315) or (playerAngle < 45);
look = (downAngle or rightAngle or upAngle or leftAngle)

var up = keyboard_check(ord("W"));
var down = keyboard_check(ord("S"));
var left = keyboard_check(ord("A"));
var right = keyboard_check(ord("D"));
move = (up or down or left or right)


if downAngle {
sprite_index = spr_playerDownIdle;
if move {
sprite_index = spr_playerDownWalk;
}
}

if rightAngle {
sprite_index = spr_playerRightIdle;
if move {
sprite_index = spr_playerRightWalk;
}

}
if upAngle {
sprite_index = spr_playerUPiIdle;
if move {
sprite_index = spr_playerUPWalk;
}


}
if leftAngle {
sprite_index = spr_playerLeftIdle;
if move {
sprite_index = spr_playerLeftWalk;
}

}

/// MOVEMENT

var up = keyboard_check(ord("W"));
var down = keyboard_check(ord("S"));
var left = keyboard_check(ord("A"));
var right = keyboard_check(ord("D"));

if up {
y += -1;
}

if down {
y += 1;
}

if left {
x += -1;
}

if right {
x += 1;
}

if move {
image_speed += 0;
image_index += 0;
}


I know the code may be messy or whatever, I have tinkered with it for hours to no avail. Please help!
 
J

Jordan Robinson

Guest
When you set the idle Sprite, try moving it into an else statement to make sure that the Sprite isn't set to idle every step. The problem is likely that it is setting the idle Sprite (which sets the image index to 0) every frame before setting the walk sprite.

Edit for clarity:
If move { set walk }
Else { set idle }
 
T

Taddio

Guest
Couple of things here. First, welcome!

In your player's StepEvent you have code like this:
Code:
point_direction(mouse_x,mouse_y,obj_player.x,obj_player.y);
This is wrong, as it is. Since you're calling this code from obj_player, you don't need the dot operator, just:
Code:
point_direction(mouse_x,mouse_y, x, y);
since the x and y already belong to the calling instances.
This was a small problem.

Your angle block, on the pther hand, not too solid as it is. Wont even work, in fact.
You can't do that:
Code:
var downAngle = (playerAngle > 45) and (playerAngle < 135);
The way to do that is have ONE variable named _angle, that's it. Then
Code:
if ((_angle >=45) || (_angle <135)) {
    //Do stuff upwards
} else
if ((_angle >=135) || (_angle <225)) {
    //Do stuff to the left
} else

///And so on
You will probably use the eame _angle variable for direction and image rotation as well, so don't use var, make it a instance variable (the blue ones).

Also try to put else between your if statements in the cases it's one or the other, it will prevent useless code to run (like checking for angles that we know we are not at).

The problem is likely that it is setting the idle Sprite (which sets the image index to 0
I don't think this is the case at all, unless they updated it. Changing sprite_index WONT refresh your image_index to 0, of that Im sure, I had enough animation problems in the past!!!

But you do have
if(move) image_index +=0;
Which is very suspicious
 
Last edited by a moderator:

Simon Gust

Member
Your angle block, on the other hand, not too solid as it is. Wont even work, in fact.
You can't do that:
Code:
var downAngle = (playerAngle > 45) and (playerAngle < 135);
The way to do that is have ONE variable named _angle, that's it. Then
Code:
if ((_angle >=45) || (_angle <135)) {
    //Do stuff upwards
} else
if ((_angle >=135) || (_angle <225)) {
    //Do stuff to the left
}
Are you sure about what you've written here? The Original looks fine to me and should totally work fine.

As of right now, when the player object is not moving, the sprite is idle but looks in the direction of the cursor. When the player object moves, it looks as though that the sprite only goes to the first image in the sprite walk animation.

Can anyone assist me on how I can play the full sprite animation when moving?
First look at this code:
Code:
if move {
    image_speed += 0;
    image_index += 0;
}
This won't do anything in favor of your animation.
What these originally are for is
image_speed being the automatic incrementation of image_index per frame
image_index being the current animation frame.

You only have to set image_speed to something along those lines
Code:
if (move) {
   image_speed = 0.50;
}
If your animation works, then we can talk about making code tidier and fail-secure.

EDIT:
set image_speed to 1 for now, I have no idea how image_speed works in GM:S 2. Just don't set it to 0.
 
C

CleanFF

Guest
Thanks for the help guys! I had the right idea, I just had to clean some things up. The if move, walk else, idle tip really helped!
 
T

Taddio

Guest
Are you sure about what you've written here? The Original looks fine to me and should totally work fine.
Unless downangle, upangle, rightangle and leftangle are booleans (which would probably be kind of be useless, but possible nonetheless), your ifs wont run if you do
if(downangle){//do stuff}
 

Simon Gust

Member
Unless downangle, upangle, rightangle and leftangle are booleans (which would probably be kind of be useless, but possible nonetheless), your ifs wont run if you do
if(downangle){//do stuff}
Doesn't matter if I save a statement to a variable beforehand.
Code:
if (angle > a && angle < b) {}
Is the same as
Code:
this = (angle > a && angle < b);
if (this) {}
Just that with the variable, it is more useful if you desire to lookup and use the player angles multiple times.
 
Top