Question

I am currently working on a nice little 2D game engine in AS3. You can even load in different flash movie clips through XML for the different animations. One of the features also allows you to flip an animation when you perform a certain action. That way you could have 1 animation for both left and right (as usual). I have the matrix transformation working correctly; however, I think my logic for flipping things back and forth is incorrect. The result is that the wrong animation will play at the wrong time. I decided to make the animation played based on the velocity of the moving object rather than on key press since I have physics elements involved.

Here is a link to the game in its current state: http://parrisstudios.com/Game_Design/gameEngineDemo/

The issue is mainly that animations play at incorrect times, or don't play when they should.

Here is my code for the flipping (let me know what you guys think): ps: the direction variable is the last direction the character is facing (left or right in this case, it is described later in the code)

private function drawJumpMode():void {
        var change:Boolean = false;
        //decide whether to swap graphics or continue playing

        if (Math.abs(particleGroup.particles[0].velocity.y) < epsilon && Math.abs(particleGroup.particles[0].velocity.x) < epsilon && direction == "right") {
            if (lastClipAction != "stillRight"){ 
                lastClipAction = "stillRight";
                change = true;
            }
        }
        else if (Math.abs(particleGroup.particles[0].velocity.y) < epsilon && Math.abs(particleGroup.particles[0].velocity.x) < epsilon && direction == "left") {
            if (lastClipAction != "stillLeft"){ 
                lastClipAction = "stillLeft";
                change = true;
            }
        }
        else if (particleGroup.particles[0].velocity.y > 0 && Math.abs(particleGroup.particles[0].velocity.x) < epsilon) {
            if (lastClipAction != "down"){ 
                lastClipAction = "down";
                change = true;
            }
        }
        else if (particleGroup.particles[0].velocity.y < 0 && Math.abs(particleGroup.particles[0].velocity.x) < epsilon) {
            if (lastClipAction != "up"){ 
                lastClipAction = "up";
                change = true;
            }
        }
        else if (particleGroup.particles[0].velocity.x > 0) {
            if (lastClipAction != "right") {
                lastClipAction = "right";
                direction = "right";
                change = true;              
            }
        }
        else if (particleGroup.particles[0].velocity.x < 0) {
            if (lastClipAction != "left"){ 
                lastClipAction = "left";
                direction = "left";
                change = true;
            }
        }

        //If the movie clip has changed, swap the old one back into the all clips library and get the new one.
        if (change) {
            //set flip to false whenever there is a change in movie clip
            flipped = false;
            //if the movie clip was flipped before, this should flip it
                            //back to normal
            flip();
                            //remove movie clip from the scene
            game.removeChild(playingMovieClip);
                            //check it back into the movie clip library
            allClips.addChild(playingMovieClip);
                            //add the movie clip into the scene
            playingMovieClip = MovieClip(allClips.getChildByName(actionToClip[lastClipAction + "Name"]));
            game.addChild(playingMovieClip);
        }

        //Flip if needed
        flip();

        //set it to true so that it won't be constantly flipped.
        flipped = true;

        //set movie clip to be center over the main particle
        playingMovieClip.x = particleGroup.particles[0].center.x;
        playingMovieClip.y = particleGroup.particles[0].center.y;
    }
private function flip():void {
        //If a transformation is required, then do so
        if (actionToClip[lastClipAction + "H"]=="1" && !flipped){
            flipHorizontal(playingMovieClip);
        }
        if (actionToClip[lastClipAction + "V"]=="1" && !flipped){
            flipVertical(playingMovieClip);
        }
    }
Was it helpful?

Solution

I believe the code in question is here.

            //If the movie clip has changed, swap the old one back into the all clips library and get the new one.
            if (change) {
                    //set flip to false whenever there is a change in movie clip
                    flipped = false;
                    //if the movie clip was flipped before, this should flip it
                        //back to normal
                    flip();
                        //remove movie clip from the scene
                    game.removeChild(playingMovieClip);
                        //check it back into the movie clip library
                    allClips.addChild(playingMovieClip);
                        //add the movie clip into the scene
                    playingMovieClip = MovieClip(allClips.getChildByName(actionToClip[lastClipAction + "Name"]));
                    game.addChild(playingMovieClip);
            }

            //Flip if needed
            flip();

The problem is that you are doing a double flip here. This works find if you are in fact changing clips from the change. For example if you go from running right to standing right. It goes wrong when you go from running right to running left. Since they are the same clip just flipped you end up doing two flips in this situation. This causes the moonwalk behaviour :-).

I would suggest cleaning up this logic and providing a way to reset the flipping. Instead of flipping back to the original orientation, reset back to it so you can guarantee the state of the clip.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top