0

实现加速游戏或可靠暂停游戏的游戏速度功能的最佳方法是什么?

我希望在深入研究之前找到理想的方法,因为它是一个非常不可或缺的部分或其他游戏元素的实现方式。

4

3 回答 3

3

我会说使用一个输入帧侦听器,它有一个内部循环来多次调用主更新函数。stage.frameRate如果你想放慢你的游戏节奏,你也可以玩财产。或者,您可以创建一个“时间增量”属性,该属性将被传递到主更新函数中,这样一切都将表现得好像不是整个帧,而只是其中的一部分已经过去,从而产生实时的全局慢动作效果。

它的一个典型组织如下:

public var cyclesPerFrame:int;
addEventListener(Event.ENTER_FRAME,mainUpdate);
function mainUpdate(e:Event):void {
    for (var i:int=cyclesPerFrame;i>0;i--) internalUpdate();
    // it's the function that handles all your game ^
    // if you need to update visuals regardless of pause, use this:
    // updateVisuals();
}

这将使每帧进行多次内部更新。这也将允许您设置cyclesPerFrame为零,从而有效地暂停。

于 2013-09-28T05:19:56.147 回答
1

我认为通过测量帧之间经过的时间并以此为基础进行速度计算,您将获得最佳结果。

有一个内部速度变量,您可以根据需要更改它,然后通过计算经过的“滴答声”(游戏速度除以自上一帧以来经过的时间)来更新每一帧的游戏状态。这为您提供流畅的游戏速度控制,并保持稳定的帧速率(这对于流畅度的印象至关重要)。

不过要小心游戏暂停。如果您将游戏速度设置为 0,则不会发生任何滴答声,但所有补间、计时器和类似对象将继续运行,因此您必须单独管理它们。

于 2013-09-30T09:19:00.783 回答
1

这是一个示例,它将以相同的速率移动一个圆圈,而不管帧速率如何。它使用显示列表,但同样的技术也适用于八哥:

包裹

{
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.utils.getTimer;


    public class Main extends Sprite 
    {
        private var lastFrame:int = 0;
        private var thisFrame:int;
        private var pixelsPerSecond:Number = 200;
        private var circle:Shape
        private var percentToMove:Number; 
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
            circle = new Shape();
            circle.graphics.beginFill(0xFF0000);
            circle.graphics.drawCircle(0, 0, 25);
            circle.x = 50;
            addChild(circle);
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function onEnterFrame(e:Event):void 
        {
            // Get the miliseconds since the last frame
            thisFrame = getTimer();
            percentToMove = (thisFrame - lastFrame) / 1000;
            // Save the value for next frame.
            lastFrame = thisFrame;
            // Update your system based on time, not frames.
            circle.x += pixelsPerSecond * percentToMove;

        }

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
        }

    }

}

这有助于确保您的屏幕更新是适当的。有些事件需要更频繁地发生,并且与刷新率无关(人工智能、物理步骤)。您可以使用计时器来处理这些情况,或者根据 on EnterFrame 中的 deltaTime 迭代适当数量的步骤。

于 2013-10-14T20:50:42.853 回答