【问题标题】:Character movement tied to keypress, increases animation speed with increased character speed与按键相关的角色移动,随着角色速度的提高而提高动画速度
【发布时间】:2013-07-31 18:15:22
【问题描述】:

我遇到了一个棘手的问题(至少对我而言),我无法弄清楚。我有一个简笔画,我想根据他是向左还是向右移动来制作一个简单的跑步动画,但还要将动画速度与他在 x 方向移动的速度联系起来。

下面我包含了我的角色如何移动的代码(我的游戏中所有不必要的代码都被删除了)。 xspeed 也是我希望我的动画速度以某种方式联系起来的。我可以简单地将它与xspeed 的绝对值联系起来,因为它可能是负数。理想情况下,我想要 2 个动画,1 个用于向左移动,1 个用于向右移动。我想为我的stickman1在同一时间轴上制作两个动画,然后做这样的事情。

if (xspeed > 0){stickman1.gotoAndPlay(2)}
if (xspeed < 0){stickman1.gotoAndPlay(5)}

假设我向右移动的动画是 3 帧长,从第 2 帧开始,在第 4 帧结束,而我向左移动的动画也是 3 帧长,从第 5 帧开始,在第 7 帧结束,然后在第 4 帧和第 7 帧只是输入了一些代码,上面写着gotoAndPlay(correct frame to repeat)。尽管如此,我知道在时间线上进行任何编码总是不好的做法,所以如果可能的话,我想远离那个。然后它只会变得更糟。我不知道如何加速动画 =(。所以这就是我所在的位置,非常感谢有关这些问题的帮助,我的角色移动的完整代码如下!谢谢!

public var gameTimer:Timer;
public var stickman1:Stickman1;
public var leftBool:Boolean = false;
public var rightBool:Boolean = false;
public var accel:Number = 0.5;
public var maxspeed:Number = 8;
public var xspeed:Number = 0;

public function gameScreen():void
{
    this.addEventListener(Event.ENTER_FRAME, addSomeListeners, false, 0, true);
    stickman1 = new Stickman1();
    stickman1.x = 250;
    stickman1.y = 300;
    addChild(stickman1);
    gameTimer.addEventListener(TimerEvent.TIMER, onTick, false, 0, true);
    gameTimer = new Timer(25);
    gameTimer.start();
}

public function addSomeListeners(event:Event):void
{
    stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true);
    stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp, false, 0, true);
}

public function onTick(timerEvent.TimerEvent):void
{
    if(rightBool==true && xspeed<maxspeed){xspeed+=2}
    if(leftBool==true && xspeed>-maxspeed){xspeed-=2}
    if(xspeed>0){xspeed-=accel}
    if(xspeed<0){xspeed+=accel}

    stickman1.x+=xspeed;
    stickman1.y+=yspeed;
}

public function onKeyDown(keyboardEvent.KeyboardEvent):void
{
    if (event.keyCode == Keyboard.LEFT){leftBool = true};
    if (event.keyCode == Keyboard.RIGHT){rightBool = true};
}

public function onKeyUp(keyboardEvent.KeyboardEvent):void
{
    if (event.keyCode == Keyboard.LEFT){leftBool = false};
    if (event.keyCode == Keyboard.RIGHT){rightBool = false};
}

