2

私はエンジニアで、現在 Red5 + Flash ゲームを Node.js + Easeljs html5 アプリケーションに移植しています。

基本的にRPGではなくボードゲームです。レイヤーシステムとは、機能に基づいて複数のキャンバスがあることを意味します。たとえば、画像付きの静的な背景ステージがあります。タイマーだけのレイヤーがあります。

デフォルトでは、すべてのキャンバス サイズは 1920x1080 ですが、必要に応じて解像度に合わせて縮小します。

最初のアプローチでは kinetic.js を使用しましたが、ゲームが複雑になるとパフォーマンスが低下しました。次にイーゼルに切り替えました。抽象化レベルが低いため、提供された堅牢な機能を使用するだけでなく、さらに機能を実装する方法を決定できます。

楽観視していたのですが、また動きが鈍くなってきたので、もっと深く調べて、細かい性能調整をしたいと思っています。(もちろん、Chrome ではすべて問題ありません。問題は Firefox ですが、最新のすべてのブラウザーでゲームがスムーズに動作する必要があります)。

メイン レイヤー (ステージ) はマップで、最大 30 個のコンテナーが含まれ、それぞれに複雑なカスタム シェイプ、最大 10 個の画像があります。コンテナーは、mouseover、out、click などのマウス イベントをリッスンしています。現在、たとえばマウスオーバーで、図形をグラデーションで塗りつぶします。

どういうわけか、キャッシュを使用すると、tutsのようにパフォーマンスがさらに低下するので、何かを台無しにしていると思います。

いくつかの高度な質問を集めました。

  1. 説明されている状況で、キャッシュをいつ、どのように使用できますか? 私はすでにinitでキャッシュを試し、他の色やグラデーションで塗りつぶした後にcacheUpdateを試しましたstage.update()。影響なし。

  2. ステージキャッシュを変更しない静的なものがある場合、そのレイヤーでは意味がありませんよね?

  3. 正確には何stage.update()をしますか?レイヤー全体の再描画をトリガーしますか? ドキュメントは、変更された場合に何らかのインテリジェントな場合に言及し、効果を再描画します。

  4. カスタム シェイプを新しい色またはグラデーションで塗りつぶしたい場合は、setFill メソッドを使用するだけでなく、そのグラフィックスを完全に再描画する必要がありますよね?

  5. イーゼルでは、たとえばコンテナーだけを再描画する可能性はないため、ステージ全体を更新するのではなく、変更された 1 つのコンテナーだけを更新するにはどうすればよいでしょうか? 私はキャッシュでこれを達成できると思っていました.すべてのコンテナをキャッシュし、変更されたものを更新するだけですが、この方法は私にとってはまったくうまくいきませんでした.

  6. ビットマップ画像をキャッシュするのは理にかなっていますか? コンテナにカスタムの形状と画像がある場合、どちらが優れていますか? コンテナーまたはコンテナー内の形状のみをキャッシュします。

    奇妙なバグ、または少なくとも興味深い手がかりを見つけました。キャンバスのレイヤーが完全に重なっています。下位レイヤーでは、マウスオーバーのリッスンはうまく機能していますが、クリックはまったく同じコンテナー/オブジェクトではありません。

  7. クリック リスナーを持つ重複したレイヤーへのクリック イベントの伝播を生成するにはどうすればよいですか? 単純な DOM、jquery で試してみましたが、イベント オブジェクトはキャンバス リスナーが取得したいものとはかけ離れていました。

手短に言えば、チューニングを試みたときに、私がすでにプレイしたメソッドと小道具はほとんど成功していません: cache(), updateCache(), update(), mouseEnabled, snapToPixel, clear(), autoClear, .enableMouseOveruseRAFsetFPS()

任意の回答、提案、出発点をいただければ幸いです。

アップデート:

この無料のボード ゲームは戦略ゲームであるため、30 までの領土を持つ世界地図に直面しています。カスタム シェイプはテリトリーであり、コンテナにはテリトリー シェイプとテリトリー上にあるアイコンが含まれています。このコンテナの重なりは最小限です。

マウス イベントの例として、ホバー効果があります。プレーヤーがテリトリー シェイプをナビゲートすると、シェイプの色やサイズが変更され、その場所の詳細を示すバブルが表示されます。

基本的に、一度に 1 ~ 3 個のコンテナーの最大量を変更できます (init フェーズを除く -> この時点ですべて)。FF ではアニメーションと色の変更が遅いだけでなく、リスナーの遅延も大きくなります。

変更ハンドラーを作成したので、stage.update()変更されたステージとアニメーションが実行されているステージ (tweenjs) のみをチェックします。

最初のアプローチでは、ゲーム中に少なくとも 1 回は必要となる可能性のあるすべての画像をコンテナーに配置するため、画像にのみ可視フラグを設定します (ベクターではありません)。

4

2 に答える 2

0

キャッシングについて: いくつかの奇妙なキャッシングの問題があり、キャッシング長方形の特定のサイズでパフォーマンスが低下する可能性があります: CreateJS / EaselJS 特定のサイズの形状での奇妙なパフォーマンス

(2) stage.update(); を呼び出す頻度によって異なります。

(3)

update メソッドが呼び出されるたびに、ステージはティック メソッド (例: BitmapAnimation) を公開しているすべての子孫をティックし、その表示リスト全体をキャンバスにレンダリングします。update に渡されたすべてのパラメーターは、すべての onTick ハンドラーに渡されます。

=>キャッシュされていない場合、すべてを再レンダリングします

(4) はい。

(5)いいえ(私は知りません)

(6) コンテナーのコンテンツが頻繁に変更されない場合は、コンテナー全体をキャッシュします。それ以外の場合、コンテナーはフレームごとに再構築されます。

質問があります: なぜ複数のキャンバスを使用するのですか? 何枚使いますか?複数のキャンバスを使用すると、ゲームの速度が低下する可能性があると想像できました。

合計で何個のスプライトを使用しますか?

于 2013-02-28T22:53:49.783 に答える
0

2: レイヤーまたはステージが変更されない場合は、そのレイヤーに対して stage.update() を呼び出さないでください (再レンダリングされず、CPU が大幅に低下します!) たとえば、グローバルな「stagechanged」を保持します。変数を変更し、何かが変更されたときにこれを true に設定します。

createjs.Ticker.addEventListener("tick",
    function() {
        if (stagechanged)
        {
            stagechanged = false;
            stage.update();
        }
    });

(または、「アップデート」に記載されているように、すでにこれを使用していますか?)

4: たとえば、塗りつぶしの色を更新する方法を見つけました :)

contaier1.shape1.graphics._fillInstructions[0].params[1] = '#FFFFFF';

(chrome デバッガーを使用して _fillInstructions 配列を調べ、どの配列位置に色が含まれているかを確認します)

5: コンテナを 1 つだけペイントする方法を見つけました :)

        //manual draw 1 component (!)
        var a = stage.canvas.getContext("2d");
        a.save();
        container1.updateContext(a);  //set position(x,y) on context
        container1.draw(a);
        a.restore();
于 2013-09-24T10:37:41.803 に答える