1

プラットフォーマーゲームを作っています。しかし、スペースバーを押してジャンプするたびに、キャラクターが空中で立ち往生するため、問題が発生しています。ただし、スペースバーを押し続けることで問題を解決でき、キャラクターが着陸します。

問題はクラスmainJump()内にあります。Boy

多くの人がアクションタイムラインを使用して問題を解決するのを見ましたが、私の主な問題は、とにかく外部クラスを使用して問題を解決できるかどうかです。

メインクラス

package 
{
import flash.display.*;
import flash.text.*;
import flash.events.*;
import flash.utils.Timer;
import flash.text.*;

public class experimentingMain extends MovieClip 
{
    var count:Number = 0;
    var myTimer:Timer = new Timer(10,count);

    var classBoy:Boy;

    //var activateGravity:gravity = new gravity();

    var leftKey, rightKey, spaceKey, stopAnimation:Boolean;

    public function experimentingMain() 
    {
        myTimer.addEventListener(TimerEvent.TIMER, scoreUp);
        myTimer.start();

        classBoy = new Boy();
        addChild(classBoy);


        stage.addEventListener(KeyboardEvent.KEY_DOWN, pressTheDamnKey);
        stage.addEventListener(KeyboardEvent.KEY_UP, liftTheDamnKey);
    }

    public function pressTheDamnKey(event:KeyboardEvent):void
    {
        if (event.keyCode == 37)
        {
            leftKey = true;
            stopAnimation = false;
        }

        if (event.keyCode == 39)
        {
            rightKey = true;
            stopAnimation = false;
        }

        if (event.keyCode == 32)
        {
            spaceKey = true;
            stopAnimation = true;
        }
    }

    public function liftTheDamnKey(event:KeyboardEvent):void
    {
        if (event.keyCode == 37)
        {
            leftKey = false;
            stopAnimation = true;
        }

        if (event.keyCode == 39)
        {
            rightKey = false;
            stopAnimation = true;
        }

        if (event.keyCode == 32)
        {
            spaceKey = false;
            stopAnimation = true;
        }
    }

    public function scoreUp(event:TimerEvent):void 
    {
        scoreSystem.text = String("Score : "+myTimer.currentCount);
    }

}
    }

男の子クラス

package 
{
import flash.display.*;
import flash.events.*;

public class Boy extends MovieClip
{
    var leftKeyDown:Boolean = false;
    var upKeyDown:Boolean = false;
    var rightKeyDown:Boolean = false;
    var downKeyDown:Boolean = false;
    //the main character's speed
    var mainSpeed:Number = 5;
    //whether or not the main guy is jumping
    var mainJumping:Boolean = false;
    //how quickly should the jump start off
    var jumpSpeedLimit:int = 40;
    //the current speed of the jump;
    var jumpSpeed:Number = 0;

    var theCharacter:MovieClip;

    var currentX,currentY:int;

    public function Boy()
    {
        this.x = 600;
        this.y = 540;

        addEventListener(Event.ENTER_FRAME, boyMove);
    }

    public function boyMove(event:Event):void
    {
        currentX = this.x;
        currentY = this.y;

        if (MovieClip(parent).leftKey)
        {
            currentX +=  mainSpeed;
            MovieClip(this).scaleX = 1;
        }

        if (MovieClip(parent).rightKey)
        {
            currentX -=  mainSpeed;
            MovieClip(this).scaleX = -1;
        }

        if (MovieClip(parent).spaceKey)
        {
            mainJump();
        }

        this.x = currentX;
        this.y = currentY;
    }

    public function mainJump():void
    {
        currentY = this.y;


        if (! mainJumping)
        {

            mainJumping = true;
            jumpSpeed = jumpSpeedLimit * -1;
            currentY +=  jumpSpeed;
        }
        else
        {
            if (jumpSpeed < 0)
            {
                jumpSpeed *=  1 - jumpSpeedLimit / 250;
                if (jumpSpeed > -jumpSpeedLimit/12)
                {
                    jumpSpeed *=  -2;
                }
            }
        }
        if (jumpSpeed > 0 && jumpSpeed <= jumpSpeedLimit)
        {
            jumpSpeed *=  1 + jumpSpeedLimit / 120;
        }
        currentY +=  jumpSpeed;

        if (currentY >= stage.stageHeight - MovieClip(this).height)
        {
            mainJumping = false;
            currentY = stage.stageHeight - MovieClip(this).height;
        }
    }
    }
    }
4

2 に答える 2

1

まず、コードを形式化して、関数がキーを押すことができないために関数をうまく説明していない「pressTheDamnKey」のような厄介なものを排除します。これはイベントハンドラーであり、keyDownHandlerまたはonKeyDownのいずれかという名前にする必要があります。

