• 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!

sprite issues

pixeltroid

Member
I've been working with a state system for my player.

And I want the player sprite to change to it's shooting animation (spr_heroshoot) when he enters the "shoot state" and then revert back to his normal state and sprite (spr_herostand)

I've got this code in the step event:

Code:
if (state == 'move' && health > 0) {
scr_player_move_state();
sprite_index = spr_herostand
image_speed = .2 
}

if state == 'playershoot'  {
scr_playershoot_state(); 
sprite_index = spr_heroshoot
image_speed = .2 
}
And when the shoot button is pressed, it calls scr_playershoot_state and the player shoots just fine. But the problem is that only the first frame of the shoot animation (spr_heroshoot) plays.

Why is this happening? and what should I do?
 
Last edited:

Felbar

Member
firstly i would have to see the scr_playershoot_state to see whats happening there
what is your transition out of playershoot ?
however you are setting the sprite_index to spr_heroshoot every frame which is unecessary

try something like this

GML:
if state == 'playershoot'  {

    //if we are not already on this animation
    if (sprite_index != spr_heroshoot) {
    
        //set it and reset  to start of animation
        sprite_index = spr_heroshoot;
        image_index = 0;
        image_speed = .2 ;
    }
    
    //run state script
    scr_playershoot_state();
}
 

curato

Member
usually what I do is set the state and the sprite and make the last frame the shoot frame then I use the animation end event to check if it is shooting then take the shot and reset the state and stuff there. Most likely what is happening is you are producing the projectile and resetting the state before the animation is done.
 

pixeltroid

Member
firstly i would have to see the scr_playershoot_state to see whats happening there
what is your transition out of playershoot ?
however you are setting the sprite_index to spr_heroshoot every frame which is unecessary

try something like this

GML:
if state == 'playershoot'  {

    //if we are not already on this animation
    if (sprite_index != spr_heroshoot) {
   
        //set it and reset  to start of animation
        sprite_index = spr_heroshoot;
        image_index = 0;
        image_speed = .2 ;
    }
   
    //run state script
    scr_playershoot_state();
}
scr_playershoot_state only handles the creation of the bullet, its direction and its speed. I'll try your code out now and get back if it works or doesnt work. Thanks!
 

Felbar

Member
You are probably just coming out of the shoot state too soon
if you transition to move (or any other) state is in the scr_playershoot_state than its only
going to run for one frame

for animations that need to play once thru like, shoot or attack
you should transition out in the animation end event

GML:
//Animation End event

//if shooting animation has ended
if(state == 'playershoot') {

    state = 'playeridle' // or w/e
}
 

pixeltroid

Member
You are probably just coming out of the shoot state too soon
That's the part that's confusing me. I can't seem to find what's causing the player to come out of the shoot state.

The player only has 2 states currently: 'move' and 'playershoot'. The player's default state is initialized in the create event as:
state = 'move'

and the step event defines the script that pertains to 'move'.

Code:
if (state == 'move' && health > 0) {
scr_player_move_state();
sprite_index = spr_herostand
image_speed = .2 
}
^ scr_player_move_state() covers movement, jumping and collisions with solid objects, that's it.

I switch to the 'playershoot' state only upon pressing the button O.

Code:
if (state == 'move'  && global.laser > 0 && health > 0 && !alarm[2] > 0){
{
state = 'playershoot';
}
canshoot = false
alarm[2]=7
}
^ the 'playershoot' script (below) only covers the creation of the bullet and it's speed and direction.

Code:
if (image_xscale > 0) { 
pl=instance_create(x+16,y-2,obj_bullet);
pl.direction = 0;
pl.speed = 8;
pl.image_angle = pl.direction
} else if (image_xscale < 0){
pl=instance_create(x-16,y-2,obj_bullet)
pl.direction = 180;    
pl.speed = 8;
pl.image_angle = pl.direction
}
pl.speed = 8;
I'm wondering what exactly is causing the player to go back to his default state after playing only 1 frame. Or mayh


I tried your codes, but it still only plays one frame of the animaton.
 

Felbar

Member
hmm, well i would take a look at your project if you want to link it , but i can say !alarm[2] > 0
doesn't make much sense are you trying to say "if alarm[2] is not greater than 0" ?
i might try alarm[2] == 0 or wrap it like !(alarm[2]>0) , i think you might be 'notting' the value in alarm[2] before the compare
 

TheouAegis

Member
Set your sprites when you change statez, not every step of the state. I don't understand why this is always so difficult for people to grasp. When you go into your shoot_a_protester state, do you raise your gun? NO! Your gun is already raised by the time you are in shoot_a_protester state! When you are in your walking state, do you change to your walking action? NO! You are already in your walking action by the time you enter your walking state, otherwise you would be moving like Magneto, and we call that floating!

You don't need the >0 after !alarm[2], but that part is probably fine if alarm[2] is a cooldown.
 

HayManMarc

Member
Before going back to the move state, use a check to see if the shooting is finished.

If shoot-animation-sprite = sprite_number -1 (the last frame of the sprite), then state = move state. (Or whatever it is that finishes the shoot, if its not the animation.)
 

pixeltroid

Member
Okay, I kind of figured out why only the first frame of the shooting sprite was playing. It must have been because of this line in the step event:

if (state == 'move' && health > 0) {
scr_player_move_state();
}


It kept reverting the sprite back to the 'move' state and its default sprite. Or so I think

So I added a condition saying that if it goes into the 'move' state only if the shoot button is not pressed.

Code:
if (state  == 'move' && !keyboard_check(ord("O"))) { 
//if (state  == 'move') {
scr_player_move_state();     //default stance of player that lets him move, jump
} 

if (state  == 'playershoot'){
scr_playershoot_state(); //controls bullet speed, direction and speed
}
This seems to allow the full shoot animation to play BUT the !keyboard_check(ord("O"))) check is messing with the players movement. Earlier, I could run and shoot bullets at the same time. Now when I try to do that the player pauses for a bit (switching to "playershoot" state).

I know my code is a mess but is there a fix for this?
 

Nidoking

Member
Yes. Whatever was in your scr_player_move_state that caused the problem, fix that. You should be calling those scripts every step and have the scripts handle the logic. Also, learn to use "else". Surely you don't want to run the shoot state script if you switch to shooting mid-step.
 

TheouAegis

Member
Okay, let's say most of your states allow movement but only a couple don't. You would have your movement script running separate from all the states in the step event. You would check if the state is not one of the states that don't allow movement before running your movement script.

On the other hand, let's say only a couple of your states allow movement and most of your states don't. You would therefor run the movement script from within the states that allow it, not in the step event.
 
Top