我正在创建一个基于旧Pacman的Flash游戏,我不确定哪个是控制动画的最佳方式.
据我了解,这些类型的游戏最初依赖于游戏循环,根据CPU运行得更快或更慢,这就是为什么我认为最相似的使用将是ENTER_FRAME事件.
然而,这提出了必须具有特定帧速率并且稍后改变它的问题是不可能的,更不用说仅限于很少的不同"速度"(见下文).一个例子可能是精灵在确定下一次移动之前必须移动12个像素.如果速度是每帧4像素,则数学非常简单:
[...] public var stepCount:uint = 0; [...] function enterFrameHandler(e:Event):void { if(stepCount==0) { //Some code to evaluate next move. Let's say it evaluates to MOVE RIGHT } if(MOVE_RIGHT) { x += 4; } stepCount++; if(stepCount > 2) { stepCount = 0; //Now ready to evaluate direction again. } }
这一切都很好,但是我想说我希望精灵每帧移动5个像素.然后,在进行下一次评估之前的帧数将无法计算.stepSize必须是12的倍数,这限制了不同的可能速度(每帧1,2,3,4和6像素).
这就是为什么我试图将这个动作建立在Timer的基础上,我也设法开始工作,但是这个动作有些不稳定,看起来Timer正在使用比ENTER_FRAME事件更多的内存.而不是偶数运动,定时器使精灵减速并加速并再次减速.
另一个可能的解决方案可能是Tween类,但它看起来很奢侈.
有没有人体验过其他游戏最好的东西?
莫滕特威尔曼
你在这里有几个不同的问题.你的第一个问题是,你应该在帧事件或计时器事件中执行游戏循环吗?答案很简单 - 你应该在一个框架事件中做到这一点.原因是无论您如何移动角色,屏幕每帧都会精确更新一次.因此,每当你每次调用你的游戏循环不止一次时,你就会浪费CPU,而且每次你每次调用它的时间不到一次,你就会牺牲视觉质量.所以这个很容易,根本不打扰定时器事件.
接下来的问题是你的游戏运动是否应该与帧或毫秒相关联,答案是它取决于游戏.问问自己:假设某些用户正在玩你的游戏,他们的宇宙飞船(或其他任何东西)以给定的速度飞行.突然,用户的防病毒软件包做了很多事情,CPU峰值导致Flash停止更新一秒钟.一旦尖峰结束,您是否希望宇宙飞船继续从尖峰开始时的位置移动?或者你是否希望它向前跳到它在尖峰期间继续移动的位置?如果你想要前者,你应该把你的动作绑在框架上; 如果你想要后者,你应该将它与毫秒相关联.但哪一个最好取决于你希望你的游戏如何工作.
最后一个问题是,你究竟应该如何移动游戏中的角色?根据你写的内容,我会按如下方式进行.对于基于帧的移动(即前面描述的第一种方法):
// the ship moves 25 pixels per second var shipSpeed:Number = 25; // the number of seconds per frame, based on the published framerate var frameTime:Number = 1 / stage.frameRate; // game loop called each frame: function gameLoop() { // ... playerShip.x += shipSpeed * frameTime; // .... }
这样,无论您在SWF上发布什么帧率,船舶在屏幕上的移动都是不变的.使用更高的帧速率只会使运动更平滑.同样,要将您的移动与时间而不是帧相关联,只需更改上面代码中的"frameTime"即可引用自上一帧以来经过的时间,如Allan的回答中所述.