アップデート6:
フェノメナスは、可能な限りシンプルにすべてを再作成するように私に提案しました。アルゴリズムは同じままであり、パフォーマンスは問題ではないように思われたので、これが違いを生むのではないかと疑問に思いました。とにかく、それは私が得た唯一の提案だったので、ここにあります:
- 30 FPS: http: //www.feedpostal.com/test/simple/30/SimpleMovement.html
- 40 FPS: http: //www.feedpostal.com/test/simple/40/SimpleMovement.html
- 60 FPS: http: //www.feedpostal.com/test/simple/60/SimpleMovement.html
- 100 FPS: http: //www.feedpostal.com/test/simple/100/SimpleMovement.html
コード:
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.utils.getTimer;
[SWF(width="800", height="600", frameRate="40", backgroundColor="#000000")]
public class SimpleMovement extends Sprite
{
private static const TURNING_SPEED:uint = 180;
private static const MOVEMENT_SPEED:uint = 400;
private static const RADIAN_DIVIDE:Number = Math.PI/180;
private var playerObject:Sprite;
private var shipContainer:Sprite;
private var moving:Boolean = false;
private var turningMode:uint = 0;
private var movementTimestamp:Number = getTimer();
private var turningTimestamp:Number = movementTimestamp;
public function SimpleMovement()
{
//step 1: create player object
playerObject = new Sprite();
playerObject.graphics.lineStyle(1, 0x000000);
playerObject.graphics.beginFill(0x6D7B8D);
playerObject.graphics.drawRect(0, 0, 25, 50);
//make it rotate around the center
playerObject.x = 0 - playerObject.width / 2;
playerObject.y = 0 - playerObject.height / 2;
shipContainer = new Sprite();
shipContainer.addChild(playerObject);
shipContainer.x = 100;
shipContainer.y = 100;
shipContainer.rotation = 180;
addChild(shipContainer);
//step 2: install keyboard hook when stage is ready
addEventListener(Event.ADDED_TO_STAGE, stageReady, false, 0, true);
//step 3: install rendering update poll
addEventListener(Event.ENTER_FRAME, updatePoller, false, 0, true);
}
private function updatePoller(event:Event):void
{
var newTime:Number = getTimer();
//turning
if (turningMode != 0)
{
var turningDeltaTime:Number = newTime - turningTimestamp;
turningTimestamp = newTime;
var rotation:Number = TURNING_SPEED * turningDeltaTime / 1000;
if (turningMode == 1) shipContainer.rotation -= rotation;
else shipContainer.rotation += rotation;
}
//movement
if (moving)
{
var movementDeltaTime:Number = newTime - movementTimestamp;
movementTimestamp = newTime;
var distance:Number = MOVEMENT_SPEED * movementDeltaTime / 1000;
var rAngle:Number = shipContainer.rotation * RADIAN_DIVIDE; //convert degrees to radian
shipContainer.x += distance * Math.sin(rAngle);
shipContainer.y -= distance * Math.cos(rAngle);
}
}
private function stageReady(event:Event):void
{
//install keyboard hook
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp, false, 0, true);
}
private final function keyDown(event:KeyboardEvent):void
{
if ((event.keyCode == 87) && (!moving)) //87 = W
{
movementTimestamp = getTimer();
moving = true;
}
if ((event.keyCode == 65) && (turningMode != 1)) //65 = A
{
turningTimestamp = getTimer();
turningMode = 1;
}
else if ((event.keyCode == 68) && (turningMode != 2)) //68 = D
{
turningTimestamp = getTimer();
turningMode = 2;
}
}
private final function keyUp(event:KeyboardEvent):void
{
if ((event.keyCode == 87) && (moving)) moving = false; //87 = W
if (((event.keyCode == 65) || (event.keyCode == 68)) && (turningMode != 0)) turningMode = 0; //65 = A, 68 = D
}
}
}
結果は思った通りでした。まったく改善はありません。この問題を修正する必要があるので、誰かが別の提案をしてくれることを本当に望んでいます。また、私はかなり良いシステム(8GB RAM、Q9550 QuadCore Intel、ATI Radeon 4870 512MB)を持っているので、それが私のシステムだとは思えません。また、私がこれまでに尋ねた他のすべての人は、私のクライアントと同じ問題を抱えていました。
アップデート5:私の動きが間違いなく違うことを示すためのスムーズなフラッシュゲームの別の例!http://www.spel.nl/game/bumpercraft.htmlを参照してください
更新4:レンダリング前(EVENT.RENDER)とレンダリング直後(EVENT.ENTER_FRAME)の時間をトレースした結果、次のようになりました。
rendering took: 14 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 14 ms
rendering took: 14 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 24 ms
rendering took: 18 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 232 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 16 ms
rendering took: 12 ms
rendering took: 14 ms
rendering took: 12 ms
範囲は12〜16ミリ秒です。これらの違いの間、衝撃的/反り/ちらつきの動きはすでに起こっていました。232msのピークも1つありますが、このときは比較的大きな反りがありました。ただし、これは最大の問題ではありません。最大の問題は、通常の動作中の継続的な小さな反りです。これは誰かに手がかりを与えますか?
更新3:テスト後、次の要因が問題の原因ではないことがわかりました。
- ビットマップの品質->フォトショップで醜い8色に最適化されたグラフィックに変更されましたが、まったく改善されていません。
- 回転中の画像の一定の回転->無効にした、まったく改善なし
- ブラウザのレンダリング->FlashPlayerをスタンドアロンで使用しようとしましたが、まったく改善されていません
私は、問題が私のコードまたは私のアルゴリズムのいずれかにあると100%確信しています。私を助けてください。ほぼ2週間(SOでこの質問をしたのは1週間)ですが、それでも黄金の答えを得る必要があります。
更新1:完全なフレックスプロジェクトソースと私の問題を示すライブデモについては、下部を参照してください。
私は2Dフラッシュゲームに取り組んでいます。プレイヤーの船はオブジェクトとして作成されます:
ships[id] = new GameShip();
移動と回転の情報が利用できる場合、これは対応する船に送信されます。
ships[id].setMovementMode(1); //move forward
これで、このGameShip内で、オブジェクトの移動は「Event.ENTER_FRAME」イベントを使用して機能します。
addEventListener(Event.ENTER_FRAME, movementHandler);
その後、次の関数が実行されます。
private final function movementHandler(event:Event):void
{
var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp
var distance:Number = (newTimeStamp - movementTimeStamp) / 1000 * movementSpeed; //speed = x pixels forward every 1 second
movementTimeStamp = newTimeStamp; //update old timeStamp
var diagonalChange:Array = getDiagonalChange(movementAngle, distance); //the diagonal position update based on angle and distance
charX += diagonalChange[0];
charY += diagonalChange[1];
if (shipContainer)
{ //when the container is ready to be worked with
shipContainer.x = charX;
shipContainer.y = charY;
}
}
private final function getDiagonalChange(angle:Number, distance:Number):Array
{
var rAngle:Number = angle * Math.PI/180; //convert degrees to radian
return [Math.sin(rAngle) * distance, (Math.cos(rAngle) * distance) * -1];
}
オブジェクトが移動しなくなると、イベントリスナーは削除されます。同じ方法が回転にも使用されています。すべてがほぼ完璧に機能します。
プロジェクトのターゲットFPSを100に設定し、FPSカウンターを作成しました。FPSカウンターによると、Firefoxの平均FPSは約100、トップは1000、ボトムは22です。ボトムとトップのFPSは、クライアントの初期化(起動)中にのみ発生していると思います。
問題は、船がほぼ完全に滑らかに見えることですが、「ほぼ」部分がない状態である必要があります。まるで船が非常に速く「ちらつき」ているようで、実際には見えませんが、目で動いている間は物体に焦点を合わせるのが困難です。また、時々、フレームレートのスパイクが少しあるように見えます。クライアントが数フレームをスキップしているように、すぐにワープするのがわかります。
本当の問題を説明するのは非常に難しいですが、一般的には動きが完全にスムーズではないということです。では、オブジェクトの移動や遷移を完全にスムーズにする方法について何か提案はありますか?
アップデート1:
問題を示すためにクライアントを再作成しました。チェックアウトしてください。
クライアント: http: //feedpostal.com/test/MovementTest.html
Actionscriptプロジェクト(完全なソース): http: //feedpostal.com/test/MovementTest.rar
スムーズなフラッシュゲームの例(私が作成したものではありません):http ://www.gamesforwork.com/games/swf/Mission%20Racing_august_10th_2009.swf
このクライアント側バージョンを再作成するのにかなり長い時間がかかりました。これが問題の解決に役立つことを願っています。
注意:はい、実際にはかなりスムーズです。しかし、それは確かに十分に滑らかではありません。