javascript - 为什么我的某些 Angular 在更改时不正确?

标签 javascript dom canvas angle

我用 JavaScript 和 DOM 编写了一个程序,显示一个球在盒子里弹跳;它是一个 Canvas 元素。唯一不能正常工作的是 Angular 。直到 Angular 很小时,这才明显,此时很明显球没有从盒子中正确弹回。 Angular 可能会逐渐接近一个盒子,然后非常陡峭地反弹回来。这似乎可能不是 angle-in=angle-out,而是前进的 Angular 是输出 Angular 。这相当于一个 Angular 和它的补充。这个问题似乎只发生在一半类型的弹跳上:它可能不会发生在一个方向的一面墙上,但会发生在另一个方向的墙上。

Illustration of possible problem : http://i.stack.imgur.com/WviEd.gif

代码测试能力的代码我都贴出来了,用的是渐变 Angular ,所以可以看出问题,但是问题的 Angular 在checkAngle功能。

<!doctype html>
<script src="code/chapter/15_game.js"></script>
<script src="code/game_levels.js"></script>
<script src="code/chapter/16_canvas.js"></script>

<canvas width="400" height="400"></canvas>
<script>
  var cx = document.querySelector("canvas").getContext("2d");

  var lastTime = null;
  function frame(time) {
    if (lastTime != null)
      updateAnimation(Math.min(100, time - lastTime) / 1000);
    lastTime = time;
    requestAnimationFrame(frame);
  }
  requestAnimationFrame(frame);
  var x = y = 200//, angle = 2 * Math.PI * Math.random();
  var angle = 2 * Math.PI / 40 + Math.PI;
  function checkAngle(angle) {
    if(x + 10 >= 400) {
      if(angle <= Math.PI)
        return angle = (Math.PI/2) + ((Math.PI / 2) - reduceAngle(angle));
      else if(angle > Math.PI)
        return angle = (3 * Math.PI / 2) - ((Math.PI / 2) - reduceAngle(angle));
    }else if(x - 10 <= 0) {
      if(angle <= Math.PI)
        return angle = Math.PI/2 - reduceAngle(angle);
      else if(angle > Math.PI)
        return angle = 3* Math.PI/2 + (Math.PI/2  - reduceAngle(angle));
    }else if(y - 10 <= 0) {
      if(angle >= 3 * Math.PI /2)
        return angle = Math.PI/2 - reduceAngle(angle);
      else if(angle < 3 * Math.PI/2)
        return angle = Math.PI - (Math.PI / 2 - reduceAngle(angle));
    }else if(y + 10 >= 400) {
      if(angle <= Math.PI/2)
        return angle = 2*Math.PI - (Math.PI / 2 - reduceAngle(angle));
      else if(angle > Math.PI/2)
        return angle = Math.PI + (Math.PI / 2 - reduceAngle(angle));
    }else
      return angle;
  }
  function reduceAngle(angle) {
    if(angle < Math.PI / 2) {
      return angle;
    }else{
      angle = angle - (Math.PI / 2);
      return reduceAngle (angle);
    }
  }
  function updateAnimation(step) {
    cx.clearRect(0, 0, 400, 400);
    cx.lineWidth = 4;
    cx.strokeRect(0, 0, 400, 400);
    angle = checkAngle(angle);
    x += Math.cos(angle) * step * 200;
    y += Math.sin(angle) * step * 200;
    cx.lineWidth = 2;
    cx.beginPath();
    cx.arc(x, y, 20, 0, 7);
    cx.stroke();
  }
</script>

最佳答案

在处理非旋转盒子中的反射时,您实际上不需要处理反射时的 Angular 。只需定义一个基于 Angular 初始向量。

var vector = {
      x: speed * Math.cos(angle),
      y: speed * Math.sin(angle)
    };

然后您只需分别检查 x 和 y 的边界并反转每个轴的斜率值:

  if (x - radius <= 0 || x + radius>= 400) {
    vector.x = -vector.x;      // reflect x
  }
  if (y - radius<= 0 || y + radius> 400) {
    vector.y = -vector.y;      // reflect y
  }

您始终可以通过添加另一个具有增量 Angular 的矢量来动态调整 Angular 。

如果您的弹跳框不会旋转 0°,请查看 this answer用于矢量反射。

例如

以您的代码为基础,可以这样实现:

var cx = document.querySelector("canvas").getContext("2d");
var lastTime = null;
var x, y;

// calculate an initial vector
var angle = 20 / 180 * Math.PI;   // angle -> radians
var speed = 5;
var vector = {
      x: speed * Math.cos(angle),
      y: speed * Math.sin(angle)
    };

x = y = 200;

function frame(time) {
  if (lastTime != null)
    updateAnimation(Math.min(100, time - lastTime) / 1000);
  lastTime = time;
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);


function checkAngle() {
  var dlt = 10 + 2 + 4;        //include radius and line-widths;
  if (x - dlt <= 0 || x + dlt >= 400) {
    vector.x = -vector.x;      // reflect x
  }
  if (y - dlt <= 0 || y + dlt > 400) {
    vector.y = -vector.y;      // reflect y
  }
}

function updateAnimation(step) {
  cx.clearRect(0, 0, 400, 400);
  cx.lineWidth = 4;
  cx.strokeRect(0, 0, 400, 400);
  
  x += vector.x;    // use our vector
  y += vector.y;
  checkAngle();     // test for hits
  
  cx.lineWidth = 2;
  cx.beginPath();
  cx.arc(x, y, 20, 0, 7);
  cx.stroke();
}
<canvas width="400" height="400"></canvas>

关于javascript - 为什么我的某些 Angular 在更改时不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30788092/

相关文章:

javascript - 在 Express.js 应用程序中提供客户端 JavaScript

javascript - 脚本70 : Permission denied IE9

javascript - 如何从 js 对象完全创建 HTML?

html - KineticJS 是否有对 SVG 的库支持?

javascript - 尝试将原始对象推送到数组,并稍后找到其索引

javascript - mapbox - 如何设置要素图层的弹出选项

javascript - 根据 &lt;iframe&gt; 的宽度和高度自动缩放内容

javascript - Wijmo 饼图对象引用错误?

javascript - Chrome : Dynamically created &lt;style&gt; tag does not have content?

php - "Mapping"指向字符的箭头