【问题讨论】:

    标签: actionscript-3 animation actionscript keypress


    【解决方案1】:

    您需要管理自己的动画系统,但这并不像听起来那么难:)

    这样的事情应该可以工作(假设第 0 帧是站立的,而第 1-n 帧正在运行):

    public var dir:int = 0; // direction you're going; -1 = left, 1 = right, 0 = not moving
    public var speed:Number = 0.0; // the speed of your char
    public var stickman:Stickman; // your stickman obj
    public var prevTime:Number = 0.0; // used to calculate delta time in the update
    public var currAnimTime:Number = 0.0; // our current animation time
    public var currAnimFrame:int = 0; // our current animation frame
    
    public function gameScreen():void
    {
        // create our stickman
        this.stickman = new Stickman();
        this.stickman.gotoAndStop( 0 ); // stand frame
        …
    
        // add our listeners
        this.addEventListener( Event.ENTER_FRAME, this._onEnterFrame );
        this.addEventListener( KeyboardEvent.KEY_DOWN, this._onKeyDown );
        this.addEventListener( KeyboardEvent.KEY_UP, this._onKeyUp );
    
        this.prevTime = getTimer();
    }
    
    private function _onEnterFrame( e:Event ):void
    {
        // calculate delta time
        var currTime:int = getTimer();
        var dt:Number   = ( currTime - this.prevTime ) * 0.001; // dt is in seconds
        this.prevTime   = currTime;
    
        // check if we're slowing down
        if( this.dir == 0 )
        {
            this.speed *= 0.8;
            if( this.speed <= 0.01 ) // or whatever value you want
                this.speed = 0.0;
        }
        else
        {
            // we're running
            this.speed += 20 * dt * this.dir; // or whatever speed increase you want
            if( this.speed > 20 )
                this.speed = 20; // max speed;
        }
    
        // if our speed is 0, just play the stand anim and return
        if( this.speed == 0 )
        {
            this.gotoAndStop( 0 );
            return;
        }
    
        // get our anim time - the seconds for a frame.
        // basically, if speed is 20, then our anim time will be
        // 1.0 (1 second) / 20.0 -> 0.05, or 0.05 seconds
        // per frame. We use seconds because dt and currAnimTime are
        // in seconds. NOTE: this is a linear transform of speed -> fps
        var animTime = 1.0 / this.speed;
    
        // update our current anim time
        this.currAnimTime += dt;
        while( this.currAnimTime > animTime )
        {
            // increase our current anim frame
            this.currAnimFrame++;
            if( this.currAnimFrame > this.totalFrames )
                this.currAnimFrame = 1; // frame 0 is our stand anim
        }
    
        // go to our new frame
        if( this.currAnimFrame != this.currFrame )
            this.gotoAndStop( this.currAnimFrame );
    
        // flip our scale based on if we're right or left
        this.scaleX = ( this.dir < 0 ) ? -1 : 1;
    }
    
    private function _onKeyDown( e:KeyboardEvent ):void
    {
        // move left or right
        if( e.keyCode == Keyboard.LEFT )
            this.dir = -1;
        else if( e.keyCode == Keyboard.RIGHT )
            this.dir = 1;
    }
    
    private function _onKeyUp( e:KeyboardEvent ):void
    {
        // stop
        if( e.keyCode == Keyboard.LEFT || e.keyCode == Keyboard.RIGHT )
            this.dir = 0;
    }
    

    基本上,您只需更改显示每一帧的时间,然后手动处理更改为正确的帧。这样一来,您的动画就会随着 char 的速度加快和减慢。

    【讨论】:

    • 编辑:我在animFPS 计算周围添加了一个Math.abs(),因为speed 可以低于0
    • 哇,这太棒了!唯一可能您可以再次查看的另一件事是 this.animFPS 部分。在我看来,我们走得越快,animFPS 就越慢,因为它们成反比。对我来说,它看起来应该只是 Math.abs(this.speed),但也许我错过了什么?还猜测那里的某个地方也必须有一个比例常数?
    • 我是凭脑子写的,所以里面可能有bug :D 你可以去掉animFPS 变量;它只是用来计算animTime,即每帧花费的毫秒数。基本上,随着speed 上升,animTime 应该越来越低,所以像 var animTime = 1000 / Math.abs( this.speed );
    • “还猜测那里一定有一个比例常数” - 是的,这里是非常线性的;你如何计算最终的animTime 取决于你想要的效果。查看缓动方程或日志函数(不是我的专业领域,抱歉)
    • 好的,我今天要尝试实现它,至少对我来说这一切都有意义 =p
    猜你喜欢
    • 2019-05-09
    • 2020-11-07
    • 1970-01-01
    • 2018-02-22
    • 2011-09-20
    • 1970-01-01
    • 2014-02-16
    • 2015-02-01
    • 2017-06-01
    相关资源
    最近更新 更多