与按键相关的角色移动,随着角色速度的提高而提高动画速度
Posted
技术标签:
【中文标题】与按键相关的角色移动,随着角色速度的提高而提高动画速度【英文标题】: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;
【问题讨论】:
【参考方案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以上是关于与按键相关的角色移动,随着角色速度的提高而提高动画速度的主要内容,如果未能解决你的问题,请参考以下文章