AS3 - (?)摩擦导致影片剪辑跳跃,暂时改变路径(包括播放SWF)摩擦、路径、影片剪辑、SWF

2023-09-08 13:58:39 作者:我为你倾心

林做一个游戏在FlashBuilder,玩家控制一个影片剪辑(_character)与周围的箭头或WASD阶段。在舞台上有方形/周围的碰撞检测箱和一个50像素的边框。

Im making a game in FlashBuilder where the player controls a movieclip (_character) around the stage with the arrows or WASD. On the stage there are squares/boxes with collision detection and a 50 pixel border around.

在测试香港专业教育学院注意到,如果我按住方向键,然后切换到另一个和影片剪辑行驶过去,在箱子的缝隙,的影片剪辑会跳几像素在previous pressed方向,然后再次回落快。

While testing Ive noticed that if I hold a direction key, then switch to another AND the MovieClip is travelling past a gap in the boxes, the movieclip will jump a few pixels in the previous pressed direction, then back down again quickly.

这是一个瞬间的闪烁,但创建一个分散注意力的跳动,口吃的效果。出现这种情况有多个键presses,但如果我preSS按钮,释放它,然后preSS另一个方向按钮。

It’s a split second flicker but creates a distracting jumpy, stutter effect. This happens with multiple key presses, but not if I press a button, release it, then press the other direction button.

黄色十字架下面的图片显示了一些地方发生这种情况。

The yellow crosses on the image below show some of the areas where this happens.

在我的code较大的摩擦数量,更引人注目的是。但是,如果我降低摩擦过多(0.8ish)影片剪辑动作太慢,在舞台和游戏无法播放。

The larger the Friction number in my code, the more noticeable it is. But if I lower the friction too much (0.8ish) The Movie Clip moves too slowly around the stage and the game is unplayable.

我目前有0.88摩擦而减轻了跳,但它仍然是明显的。 有谁知道为什么发生这种情况和/或我怎么能阻止它?(同时保持课程的影片剪辑的流体运动。)

I currently have the friction at 0.88 which lessens the jump, but it is still noticeable. Does anyone know why this is happening and/or how I could stop it? (while keeping the fluid movement of the movieclip of course.)

这个SWF显示摩擦在0.94这样的效果非常显着,尤其是在右上角。 (移动字符周围箭头或WASD阶段。)

This SWF shows friction at 0.94 so the effect is very noticeable, especially in the top right corner. (Move character around stage with arrows or WASD.)

0.94摩擦SWF

该SWF的摩擦0.88,不太明显,但它仍然发生!

This SWF has friction at 0.88, less noticeable, but it still happens!

0.88摩擦SWF

如果我要上到下或从左到右,行驶过去的差距这个问题不会发生。它只发生在两个对角相连方向按钮pssed $ P $,旅行过去的差距。

This problem doesn’t happen if I’m going UP to DOWN or LEFT to RIGHT, traveling past gaps. It only happens when two diagonal linked direction buttons are pressed, traveling past a gap.

如果我游UP然后离开了影片剪辑会向上跳起。如果我出差了,然后离开去跨越间隙的影片剪辑会跳几个像素向下,游戏中的人物正蹲在(?)

If I travel UP then LEFT the MovieClip will jump upwards. If I travel DOWN, then LEFT and go across a gap the movieclip will jump a few pixels downwards, like the character is squatting(?)

目前的code

新秀比赛 /应用类被用作水平转换器把LEVELONE搬上舞台。

Rookies game/Application class is used as a level switcher to put levelOne onto the stage.

package
{
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    [SWF(width="650", height="450", backgroundColor="#FFFFFF", frameRate="60")]

    public class RookiesGame extends Sprite
    {
        private var _levelOne:LevelOne;
        //public static var gameMute:Boolean = false;

        public function RookiesGame()
        {
            _levelOne = new LevelOne(stage);

            stage.addChild(_levelOne);
            stage.addEventListener("levelOneComplete",levelTwoSwitchHandler);
        }
        private function levelTwoSwitchHandler(event:Event):void
        {
        }
    }
}

第一级包含了大部分的code的工作,多数。

Level One contains most of the code, and majority of the work.

