我正在创建一个基于旧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类,但它看起来很奢侈。
有没有人有过在其他游戏中效果最好的经验?
Morten Twellmann
答案 0 :(得分:6)
这里有几个不同的问题。你的第一个问题是,你应该在帧事件或计时器事件中执行你的游戏循环吗?答案很简单 - 你应该在一个框架事件中做到这一点。原因是无论您如何移动角色,屏幕每帧都会精确更新一次。因此,每当你每次调用你的游戏循环超过一次时,你就会浪费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的答案中所述。
答案 1 :(得分:1)
是的帧速率会因CPU等因素而异。因此,您需要在游戏循环中考虑到这一点。我喜欢做的是获取当前帧和旧帧之间的时差,并在计算中使用该值。因此,如果发生延迟,则较大的差值将弥补较少帧运行的事实。
var _previousTime:Number;
//gameLoop is the function called on ENTER_FRAME
public function gameLoop(e:Event):void
{
var currentTime:Number = getTimer();
var difference:Number = currentTime - _previousTime;
_previousTime = currentTime;
//use difference variable with calculations involving movement
}