2

マップをマウスでドラッグして探索できる基本的なアイソメ タイル エンジンを実装しました。以下のフィドルを見て、ドラッグしてください:

http://jsfiddle.net/kHydg/14/

分解されたコードは次のとおりです (CoffeeScript):

ドロー機能

draw = ->
  requestAnimFrame draw
  canvas.width = canvas.width

  for row in [0..width]
    for col in [0..height]
      xpos = (row - col) * tileHeight + width
      xpos += (canvas.width / 2) - (tileWidth / 2) + scrollPosition.x
      ypos = (row + col) * (tileHeight / 2) + height + scrollPosition.y
      context.drawImage(defaultTile, Math.round(xpos), Math.round(ypos), tileWidth, tileHeight)

マウスドラッグスクロールコントロール

scrollPosition =
  x: 0
  y: 0

dragHelper = 
  active: false
  x: 0
  y: 0


window.addEventListener 'mousedown', (e) =>
  handleMouseDown(e)
, false

window.addEventListener 'mousemove', (e) =>
  handleDrag(e)
, false

window.addEventListener 'mouseup', (e) =>
  handleMouseUp(e)
, false

handleDrag = (e) =>
  e.preventDefault()
  if dragHelper.active
    x = e.clientX
    y = e.clientY
    scrollPosition.x -= Math.round((dragHelper.x - x) / 28)
    scrollPosition.y -= Math.round((dragHelper.y - y) / 28)

handleMouseUp = (e) =>
  e.preventDefault()
  dragHelper.active = false

handleMouseDown = (e) =>
  e.preventDefault()
  x = e.clientX
  y = e.clientY
  dragHelper.active = true
  dragHelper.x = x
  dragHelper.y = y

問題

フィドルからわかるように、ドラッグ操作は問題ありませんが、完全ではありません。ドラッグ操作をよりスムーズにするためにコードを変更するにはどうすればよいですか? 私が望むのは、ドラッグしている間、クリックしたマップのポイントがマウスポイントの下に留まるようにすることです。ここで行ったのと同じ: http://craftyjs.com/demos/isometric/

4

1 に答える 1

1

多くのライブラリがこのようなことに役立ちます。いくつかの理由から、d3 のデータ操作機能を使用することをお勧めします。

まず、d3 では、オブジェクトの原点が保存され、ドラッグの開始時に原点に対するマウスの位置が計算されるドラッグ動作があります。次に、マウスの絶対位置を使用してオブジェクトの位置を決定し、相対変更を使用したときに発生する増分エラーを回避できます。上記のように、丸めを開始するとさらに悪化します。

dragMap = (d) ->  
  d.x = d3.event.x # d3.event.x, y are computed relative to the origin for you!
  d.y = d3.event.y 

dragBehavior = d3.behavior.drag()
  .origin(Object) # equivalent to (d) -> d 
  .on("drag", dragMap)

d3.select(canvas)
  .datum(x: 0, y: 0)  # Load your canvas with an arbitary origin
  .call(dragBehavior) # And now you can drag it!

次に、d3 の線形またはその他の数値スケールを使用することで、特にあちこちで行う必要がある場合にエラーが発生しやすい典型的な描画計算を自分で行うことを回避できます。以前はドラッグを 28 倍にスケーリングしていました。現在のアプローチでは不要ですが、描画アルゴリズムを変更してピクセルではなくタイルを使用する場合、このスケールを変更すると、マウスのピクセルがタイル サイズに自動的に変換されます。

pixelToTile = d3.scale.linear()
  .domain([0, 1])
  .range([0, 1])  

これは、d3 ヘルプを使用してやり直したフィドルです。dragHelper や余分なコードは必要ありません。すべての Math.round 呼び出しも不要です。キャンバス描画用のものを除き、アンチエイリアシングを防ぎます。

http://jsfiddle.net/kHydg/23/

それははるかに短くて甘いではありませんか?

PS Isometric リアルタイム ブラウザ ゲームは素晴らしいアイデアです。時間があれば必ず作ってみます。

于 2012-09-28T19:48:18.460 に答える