package
{
    //import statements

    public class LevelOne extends Sprite
    {
        //Declare the variables to hold the game objects
        private var _character:Character = new Character();
        private var _background:Background = new Background();

        private var _box1:Box = new Box();
        //Other box vars        

        //A variable to store the reference to the stage from the application class
        private var _stage:Object;
        //Control System
        private var _bUp:Boolean = false;
        private var _bDown:Boolean = false;
        private var _bLeft:Boolean = false;
        private var _bRight:Boolean = false;

        public function LevelOne(stage:Object)
        {
            _stage = stage; 
            this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }
        private function addedToStageHandler(event:Event):void
        {
            startGame();
            this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }
        private function startGame():void
        {
            addGameObjectToLevel(_background, 0, 0);
            addGameObjectToLevel(_box1, 300, 200);
            //Other boxes added to Level

            //Add character 
            this.addChild(_character);
            _character.x = 300;
            _character.y = 50;
            _character.gotoAndStop(1);

            playGame(); 
        }
        private function playGame():void
        {   //EVENT LISTENERS////////////////////////
            _stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            _stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); 
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        private function enterFrameHandler(event:Event):void
        {   
            _character.accelerationX = 0;
            _character.accelerationY = 0;
            _character.friction = 0.94;

            var _updown:Boolean=Boolean(!(_bUp==_bDown)); 
            var _leftright:Boolean=Boolean(!(_bLeft==_bRight));

            if (!_updown && !_leftright) 
            {   // not moving anywhere
                _character.gotoAndStop(1);
                _character.accelerationX = 0;
                _character.accelerationY = 0; 
                _character.friction = 0.94;

                _character.vy=0;
                _character.vx=0; 
            }
            else
            {
                if (_bUp) 
                {
                    _character.accelerationY = -0.5;
                    _character.gotoAndStop(2);
                } 
                else if (_bDown)
                {
                    _character.accelerationY = 0.5;
                    _character.gotoAndStop(3);
                } 
                if (_bLeft)
                {
                    _character.accelerationX = -0.5;
                    _character.gotoAndStop(4);
                } 
                else if (_bRight)
                {
                    _character.accelerationX = 0.5;
                    _character.gotoAndStop(5);
                }                           
            }
            //Apply friction
            _character.vx *= _character.friction; 
            _character.vy *= _character.friction;
            //Apply acceleration 
            _character.vx += _character.accelerationX; 
            _character.vy += _character.accelerationY;
            //Limit the speed
            if (_character.vx > _character.speedLimit)
            {
                _character.vx = _character.speedLimit;
            }
            if (_character.vx < -_character.speedLimit)
            {
                _character.vx = -_character.speedLimit;
            }
            if (_character.vy > _character.speedLimit)
            {
                _character.vy = _character.speedLimit;
            } 
            if (_character.vy < -_character.speedLimit)
            {
                _character.vy = -_character.speedLimit;
            }
            //Force the velocity to zero after it falls below 0.1
            if (Math.abs(_character.vx) < 0.1)
            {
                _character.vx = 0;
            }
            if (Math.abs(_character.vy) < 0.1)
            {
                _character.vy = 0;
            }
            //Move the character 
            _character.x += _character.vx;
            _character.y += _character.vy;
            checkStageBoundaries(_character);

            //Box Collisions
            Collision.block(_character,_box1);
            //All other box collisions              

        }
        private function checkStageBoundaries(gameObject:MovieClip):void
        {
            if (gameObject.x < 50)
            {
                gameObject.x = 50;
            }
            if (gameObject.y < 50)
            {
                gameObject.y = 50;
            }
            if (gameObject.x + gameObject.width > _stage.stageWidth - 50)
            {
                gameObject.x = _stage.stageWidth - gameObject.width - 50;
            }
            if (gameObject.y + gameObject.height > _stage.stageHeight - 50)
            {
                gameObject.y = _stage.stageHeight - gameObject.height - 50;
            }
        }

        public function replay():void
        {
            _stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            _stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler); 
            this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
            startGame();
        }
        private function keyDownHandler(event:KeyboardEvent):void
        {
            if (event.keyCode == Keyboard.LEFT || event.keyCode == 65 )
            {
                _bLeft=true;                
            }
            else if (event.keyCode == Keyboard.RIGHT || event.keyCode == 68)
            {
                _bRight=true;               
            }
            else if (event.keyCode == Keyboard.UP || event.keyCode == 87 )
            {
                _bUp=true;              
            }
            else if (event.keyCode == Keyboard.DOWN || event.keyCode == 83)
            {
                _bDown=true;                
            }   
            if (event.keyCode == Keyboard.ENTER)
            {
                replay();
            }
        }
        private function keyUpHandler(event:KeyboardEvent):void
        {
            if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT 
                || event.keyCode == 65 || event.keyCode == 68)
            {
                _bLeft=false;
                _bRight=false;
            } 
            else if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.UP 
                || event.keyCode == 87 || event.keyCode == 83 )
            {
                _bUp=false;
                _bDown=false;
            }
        }
        private function addGameObjectToLevel(gameObject:Sprite, xPos:int, yPos:int):void
        {
            this.addChild(gameObject);
            gameObject.x = xPos;
            gameObject.y = yPos;
        }   
    }
}

_character是在字符类的实例。

该SWF有五个关键帧,每一个动画里面,起到当四个方向按钮是pressed,再加上没事的时候是被pressed红色静止动画。

