我正在创建一个收集游戏,我想创建一个时间慢/加速通电。 关于如何在Flash / AS3中做到这一点的任何想法?
我想到的一种方法就是改变帧速率。我可以减慢帧速率。但是当我尝试将帧速率提高到60以上时,Flash会将其限制为60。
提前感谢您的帮助。
答案 0 :(得分:2)
我喜欢做基于时间的动作而不是基于帧的动作,以获得更好的一致性。一般的概念是检查帧之间经过的时间量和基础移动而不是可以交替的帧(例如,你可以有60FPS一点然后它减慢到30FPS)。您可以根据移动的时间进行简单的计算,例如player.x += player.speed * timeDiff
但是如果在帧之间传递的时间恰好很大(例如,玩家最终可能会丢失大量的碰撞,因为你正在一个大的运动中移动他)。相反,我喜欢使用游戏循环根据帧之间传递的时间量移动玩家X次,确保正确检查碰撞和任何其他游戏循环事件。
这也具有易于调节速度的优点。
这是基本概念:
private var speedMultiplier:int = 100;//100 normal speed, 0 paused
private var currRealTime:int = getTimer();
private var currGameTime:int = currRealTime;
private var globalLastTime:int = currRealTime;
private var totalTimeDiffRemainder:int = 0;
private var loopTime:int = 20;//every 20 ms run our actions
public function getGameTimer():int
{
return currGameTime;
}
private function updateGameTime():void
{
var realTime:int = getTimer();
currGameTime = currGameTime + speedMultiplier/100*(realTime - currRealTime);
currRealTime = realTime;
}
private function runEvents(event:Event):void
{//ENTER_FRAME event
var totalTimeDiff:int = getGameTimer() - globalLastTime + totalTimeDiffRemainder;
globalLastTime = getGameTimer();
while (totalTimeDiff > loopTime)
{//every 20 ms run all our actions
totalTimeDiff -= loopTime;
//run all your game loop events here, such as collision checks
}
totalTimeDiffRemainder = totalTimeDiff;
updateGameTime();
}
因此,每当一个ENTER_FRAME事件触发时,我们将检查自上次ENTER_FRAME事件以来经过的时间,然后对已经过的每个20ms执行一次操作,并将余数传递给下一个ENTER_FRAME事件。例如,如果自上次ENTER_FRAME以来已经过了47毫秒,我们将执行两次操作并将剩余的7个ms传递给下一个ENTER_FRAME事件。
为了暂停,减慢或加速游戏,你所要做的就是修改speedMultiplier。将speedMultiplier更改为0将暂停游戏,50为半速100正常速度,200倍速等等。
答案 1 :(得分:1)
我相信这样做的一般方法是使用类似MVC的设置,其中模型包含游戏元素的所有数据(角色位置/方向,敌人,动态地图元素),然后控制器正在修改模型。通过控制器以这种方式修改模型,您可以向模型添加乘数,并在控制器更新游戏中“物理”或其他修改动态元素的模型时使用乘数。
大致是:
模型
public var speedMultiplier:Number=1;
public var playerXSpeed:Number;
public var playerYSpeed:Number;
Controller(我假设您创建一个控制器类并将视图传递给构造函数,并从控制器中的视图中侦听事件。)
private function enterFrame_handler(event:Event):void
{
var playerSprite:Sprite = mainView.playerSprite;
playerSprite.x += playerXSpeed*speedMultiplier; //only problem I can see here is your player skipping past certain elements, to avoid this you could use a loop to make each motion and do checks but it's more CPU intensive
//var enemySprites:Vector<EnemySprite>;
//other game physics here, reduce speed due to drag, fix any invalid values etc.
}
修改强>
实际上通过更多思考这个,虽然我一般都喜欢自己使用MVC设置,因为它允许一个人有一个精灵来完成所有的绘图;您也可以使用此处所示的speedMultiplier的相同概念,而无需更改任何软件模式。如果您最终需要使用循环,因为您需要它来检查对象移动时会遇到的每个点,您可能需要将默认的speedMultiplier设置为10,这样您就可以将其设置为1使用所有相同的检查得到1/10的速度,就像它在正常速度下得到的那样(再次只是问题,它必须为每次更新做10次计算,在这种情况下你可能想要使用计时器而不是帧速率控制整体计算速度。)