鼠标点击角度

时间:2017-01-29 01:15:05

标签: javascript canvas

所以我创造了一个破砖机游戏,我需要一些帮助找到一个角度。

游戏几乎包含了一些块,当它们被击中时,会导致你失去1点生命值。游戏的目的是在击球之前用球击打它们以打破它们。如果球击中墙壁或街区,其轨迹将反转。

我希望用户能够在html画布中点击某人。然后,从画布底部的屏幕中心开始的球将遵循该角度。换句话说,用户将点击并且球将移动到该位置然后继续直到它击中某些东西。

我在这里有一些代码,但它可能不会对如何实现这个角度有所帮助。

   function animate(callback) {
  window.requestAnimationFrame(function() {
    window.setTimeout(callback, 1000/60);
  });
}

// canvas
  var canvas = document.getElementById('canvas');
  var context = canvas.getContext('2d');

// variables
var ballList = [];
var maxBalls = 1;
var checkAmount = 0;
var interval;
// onload/refresh/update/render
window.onload = function() {
  refresh();
}

function refresh() {
  update();
  render();
  animate(refresh);
}

function update() {
  document.addEventListener("click", spawn);
  for(var i = 0; i < ballList.length; i++) {
    ballList[i].move();
  }
}

function render() {
  context.fillStyle = '#000';
  context.fillRect(0, 0, canvas.width, canvas.height);
  for(var i = 0; i < ballList.length; i++) {
    ballList[i].show();
  }
}

// ball
function Ball() {
  this.x = canvas.width / 2;
  this.y = canvas.height - 50;
  this.width = 10;
  this.height = 10;
  this.xVel = 5;
  this.yVel = -10;

  this.show = function() {
    context.fillStyle = '#fff';
    context.fillRect(this.x, this.y, this.width, this.height);
  }

  this.move = function() {
    this.x += this.xVel;

    this.y += this.yVel;
    if(this.x >= canvas.width || this.x <= 0) {
      this.xVel *= -1;
    }
    if(this.y >= canvas.height || this.y <= 0) {
      this.yVel *= -1;
    }
  }
}

function spawn(event) {
  var xVel = (event.clientX - canvas.width / 2) / 90;
  if(ballList.length < maxBalls) {
    if(checkAmount < maxBalls) {
      interval = setInterval(function() {
        ballList.push(new Ball((event.clientX)));
        checkAmount++;
        if(checkAmount > maxBalls) {
          clearInterval(interval);
          checkAmount = 0;
        }
      }, 10);
    }

  }
}

提前致谢。

2 个答案:

答案 0 :(得分:3)

单位矢量

要将对象从一个点移动到另一个点,请使用向量。向量只是表示方向和速度的两个数字。它可以是极性的,因为一个数字是一个角度,另一个是距离,或者说是向量的笛卡尔,即x和y的变化量。

笛卡尔单位向量

为此您可以使用其中任何一种,但我更喜欢笛卡尔向量和一种称为单位向量的特定类型。单位矢量长1个单位。在计算机图形学中,单元通常是像素。

所以我们有一个重点从

开始
var startX = ?
var startY = ?

我们想要走向

var targetX = ?
var targetY = ?

我们希望单位矢量从开始到目标,

var vectorX = targetX - startX;
var vectorY = targetY - startY;

矢量的长度是两点之间的距离。这不是那么方便,所以我们将x和y除以长度

将其转换为单位向量
var length = Math.sqrt(vectorX * vectorX + vectorY * vectorY);
var unitVectX = vectorX / length;
var unitVectY = vectorY / length;

现在我们有一个像素长的单位向量。

球将在开始时开始

var ballX = startX
var ballY = startY

并将以每秒200像素的速度移动(假设为60fps)

var ballSpeed = 200 / 60;

现在移动球只需加速单位矢量乘以速度就可以了。直到下一帧。

 ballX += unitVectX * ballSpeed;
 ballY += unitVectY * ballSpeed;

使用笛卡儿可以很容易地从与x或y轴对齐的墙壁上反弹。

if(ballX + ballRadius > canvas.width){
      ballX = canvas.width - ballRadius;
      unitVectX = - unitVectX;
}

极坐标矢量

您也可以使用极坐标。当我们使用单位向量时,极性单位向量只需要方向。你使用trig函数atan2

 // get the direction in radians
 var polarDirection = Math.atan2(targetY - startY, targetX - startX); 

方向是弧度,许多人不喜欢弧度并转换为度数,但只要它朝着正确的方向,就没有必要知道它的走向。记住弧度很容易。 360度是2弧度180是1兰迪90是0.5。使用的实际单位是PI(很少有人知道pi的许多数字但你不需要)。所以270度是1.5弧度或数字1.5 * Math.PI。

角度从3点钟位置开始(指向屏幕右侧)为0弧度或0度,然后顺时针90度为6点钟位置为0.5弧度,而6点位置为180度1弧度,因此上。

要使用polarDirection移动球,您需要使用更多的trig。

 // do this once a frame
 ballX += Math.cos(polarDirection) * ballSpeed;
 ballY += Math.sin(polarDirection) * ballSpeed;
 // note that the cos and sin actually generate the cartesian unit vector

答案 1 :(得分:1)

/**
 * @param {number} x1 - x coordinate of the first point
 * @param {number} y1 - y coordinate of the first point
 * @param {number} x2 - x coordinate of the second point
 * @param {number} y2 - y coordinate of the second point
 * @return {number} - the angle (between 0 and 360)
 */
function getDirection(x1, y1, x2, y2) {
    // might be negative:
    var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
    // correct, positive angle:
    return (angle + 360) % 360;
}

我为了类似的目的编写了这个函数。不要忘记你可能不得不否定x。

在下图中,第一个点位于中心,第二个点位于圆圈的某个位置:

Angles as returned by getDirection