-1

現在 Canvas/Phaser でゲームを作成しており、次の問題の解決策を探しています。

X 軸上でのみ移動するオブジェクトから Y 軸の軌跡を作成する必要があるため、ほこりの軌跡を残しているように見えます。

しかし、バウンドするボールやその他の X/Y 移動オブジェクトからトレイルを作成している人を見ると、これは私が作成したいものではありません。

私は Phaser ゲーム フレームワークを使用してゲームを開発しています。このフレームワーク内に解決策がある場合、それは素晴らしいことですが、純粋なキャンバス ソリューション/アイデアで私を助けてくれれば、それも素晴らしいでしょう!

説明に適切な言葉を選んだことを願っています。以下に、希望する最終結果を視覚化する写真と小さなビデオを追加しました.

http://vrrsus.com/static/lastvoyage/web6.jpg

https://youtu.be/Fd7VOACEKig?t=22m32s

4

1 に答える 1

3

私はフェーザーを知りませんが、あなたはプレーンキャンバスの例も求めているので、ここにその例があります:

FIFO バッファ (配列)

FIFO バッファー (先入れ先出し) または遅延バッファーを使用できます。必要に応じて x および/または y の値をバッファに格納します。定義済みの最大値に従ってバッファがいっぱいになると、最初の値がスローされます。

これで末尾の値が得られ、必要に応じてレンダリングできるようになりました。

デモ

以下では x だけを保存します。尻尾にはグラデーションが定義されています。これにより、最良の/最も滑らかな結果が得られますが、fifo-buffer のエントリに一致する定義済みの色で配列を作成することもできます。

その場合、ソリッドのみ (アルファなし) をレンダリングする必要があることに注意してください。そうしないと、各線分間のトランジションが表示されます。

そして、それは基本的にそこにあるすべてです。レンダリングサイクルに合わせてください。

パフォーマンスのヒント:

  • y 方向に移動する場合は、グラデーションに従う必要があります。毎回新しいグラデーションを作成する代わりに、プレーヤーの頭に translate() を使用します。これにより、グラデーション ラインの定義も変換されます。
  • 多くの/長いテールが必要な場合は、型付き配列を使用するとパフォーマンスが向上します。これらはリスト/ノード配列よりも高速ですが、シフトが付属していないため、代わりに循環ポインターを使用する必要があります。
  • ビデオのゲームでは、1 つの尾を 1 回だけレンダリングし、それを他の頭に再利用します。
  • デモのようにグローにシャドウを使用する代わりに、グローが既に適用されている頭の画像を使用します。

var ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "#fff";

var fifo = [],           // fifo buffer to cycle older x values through
    max = 30,            // max positions stored in the buffer
    i = 0,               // just for demo, make x cycle on screen
    size = 8,            // draw size
    x = 300,             // x-pos from mousemove event
    y = 30,              // y-pos for player head
    
    // make gradient for the tail stroke:
    // Adjust range as needed
    gradient = ctx.createLinearGradient(0, 30, 0, 280);

// brightest color on top, transparent color at bottom.
gradient.addColorStop(0, "#ccd");
gradient.addColorStop(1, "rgba(200,200,240,0)");

// set up canvas
ctx.strokeStyle = gradient;
ctx.lineWidth = 10;
ctx.lineJoin = "round";
ctx.lineCap = "square";

// glow effect (because we can.. :) )
ctx.shadowColor = "rgba(255,255,255,0.5)";
ctx.shadowBlur = 20;

ctx.canvas.onmousemove = function(e) {
  var rect = this.getBoundingClientRect();
  x = e.clientX - rect.left;
};

// main loop -
(function loop() {

  // push new value(s) to fifo array (for demo, only x)
  fifo.push(x);
  
  // fifo buffer full? Throw out the first value
  if (fifo.length > max) fifo.shift();

  // render what we got;
  ctx.clearRect(0, 0, 600, 480);
  
  ctx.beginPath();
  ctx.moveTo(fifo[0], y + fifo.length * size);
  for(var t = 1; t < fifo.length; t++) {
    ctx.lineTo(fifo[t], y + (fifo.length - t) * size);
  }
  ctx.stroke();
  
  // draw main player head
  ctx.translate(x, y);
  ctx.rotate(0.25*Math.PI);
  ctx.fillRect(-size*0.5, -size*0.5, size*2, size*2);
  ctx.setTransform(1,0,0,1,0,0);
                 
  requestAnimationFrame(loop)
})();
canvas {background:#000}
<canvas width=600 height=360></canvas>

于 2015-05-12T05:00:35.747 に答える