GML Preventing an animation from looping to the start!

S

Snayff

Guest
Morning all,

When I jump I want to use the starting frames pre-jump, then the middle frames when in the air. I have added what I think should do that. However, when holding down the jump button, for the variable jump height, it flashes on to the first frame just before ending. When not holding down the jump this doesnt happen.

I have worked through the debugger but I havent managed to catch it moving back to the first frame. I have played with image speed and indexes but this is as close as I can get.

One thing to note, when I reduced the image speed to something tiny it also dramatically reduced the speed of movement - that shouldnt happen naturally, right?

Code:
///@description manage jump and fall sprites


//get jump direction
var _jumpSign = sign(currVelocity[YVELOCITY]); 
switch _jumpSign 

{ 
    case -1: // going up
        //change to jump sprite
        currAction = JUMP;
       
        //loop in air animation
        if (image_index > 7) { 
            image_index = 6; 
        } 
        break; 
   
    case 0: 
        currAction = JUMP
        break;

    case 1: //falling 
   
        //check if just moved from jump, else must be jumping
        if currState == scStatePlyAirborne && currAction == JUMP{
            image_index = 0;
        }
        //change to fall sprite
        currAction = FALL;
       
        //loop initial jump frames
        if (image_index >= 4) { 
            image_index = 2; 
        } 
    break; 
}

Code:
///@description handle player jumping

//---STATE NEW---
if newState == true {
    image_index = 0; //reset animation
    currVelocity[YVELOCITY] = 0; //remove current gravitational force
    scHandleJumpAndFallSprites();
   
    jumpTimer = 0; //reset jump timer
    stateVar[0] = 3; //castFrame
   
    scStateNewSetZero(); //reset new status
   
}

currVelocity[YVELOCITY] = 0; //remove current gravitational force

//---STATE BEHAVIOUR---

//check cast animation reached
if image_index = stateVar[0] {
    //apply jump input to velocity
    y = y - 1; // to force player off the ground to allow pass to airborne state
    currVelocity[YVELOCITY] -= jumpSpeed; 

    //timers
    currJumpCount ++; //increase count of jumps made
}
// confirm on ground and which forces to apply
scDetermineForces();

//apply forces
scApplyFriction();
//N.B. no gravity on initial jump frame

//apply movement
scMoveWithCollision(oMainController.tileMapIDCollision, currVelocity, "Stop");  //collision tiles


//---Sprite---
scHandleJumpAndFallSprites();
scUpdateSprite(); //update sprite

//---STATE SWITCH---
//only allow state switch (except hit) once cast frame reached
if image_index >= stateVar[0] {
    scStateChkSwHit();
    scStateChkSwAirborne();
    scStateChkSwMobility();
    scStateChkSwAttack();
   
}
scStateChkSwHit();

Code:
///@description handle player Airborne

//---STATE NEW---
if newState == true {
   
    scHandleJumpAndFallSprites();
    stateVar[0] = 0; //hang time timer
    stateVar[1] = 0.1; //hang time length
   
    scStateNewSetZero(); //reset new status

}


//---STATE BEHAVIOUR---


//---Velocity changes---

// confirm on ground and which forces to apply
scDetermineForces();

//apply left/right input to velocity
currVelocity[XVELOCITY] = clamp(currVelocity[XVELOCITY] + ((oMainController.inpRight - oMainController.inpLeft) * currAcceleration), -maxVelocity[XVELOCITY], maxVelocity[XVELOCITY]);

//if moved from jump and holding down jump
if (previousState == scStatePlyJump && oMainController.inpJumpHeld){ 
    //apply hang time
    if  (stateVar[0] > 0)
    {
        currVelocity[YVELOCITY] = 0;
        stateVar[0] -= (1 /room_speed) * global.timeMultiplier; //increment    
    }
    else 
    {
        // store old Y veloc
        var _oldYVelocity = currVelocity[YVELOCITY];
        scApplyGravity();
        if (sign(_oldYVelocity) == sign(currVelocity[YVELOCITY])*-1)
        {
            // if our sign just changed after applying gravity, that means that we have flipped from a negative 
            //to a positive y velocity, it means we just crossed the apex of our jump.
            stateVar[0] = stateVar[1] ; // set ahng time timer to hang time length
        }
    }
}else 
{

    scApplyGravity();
}


//apply forces
scApplyFriction();


//---Movement---

//apply movement
switch sign(currVelocity[YVELOCITY])
{
    case -1: // moving upwards, ignore oneWayTileMaps
   
    scMoveWithCollision(oMainController.tileMapIDCollision, currVelocity, "Stop");
   
    break;
   
    case 0: // moving downwards, collide oneWayTileMaps
    case 1:
   
    scMoveWithCollisionAirborne(oMainController.tileMapIDCollision,oMainController.tileMapIDOneWay,currVelocity);
   
    break;
   
}

//---Sprite---
scHandleJumpAndFallSprites();
scUpdateSprite(); //update sprite


//---STATE SWITCH---
scStateChkSwHit();
scStateChkSwIdle();
scStateChkSwRun();
scStateChkSwJump();
scStateChkSwMobility();
scStateChkSwAttack();
scStateChkSwHit();


Any help would be appreciated!

Snayff
 
F

float

Guest
Wouldn't it be easier to just have a keypress event that changes the sprite to a single image sprite then a key release to change to another sprite?
 
S

Snayff

Guest
That might work but it would involve redesigning how I handle all of the states, I think. Is it not possible to do what I am intending?
 
F

float

Guest
It is possible, I have even tried cramming together all of a character's animation in a single sprite, used state machines to determine where the limits are of my current animation are (i.e. jumping on frame 0-5, walking on 6-3 etc). But then again, it was a bit messy than assigning sprite_index=spr_walk, and image_speed accordingly...
 
S

Snayff

Guest
I have split them out but I could split them out further if it will make life easier. Either way, I would have thought that the code above would have worked as intended and I am unsure why it somehow loops.
 
S

Snayff

Guest
Any other suggestions on why this isnt working as expected?
 
S

Snayff

Guest
Thanks jonjons, i'll check it out and see what the code is doing that I am missing.
 
Top