我已经实现了一个基本的Isometric tile引擎,可以通过用鼠标拖动地图来探索它。请看下面的小提琴并拖走:
细分的代码是(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/
答案 0 :(得分: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调用都是不必要的,除了用于画布绘制的调用,它会阻止抗锯齿。
是不是更短更甜?
P.S。等距实时浏览器游戏是一个很棒的主意。我有空的时候一定会尝试制作一个。