目标平滑以下

时间:2016-05-31 14:10:21

标签: javascript html5 canvas

我今天想知道如何使canvas元素顺利地跟随另一个canvas元素。例如,我正在尝试制作一个游戏,其中画布元素可以顺利地跟随玩家(可以使用W,A,S和D移动)。我有一个想法,使用毕达哥拉斯定理检查最接近的&从A点(画布元素)移动到B点(播放器)的最快方法。但是,我没有物理方法来做到这一点。有没有人有任何想法或答案,我怎么能使画布元素尽可能顺利地跟随玩家,以便最快地到达玩家?

这里有一个非常糟糕的关注方式的例子:

<!DOCTYPE html>

<html>

<head>
  <title>Target Following Test</title>
</head>

<body>
  <script src="https://code.jquery.com/jquery-2.1.0.js"></script>
  <center>
    <canvas id="canvas" width="800" height="500"></canvas>
  </center>
  <script>
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");
  var width = canvas.width;
  var height = canvas.height;
  var circle = function(x, y, radius, fillCircle, color) {
    ctx.beginPath();
    ctx.fillStyle = color;
    ctx.arc(x, y, radius, 0, Math.PI * 2, false);
    if (fillCircle) {
      ctx.fill();
    } else {
      ctx.stroke();
    }
  };
  var drawRect = function(x, y, color) {
    ctx.fillStyle = color;
    ctx.fillRect(x, y, 20, 20)
  }
  //Moving Obstacle
  var Obstacle = function(x, y) {
    this.x = x;
    this.y = y;
    this.vSpeed = 0;
    this.hSpeed = 0;
  }
  Obstacle.prototype.drawOb = function(color) {
    drawRect(this.x, this.y, "Red")
  }
  Obstacle.prototype.follow = function() {
    this.y += this.vSpeed
    this.x += this.hSpeed
    if (this.x < ball.x - 9) {
      this.hSpeed = 1;
    }
    if (this.x > ball.x - 10) {
      this.hSpeed = -1;
    }
    if (this.y > ball.y - 10) {
      this.vSpeed = -1;
    }
    if (this.y < ball.y - 9) {
      this.vSpeed = 1;
    }
  }
  Obstacle.prototype.checkCollision = function(direction) {
    return (ball.x - ball.radius < this.x + 20) &&
      (ball.x + ball.radius > this.x) &&
      (ball.y - ball.radius < this.y + 20) &&
      (ball.y + ball.radius > this.y);
  }
  // The Ball constructor
  var Ball = function() {
    this.x = 20
    this.y = 20
    this.xSpeed = 0;
    this.ySpeed = 0;
    this.radius = 10;
  };
  // Draw the ball at its current position
  Ball.prototype.draw = function() {
    circle(this.x, this.y, 10, true, "Black");
  };
  Ball.prototype.reposition = function(reX, reY) {
    this.x = reX;
    this.y = reY;
  }
  // Update the ball's position based on its speed
  Ball.prototype.move = function() {
    this.x += this.xSpeed;
    this.y += this.ySpeed;
    if (this.x < 11) {
      this.x = 11;
    } else if (this.x > width - 11) {
      this.x = width - 11;
    } else if (this.y < 11) {
      this.y = 11;
    } else if (this.y > height - 11) {
      this.y = height - 11;
    }
  };
  // Set the ball's direction based on a string
  Ball.prototype.setDirection = function(direction) {
    if (direction === "up") {
      this.xSpeed = 0;
      this.ySpeed = -2;
    } else if (direction === "down") {
      this.xSpeed = 0;
      this.ySpeed = 2;
    } else if (direction === "left") {
      this.xSpeed = -2;
      this.ySpeed = 0;
    } else if (direction === "right") {
      this.xSpeed = 2;
      this.ySpeed = 0;
    } else if (direction === "stop") {
      this.xSpeed = 0;
      this.ySpeed = 0;
    }
  };

  function simulate() {
    var prev_ball_x = ball.x;
    var prev_ball_y = ball.y;
    var prev_fol_x = follower.x;
    var prev_fol_y = follower.y;
    ball.move();
    follower.follow()
    if (follower.checkCollision()) {
      ball.setDirection('stop');
      follower.vSpeed = 0;
      follower.hSpeed = 0;
      follower.x = prev_fol_x;
      follower.y = prev_fol_y;
      ball.x = prev_ball_x;
      ball.y = prev_ball_y;
    }
  }

  function draw() {
    ctx.clearRect(0, 0, width, height);
    ball.draw();
    follower.drawOb();
    ctx.strokeRect(0, 0, width, height);
  }
  // An object to convert keycodes into action names
  var keyActions = {
    37: "left",
    38: "up",
    39: "right",
    40: "down"
  };
  // The keydown handler that will be called for every keypress
  $("body").keydown(function(event) {
    var direction = keyActions[event.keyCode];
    ball.setDirection(direction);
  });
  $("body").keyup(function(event) {
    ball.setDirection('stop');
  })
  setInterval(function() {
    // separate drawing and simulating phases
    simulate();
    draw();
  }, 10);
  // Create all the Objects!
  var ball = new Ball();
  var follower = new Obstacle(400, 100);
  </script>
</body>

</html>

1 个答案:

答案 0 :(得分:1)

注意:我还没有真正检查过您的代码...... 但希望我能正确理解你的问题。如果我这样做,解决方案可能非常简单。

最简单快捷的方法是将画布元素直线移动到播放器,而不需要Pythagoras先生的帮助。为此你需要知道玩家的位置(x,y)。

我从AS3问题中获取了一个缓动函数,但对JS来说也是如此:AS 3 simple ease

在每次更新时,让关注者轻松到达玩家的位置:

follower.x += (player.x - follower.x) / delay;
follower.y += (player.y - follower.y) / delay;

示例:Fiddle

这不是您的脚本的简易修复程序,但希望它有用