The SWF has five key frames, each with an animation inside, which plays when the four direction buttons are pressed, plus the red stationary animation when nothing is being pressed.

package
{
    import flash.display.MovieClip;
    import flash.display.DisplayObject

        [Embed(source="../swfs/characterResource.swf", symbol="Character")]
        public class Character extends MovieClip
        {
            //Public properties
            public var vx:Number = 0;
            public var vy:Number = 0;
            public var accelerationX:Number = 0; 
            public var accelerationY:Number = 0; 
            public var speedLimit:Number = 4; 
            public var friction:Number = 0.94;

            public function Character()
            {
            }
        }   
}

在箱和背景类是一样的,他们只是嵌入PNG,并添加精灵。请注意,网格背景是单一的形象。本场比赛是不是基于瓷砖。

The Box and Background classes are the same, they just embed the png and add the sprites. Note that the grid background is a single image. The game is not tile based..

最后的冲突类。当_character一个盒子碰撞时,它会调用Collision.block功能。

And finally the Collision Class. When _character collides with a box, it calls the Collision.block function.

package 
{
    import flash.display.Sprite;

    public class Collision
    {
        static public var collisionSide:String = ""; 

        public function Collision()
        {
        }
        static public function block(r1:Sprite, r2:Sprite):void
        {
            //Calculate the distance vector
            var vx:Number 
                = (r1.x + (r1.width / 2)) 
                - (r2.x + (r2.width / 2));

            var vy:Number 
                = (r1.y + (r1.height / 2)) 
                - (r2.y + (r2.height / 2));

            //Check whether vx 
            //is less than the combined half widths
            if(Math.abs(vx) < r1.width / 2 + r2.width / 2)
            {
                //A collision might be occurring! Check 
                //whether vy is less than the combined half heights
                if(Math.abs(vy) < r1.height / 2 + r2.height / 2)
                {
                    //A collision has ocurred! This is good!

                    //Find out the size of the overlap on both the X and Y axes
                    var overlap_X:Number 
                    = r1.width / 2 
                        + r2.width / 2 
                        - Math.abs(vx);

                    var overlap_Y:Number 
                    = r1.height / 2 
                        + r2.height / 2 
                        - Math.abs(vy);

                    //The collision has occurred on the axis with the
                    //*smallest* amount of overlap. Let's figure out which
                    //axis that is

                    if(overlap_X >=  overlap_Y)
                    {
                        //The collision is happening on the X axis
                        //But on which side? _v0's vy can tell us 
                        if(vy > 0)
                        {
                            collisionSide = "Top";

                            //Move the rectangle out of the collision
                            r1.y = r1.y + overlap_Y;
                        }
                        else
                        {
                            collisionSide = "Bottom";

                            //Move the rectangle out of the collision
                            r1.y = r1.y - overlap_Y;
                        }
                    }
                    else
                    {
                        //The collision is happening on the Y axis
                        //But on which side? _v0's vx can tell us 
                        if(vx > 0)
                        {
                            collisionSide = "Left";

                            //Move the rectangle out of the collision
                            r1.x = r1.x + overlap_X;
                        }
                        else
                        {
                            collisionSide = "Right"; 

                            //Move the rectangle out of the collision
                            r1.x = r1.x - overlap_X;
                        }
                    }
                }
                else
                {
                    //No collision
                    collisionSide = "No collision";
                }
            }
            else
            {
                //No collision
                collisionSide = "No collision";
            }
        }
    }
}  

任何帮助将是非常美联社preciated。我是个初学者所以它总是可能的,问题是一些简单的我已经错过了。

Any help would be much appreciated. I'm a beginner so its always possible the problem is something simple I've missed.

林还问了有关动画的不必要的上下摆动的问题。如果任何这些信息可以帮助你,或者你足够聪明,知道解决,太多的问题是,HERE

Im also asking a question about the unwanted bobbing of the animations. If any of that info helps you, or you're smart enough to know the solution to that too, the question is HERE

推荐答案

你试过吗?

    if (event.keyCode == Keyboard.LEFT || event.keyCode == 65 )
                {
                    _bLeft=true; 

                    _bRight=false;       
                    _bUp=false;      
                    _bDown=false;    
                }
                else if (event.keyCode == Keyboard.RIGHT || event.keyCode == 68)
                {
                    _bRight=true;

                    _bLeft=false;  
                    _bUp=false;      
                    _bDown=false;               
                }
                else if (event.keyCode == Keyboard.UP || event.keyCode == 87 )
                {
                    _bUp=true; 

                    _bRight=false; 
                    _bLeft=false;    
                    _bDown=false;     
                }
                else if (event.keyCode == Keyboard.DOWN || event.keyCode == 83)
                {
                    _bDown=true;    

                    _bRight=false; 
                    _bLeft=false;    
                    _bUp=false;            
                }