次に、イベントデータの直接の懸念を超えて、イベントハンドラーで実際の作業を行うことはめったにありません。代わりに、実際の作業を行う関数を呼び出します。ハンドラーがイベントを処理してから、作業を行うコードを呼び出します。これにより、おそらくマウスのように、enterFrameHandler以外に小さな男の子をアニメートさせることができるようにしたい場合の懸念がうまく分離されます。

タイマーが1秒間に100回(1秒あたり10ミリ秒)起動しているため、トレースログが「スコア」行ですぐにいっぱいになることが想像できます。タイマーで起動しないように変更しますが、スコアが実際に変更されたときに更新されます。

スパゲッティコード以外のジャンプの問題は、キーが押されたかどうかに基づいて、キーの押下状態を変数に保存し、継続的に検査することです。これはいくつかの理由で悪いです:1。彼は情報を得るために彼の環境に手を差し伸べる必要はありません、それは彼を所有するオブジェクトまたは彼に伝える責任があるオブジェクトによって彼に与えられるべきですそして2.それはあなたを必要としますスペースバーを押し続けると、スペースバーが押し下げられているかどうかを確認するため、移動が停止します(問題1を参照)。

以下では、これらすべての問題に対処し、スコアリングは省略します。これは、まったく別の問題です。

package 
{
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import flash.utils.*;

    //  Sprite is preferred if you are not using the timeline
    public class Application extends Sprite 
    {
        private var boy:Boy;

        public function Application() 
        {
            boy = new Boy();
            addChild(boy);
            boy.x = 600;    //  set these here, not in the boy
            boy.y = 540;
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP,   keyUpHandler  );
        }

        public function keyDownHandler(event:KeyboardEvent):void
        {
            switch(event.keyCode)
            {
                case 32: boy.jump();
                         break;
                case 37: boy.moveLeft();
                         break;
                case 39: boy.moveRight();
                         break;
                default:
                    // ignored
                    break;
            }
        }

        public function keyUpHandler(event:KeyboardEvent):void
        {
            switch(event.keyCode)
            {
                //  ignored for jumping (32)
                case 37: //  fall through
                case 39: boy.stop();
                         break;
                default:
                    // ignored
                    break;
            }
        }

    }//class
}//package

package 
{
    import flash.display.*;
    import flash.events.*;

    //  It is assumed that there is an asset in the library
    //  that is typed to a Boy, thus it will be loaded onto
    //  the stage by the owner
    public class Boy extends Sprite
    {
        private var horzSpeed   :Number = 0;
        private var vertSpeed   :Number = 0;
        private var floorHeight :Number;
        private var jumpHeight  :Number;
        private var amJumping   :Boolean = false;

        public function Boy()
        {
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }

        public function moveLeft():void
        {
            horzSpeed = -1;
        }

        public function moveRight():void
        {
            horzSpeed = 1;
        }

        public function stop():void
        {
            horzSpeed = 0;
        }

        public function jump():void
        {
            if (amJumping)  return;
            floorHeight = y;
            jumpHeight = floorHeight + 20;
            vertSpeed = 2;
            amJumping = true;
            animateJump();
        }

        private function enterFrameHandler(event:Event):void
        {
            animate();
        }

        private function animate():void
        {
            x += horzSpeed;
            if( amJumping )
            {
                animateJump();
            }
        }

        //  Doing a simple version for this example.
        //  If you want an easier task of jumping with gravity,
        //  I recommend you employ Greensock's superb
        //  TweenLite tweening library.
        private function animateJump():void
        {
            y += vertSpeed;
            if( y >= jumpHeight )
            {
                y = jumpHeight;
                vertSpeed = -2;
            }
            else if( y <= floorHeight )
            {
                y = floorHeight;
                amJumping = false;
            }
        }

    }//class
}//package

これに取り組む別の方法、そしておそらく長期的にはより良い方法は、少年が自分自身を動かすことにさえ責任を負わないことです。代わりに、親、彼の所有者、またはスケジュールに従って物事をアニメーション化する責任がある特別なアニメータークラスでそれを処理します。このさらにカプセル化されたパラダイムでは、少年は、自分に何が起こっているのかを伝える外界に基づいて、自分の内部の外観を更新する責任があるだけです。彼はもはや内部でジャンプを処理しませんが、代わりに彼の腕や脚のような彼が所有するものをアニメートするようなことをする責任があります。

于 2013-02-15T10:36:13.190 に答える
0

mainJumpingジャンプの実行中にのみtrueとなる変数があります。なぜそれを使用しないのですか?

if (MovieClip(parent).spaceKey || mainJumping)
{
    mainJump();
}
于 2013-02-11T16:23:25.123 に答える