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 动画时,这很好地分离了关注点,比如鼠标。

我可以想象您的跟踪日志很快就会被“分数”行填满,因为您的计时器每秒触发 100 次(每次 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

解决这个问题的另一种方法,可能是长期更好的方法,是让男孩甚至不负责移动自己。相反,您将在父级、他的所有者或一些特殊的 Animator 类中处理该问题,该类负责按计划对事物进行动画处理。在这个更加封装的范例中,男孩只负责根据外部世界告诉他发生在他身上的事情来更新他自己的内部外观。他将不再处理内部跳跃,而是负责做一些事情,比如动画他拥有的东西,比如他的胳膊和腿。

于 2013-02-15T10:36:13.190 回答
0

您有一个mainJumping仅在跳转运行时才为真的变量。为什么不直接使用它?

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