3

ゲームループを単純化して、画面上を移動するボックスだけにしました。ここをクリックしてください。どういうわけか、箱がスムーズに動かないようです。ここでビデオを作りました。

ゲームループは次のように呼ばれます。

var game = function( ) {
    var now = Date.now( );
    var delta = now - then;

    update( delta / 1000 );
    draw( );

    then = now;
};

setInterval( game, 1000 / 50 );

draw呼び出しをメインのゲームループから分離して入れようとしましrequestAnimationFrameたが、問題は解決しません。スムーズに実行されるように見えるチュートリアルをたくさん見てきました。固定のタイムステップゲームループを使用してみましたが、ゲームの実行速度が非常に速くなりました。

おそらく呼び出しを利用しrequestAnimationFrameて維持deltaTimeすることで、上記のロジックをどのように改善できますか?update

4

2 に答える 2

4

キャンバスを使用する場合、位置変数は整数値である必要があると思います。これは、ピクセルを表し、浮動小数点値が意味をなさないためです。コンソールを開いて入力するとsceneManager.currentScene.GameplayLayer.ball.position.x、非常に長い 10 進数が返されます。ボールが1pxではなく2px動いていることを示唆するOPのコメントは、何かに関係している可能性があると思います. 位置を更新すると、浮動小数点値になります。

時には、次に高いピクセル位置に切り上げられることもあれば、切り下げられることもあると思います。床または天井を次のように取ります。

this.position.x += Math.floor(this.speed * 100 * deltaTime * Math.cos(directionInRadians));
this.position.y += Math.floor(this.speed * 100 * deltaTime * Math.sin(directionInRadians));

これらの両方の変更を加えて、それがどのように動作するかを確認します。

編集:ロジックを簡素化するために質問を編集したため。私が作成したこの Clock オブジェクトを使用することです。これは常に使用しています。スムーズなアニメーションが得られ、かなりシンプルです。これは、Three.JS が使用するクロックに基づいているため、それも確認することをお勧めします。独自のコードを使用したい場合でも、少なくともこの既製のソリューションを試して、同じ結果が得られるかどうかを確認できます。それは私にとってはうまくいくようです。また、シムを使用してみましたので、ゲーム関数での呼び出しはrequestAnimFrame(game);?

var Clock = function () {

    /** Member startTime will remain fixed at its integer
        millisecond value returned by Date.now(). Will always
        be equal to the time the clock was started */
    this.startTime = Date.now();

    /** Member ms is updated by tick() to a integer value reprsenting 
        the number of milliseconds between the epoch (January 1, 1970)
        and the current date and time of the system. */
    this.ms = this.startTime;
    this.last = this.startTime;  /** millis at last call to tick() */
    this.time = 0;               /** ms in floating point seconds not millis */

    /** Member dt is updated by tick() to an integer value representing
        the number of milliseconds since the last call to tick(). */
    this.dt = 0;
    this.delta = 0; /** dt in floating point seconds not millis */

    /** Member fps is updated by tick() to a floating point value representing
        frames per second, updated and averaged approximately once per second */
    this.fps = 0.0;

    /** Member frameCount is updated to an integer value representing the
        total number of calls to tick() since the clock was created. */
    this.frameCount = 0;

    /** The frameCounter member is a flag you can turn off if you don't need to
        calculate the frameCount or do the average FPS calculation every second */
    this.frameCounter = true;

    /** Private globals needed to calculcate/average fps over eachs second */
    var timeToUpdate = 0;
    var framesToUpdate = 0;

    /************************************************************************************
        The tick() method updates ALL the Clock members, which should only
        be read from and never written to manually. It is recommended that
        tick() is called from a callback loop using requestAnimationFrame

        Learn more: http://paulirish.com/2011/requestanimationframe-for-smart-animating/
    *************************************************************************************/
    this.tick = function () {
        /** This is a new frame with it's very own unique number */

        if (this.frameCounter) this.frameCount++;

        /** Set the private currentTime variable */
        this.ms = Date.now();

        /** Update time delta and immediately set last time to
            be as accurate as possible in our timings. */
        this.dt = this.ms - this.last;
        this.last = this.ms;

        /** Calculate floating-point delta and increment time member */
        this.delta = 0.001 * this.dt;
        this.time += this.delta;

        /** Calculate private temp variables for fps calculation */
        if (this.frameCounter) {
            timeToUpdate += this.dt;
            framesToUpdate++;
            if (timeToUpdate > 1000) {
                this.fps = Math.round((framesToUpdate * 1000) / timeToUpdate);
                framesToUpdate = 0;
                timeToUpdate = 0;
            }
        }
    }
}

このオブジェクトを使用する場合は、初期化関数で新しいクロック オブジェクトを作成するだけですclock = new Clock();。次にclock.tick()、各アニメーション呼び出しを呼び出します。clock.deltaその後、メンバーにアクセスしてclock.time、デルタと時間を秒単位の浮動小数点値として取得できます。ミリ秒単位で整数と同じになりますclock.dtclock.msを使用して fps にアクセスclock.fpsするか、設定して無効にすることもできますclock.frameCounter = false

于 2012-08-05T23:10:17.023 に答える
1

three.js時計を使用すると、アニメーションがスムーズになりました。強くお勧めします。他にもたくさんの優れたコードがあります。

于 2012-10-09T00:05:15.687 に答える