原文
http://www.8bitrocket.com/newsdisplay.aspx?newspage=10248 摘取重要的部分做点简单的翻译把 我的e文也很差阿 注意我这并非直译,e文好的最好看原文
这个主要是用来解决
游戏在不同的
播放器中fps不稳定。
在游戏循环中增加3步优化:1。在使用copyPixels 像素前先lock画布,操作后在
调用unlock 2。实现一个基于渲染计时器的sleep 3。确保游戏循环中的update都是在每次
事件后而不是每frame后。
1。 BitmapData.lock and BitmapData.unlock 这个原理就是在调用BitmapData.lock后,当对这个BitmapData执行多次copyPixels操作时
flash会停止所有引用这个BitmapData
对象的刷新,在调用BitmapData.unlock后所有改变才会在引用这个BitmapData的对象上体现。
下面的代码中
drawBackground();
drawPlayer();
drawRocks();
drawMissiles();
drawParts();
这5个操作flash只会在canvasBD.unlock();后执行一次更新,不是在每个操作后都刷新显示。
checkKeys();
updatePlayer();
updateRocks();
updateMissiles();
checkCollisions();
canvasBD.lock();
drawBackground();
drawPlayer();
drawRocks();
drawMissiles();
drawParts();
canvasBD.unlock();
2. 基于计时器的Sleep
这个好像在Andrew 那个最流行的书里有(我没看过...)。
代码如下:
- private function runGame(e:TimerEvent) {
- _beforeTime = getTimer();
- _overSleepTime = (_beforeTime - _afterTime) - _sleepTime;
- checkKeys();
- updatePlayer();
- updateRocks();
- updateMissiles();
- checkCollisions();
- canvasBD.lock();
- drawBackground();
- drawPlayer();
- drawRocks();
- drawMissiles();
- drawParts();
- canvasBD.unlock();
-
- _afterTime = getTimer();
- _timeDiff = _afterTime - _beforeTime;
- _sleepTime = (_period - _timeDiff) - _overSleepTime;
- if (_sleepTime <= 0) {
- _excess -= _sleepTime
- _sleepTime = 2;
- }
- gameTimer.reset();
- gameTimer.delay = _sleepTime;
- gameTimer.start();
- while (_excess > _period) {
- checkKeys();
- updatePlayer();
- updateRocks();
- updateMissiles();
- checkCollisions();
- _excess -= _period;
- }
-
- frameTimer.countFrames();
- frameTimer.render();
- if (aRock.length ==0 && aActiveParticle.length==0) stopRunningGame();
-
- }
FRAME_RATE 每秒的刷新次数,我设为40
_period 每次循环所有操作预定的毫秒数 即25 (1000/40)
_beforeTime and _afterTime 辅助变量,用来计算实际的执行时间,我们希望这个时间小于25ms(or _period value).
_timeDiff the _afterTime and the _beforeTime的差
_sleepTime = period (25) - _timeDiff.
_overSleepTime 用来校正sleepTime
_excess 保存所有处理时间, 当_excess 大于period (25),我们将执行额外的checkeys(), update(), and check collisions() ,但不渲染这些对象。
3. UpdateAfterEvent()
通过调用TimerEvent .updateAfterEvent() ,可以强迫Flash 立即刷新屏幕。用这种方法我们可以设置游戏的Frame Rate为一个相对较低的值,而游戏却可以以较高的Frame Rate运行。
如游戏中有一个18 FPS的
动画,而游戏需要以30FPS运行,这时我们可以设置这个flash的Frame Rate为18, 而上面代码中的FRAME_RATE设为30,这样动画以18 FPS播放,而游戏是以30 FPS运行。 (就是代码的最后面几行)

终于完了.......
- private function runGame(e:TimerEvent) {
- _beforeTime = getTimer();
- _overSleepTime = (_beforeTime - _afterTime) - _sleepTime;
- checkKeys();
- updatePlayer();
- updateRocks();
- updateMissiles();
- checkCollisions();
- canvasBD.lock();
- drawBackground();
- drawPlayer();
- drawRocks();
- drawMissiles();
- drawParts();
- canvasBD.unlock();
-
- _afterTime = getTimer();
- _timeDiff = _afterTime - _beforeTime;
- _sleepTime = (_period - _timeDiff) - _overSleepTime;
- if (_sleepTime <= 0) {
- _excess -= _sleepTime
- _sleepTime = 2;
- }
- gameTimer.reset();
- gameTimer.delay = _sleepTime;
- gameTimer.start();
- while (_excess > _period) {
- checkKeys();
- updatePlayer();
- updateRocks();
- updateMissiles();
- checkCollisions();
- _excess -= _period;
- }
-
- frameTimer.countFrames();
- frameTimer.render();
- if (aRock.length ==0 && aActiveParticle.length==0) stopRunningGame();
- e.updateAfterEvent();
- }
评论