在鼠标单击时,对象移动到X / Y坐标时更新路径

时间:2017-10-03 06:50:27

标签: javascript canvas

编辑:

你好,

此代码使玩家对象在鼠标点击时移动到X / Y坐标。我可以在代码中做什么,以便我可以更新新目的地,即使目标没有达到目标。通过这种方式,我可以让玩家能够自由地点击鼠标?

我仍在学习javascript中的基础知识,所以我不知道该怎么做。我很感激帮助,如果有人知道如何做到这一点,并可能简化代码?



var ctx = demo.getContext('2d'),
  x, y, x1, y1, x2 = 0,
  y2 = 0, /// positions
  f = 0, /// "progress"
  speed, /// speed based on dist/steps
  dist, /// distance between points
  steps = 3; /// steps (constant speed)

SPEED.onchange = function() {
  steps = val.innerHTML = SPEED.value
}

demo.onclick = function(e) {

  /// if we are moving, return
  if (f !== 0) return;

  /// set start point
  x1 = x2;
  y1 = y2;

  /// get and adjust mouse position    
  var rect = demo.getBoundingClientRect();
  x2 = e.clientX - rect.left,
    y2 = e.clientY - rect.top;

  /// calc distance
  var dx = x2 - x1,
    dy = y2 - y1;

  dist = Math.abs(Math.sqrt(dx * dx + dy * dy));

  /// speed will be number of steps / distance
  speed = steps / dist;

  /// move player
  loop();
}

function loop() {

  /// clear current drawn player
  ctx.fillStyle = 'rgba(160, 160, 160, 0.5)';
  ctx.fillRect(0, 0, demo.width, demo.height);
  ctx.fillStyle = '#007';

  /// move a step
  f += speed;

  /// calc current x/y position
  x = x1 + (x2 - x1) * f;
  y = y1 + (y2 - y1) * f;

  /// at goal? if not, loop
  if (f < 1) {
    /// draw the "player"
    ctx.fillRect(x - 4, y - 4, 8, 8);

    requestAnimationFrame(loop);
  } else {
    /// draw the "player"
    ctx.fillRect(x2 - 4, y2 - 4, 8, 8);

    /// reset f so we can click again
    f = 0;
  }
}
&#13;
body {
  background: #333;
  color: #aaa;
  font: 14px sans-serif;
}

canvas {
  background: rgba(255, 255, 255, 0.1);
}

#info {
  position: fixed;
  left: 80px;
  top: 190px;
  font-size: 20px;
  color: #fff;
  z-index: -1;
}
&#13;
<canvas id="demo" width=400 height=400></canvas>
<br> Speed <input type="range" min=1 max=20 value=3 id="SPEED">
<span id="val">3</span>
<div id="info">Click somewhere on canvas</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

我认为您的挑战是,当触发新点击时,很难将新距离合并到当前f

&#13;
&#13;
var ctx = demo.getContext('2d'),
    x, y, x1, y1, x2 = 0, y2 = 0, /// positions
    f = 0,                        /// "progress remaining"
    speed,                        /// speed based on dist/steps
    dist,                         /// distance between points
    steps = 3;                    /// steps (constant speed)

SPEED.onchange = function() {steps = val.innerHTML = SPEED.value}

demo.onclick = function(e) {

    /// if we are currently moving, note it
    var isLooping = f > 0;
    
    /// set start point to (x,y) if moving, or (x2, y2) if static
    x1 = isLooping ? x : x2;
    y1 = isLooping ? y : y2;

    /// get and adjust mouse position    
    var rect = demo.getBoundingClientRect();
    x2 = e.clientX - rect.left,
    y2 = e.clientY - rect.top;

    /// calc distance
    var dx = x2 - x1,
        dy = y2 - y1;
    
    dist = Math.abs(Math.sqrt(dx * dx + dy * dy));

    /// speed will be number of steps / distance
    speed = steps / dist;
    // 100% work remaining
    f = 1;
    /// if not currently moving, trigger the loop
    !isLooping && loop();
}

function loop() {

    /// clear current drawn player
    ctx.fillStyle = 'rgba(160, 160, 160, 0.5)';
    ctx.fillRect(0, 0, demo.width, demo.height);
    ctx.fillStyle = '#007';
    
    /// move a step
    f -= speed;

    /// calc current x/y position
    x = x1 + (x2 - x1) * (1 - f);
    y = y1 + (y2 - y1) * (1 - f);    

    /// at goal? if not, loop
    if (f > 0) {
        /// draw the "player"
        ctx.fillRect(x - 4, y - 4, 8, 8);

        requestAnimationFrame(loop);
    } else {
        /// draw the "player"
        ctx.fillRect(x2 - 4, y2 - 4, 8, 8);

        /// reset f so we can click again
        f = 0;
    }
}
&#13;
body {
    background:#333;
    color:#aaa;
    font:14px sans-serif;
}
canvas {background:rgba(255,255,255,0.1);}
#info {
    position:fixed;
    left:80px;
    top:190px;
    font-size:20px;
    color:#fff;
    z-index:-1;
}
&#13;
<canvas id="demo" width=400 height=400></canvas>
<br>
Speed <input type="range" min=1 max=20 value=3 id="SPEED">
    <span id="val">3</span>
    <div id="info">Click somewhere on canvas</div>
&#13;
&#13;
&#13;

或者参考这个更新的JSFiddle:http://jsfiddle.net/p963yquu/

主要概念变化是f现在意味着剩余进度(从1开始并向下计数到0)。这样,您可以随时轻松地将进度重置为单击时剩余的100%。否则会对您当前的代码进行细微更改。