0

プレーヤーが矢印または WASD を使用してステージの周りでムービークリップ (_character) を制御する FlashBuilder でゲームを作成しています。ステージには、衝突検出と周囲に 50 ピクセルの境界線がある正方形/ボックスがあります。

テスト中に、方向キーを押したまま別のキーに切り替え、ムービークリップがボックスのギャップを通過すると、ムービークリップが前に押した方向に数ピクセルジャンプしてから、すぐに元に戻ることに気付きました。

これは一瞬のちらつきですが、気が散るようなびくびくしたスタッター効果を生み出します。これは複数のキーを押すと発生しますが、ボタンを押して放し、反対方向のボタンを押しても発生しません。

下の画像の黄色の十字は、これが発生する領域の一部を示しています。

ここに画像の説明を入力 私のコードの摩擦値が大きいほど、それが顕著になります。しかし、摩擦を下げすぎると (0.8ish)、ムービー クリップがステージ上でゆっくりと動き、ゲームがプレイできなくなります。

現在、摩擦を 0.88 に設定してジャンプを軽減していますが、それでもまだ目立ちます。なぜこれが起こっているのか、そして/またはそれを止める方法を誰かが知っていますか? (もちろん、ムービークリップの滑らかな動きを保ちながら。)

この SWF は 0.94 で摩擦を示しているため、特に右上隅で効果が非常に顕著です。(矢印またはWASDでキャラクターをステージ上で動かします。)

0.94 フリクション SWF

この SWF には 0.88 の摩擦があり、それほど目立ちませんが、それでも発生します!

0.88 フリクション SWF

この問題は、UP から DOWN へ、または LEFT から RIGHT へ、ギャップを越えて移動する場合には発生しません。斜めにリンクされた2つの方向ボタンが押され、ギャップを通過した場合にのみ発生します.

上に移動してから左に移動すると、ムービークリップが上にジャンプします。下に移動し、次に左に移動してギャップを横切ると、キャラクターがしゃがんでいるように、ムービークリップが数ピクセル下にジャンプします(?)


現在のコード

Rookies ゲーム/Application クラスは、levelOne をステージに配置するためのレベル スイッチャーとして使用されます。

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
        {
        }
    }
}

レベル 1には、ほとんどのコードと作業の大部分が含まれています。

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 はCharacter Classのインスタンスです。

SWF には 5 つのキー フレームがあり、それぞれの中にアニメーションがあり、4 つの方向ボタンが押されたときに再生されます。また、何も押されていないときに赤い固定アニメーションが再生されます。

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()
            {
            }
        }   
}

BoxクラスとBackgroundクラスは同じで、png を埋め込んでスプライトを追加するだけです。グリッドの背景は単一の画像であることに注意してください。ゲームはタイルベースではありません。.

最後にCollision Class です。_character がボックスと衝突すると、Collision.block 関数が呼び出されます。

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";
            }
        }
    }
}  

どんな助けでも大歓迎です。私は初心者なので、問題は私が見逃した単純なものである可能性が常にあります。

アニメーションの不要なボビングについても質問しています。その情報のいずれかがあなたに役立つか、それに対する解決策も知っているほど賢いなら、質問はここにあります

4

1 に答える 1

0

これを試しましたか?

    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;            
                }   
于 2014-03-20T21:42:40.630 に答える