球在不同大小的画布javascript弹跳

时间:2016-05-01 17:50:33

标签: javascript html canvas

因此,对于我正在进行的项目,我想要四个不同大小的画布,四个球以相同的速度从墙上弹回。当所有的画布大小相同时,代码工作正常,但是一旦我尝试调整画布的高度和宽度,球就会继续在第一个画布大小的区域内反弹。我不确定我做错了什么,我真的很感激一些帮助。我对javascript很新。

这是HTML:

<canvas id="canvas1" width="200" height="200"></canvas>
<canvas id="canvas2" width="200" height="400"></canvas>
<canvas id="canvas3" width="400" height="200"></canvas>
<canvas id="canvas4" width="200" height="200"></canvas>

这是Javascript:

var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
var x = canvas.width/2;
var y = canvas.height-30;
var dx = -2;
var dy = 2;
var ballRadius = 10;

var canvas2 = document.getElementById("canvas2");
var ctx2 = canvas2.getContext("2d");
var x2 = canvas2.width/2;
var y2 = canvas2.height-30;

var canvas3 = document.getElementById("canvas3");
var ctx3 = canvas3.getContext("2d");
var x3 = canvas3.width/2;
var y3 = canvas3.height-30;

var canvas4 = document.getElementById("canvas4");
var ctx4 = canvas4.getContext("2d");
var x4 = canvas4.width/2;
var y4 = canvas4.height-30;

function drawBall() {
    ctx.beginPath();
    ctx.arc(x, y, ballRadius, 0, Math.PI*2);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();

    ctx2.beginPath();
    ctx2.arc(x2, y2, ballRadius, 0, Math.PI*2);
    ctx2.fillStyle = "#0095DD";
    ctx2.fill();
    ctx2.closePath();

    ctx3.beginPath();
    ctx3.arc(x3, y3, ballRadius, 0, Math.PI*2);
    ctx3.fillStyle = "#0095DD";
    ctx3.fill();
    ctx3.closePath();

    ctx4.beginPath();
    ctx4.arc(x4, y4, ballRadius, 0, Math.PI*2);
    ctx4.fillStyle = "#0095DD";
    ctx4.fill();
    ctx4.closePath();
}

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
    ctx3.clearRect(0, 0, canvas3.width, canvas3.height);
    ctx4.clearRect(0, 0, canvas4.width, canvas4.height);

    drawBall();
    x += dx;
    y += dy;
    x2 += dx;
    y2 += dy;
    x3 += dx;
    y3 += dy;
    x4 += dx;
    y4 += dy;

    if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {
        dy = -dy; }
    if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
        dx = -dx; }

    if(y2 + dy > canvas2.height-ballRadius || y2 + dy < ballRadius) {
        dy = -dy; }
    if(x2 + dx > canvas2.width-ballRadius || x2 + dx < ballRadius) {
        dx = -dx; }

    if(y3 + dy > canvas3.height-ballRadius || y3 + dy < ballRadius) {
        dy = -dy; }
    if(x3 + dx > canvas3.width-ballRadius || x3 + dx < ballRadius) {
        dx = -dx; }

    if(y4 + dy > canvas4.height-ballRadius || y4 + dy < ballRadius) {
        dy = -dy; }
    if(x4 + dx > canvas4.width-ballRadius || x4 + dx < ballRadius) {
        dx = -dx; }
    }
    setInterval(draw, 10);

3 个答案:

答案 0 :(得分:2)

问题在于所有球都具有相同的速度(dx,dy),所以当其中一个球击中墙壁时,它会导致所有球都反弹。要修复它,你需要为每个球(dx2,dy2等)提供速度

答案 1 :(得分:2)

在你的代码中,球共享相同的速度值(dx,dy),这将导致所有球的行为方式相同。

解决问题并使代码更清晰(/可伸缩)的一种方法是创建一个用于处理绘图的类,以及每个画布的该类的不同实例,确保画布x,y,力度和其他变量是分开的

我从@JupeP派了一个小提琴,在那里我通过传递单独的Canvas id为每个画布创建一个基类和新实例。

http://jsfiddle.net/jtjpv2bf/1/

<canvas id="myCanvas" width="800" height="400" style="border:1px solid #000000;"></canvas>
<canvas id="myCanvas1" width="400" height="400" style="border:1px solid #000000;"></canvas>
<canvas id="myCanvas2" width="200" height="200" style="border:1px solid #000000;"></canvas>
<canvas id="myCanvas3" width="600" height="300" style="border:1px solid #000000;"></canvas>

window.requestAnimFrame =
  window.requestAnimationFrame ||
  window.webkitRequestAnimationFrame ||
  window.mozRequestAnimationFrame ||
  function(callback) {
    window.setTimeout(callback, 1000 / 60);
  };

AnimationHandler = function(canvasId) {

  var canvas, WIDTH, HEIGHT, 
      ctx, dx, dy, x, y;

  function init() {
    // find the <canvas> element
    canvas = document.getElementById(canvasId);
    WIDTH = canvas.width;
    HEIGHT = canvas.height;
    // get canvas context
    ctx = canvas.getContext("2d");
    (...)
    }

  AnimationHandler.prototype = {}
  AnimationHandler.prototype.constructor = init;
  ...
  return init();
};

new AnimationHandler("myCanvas");
new AnimationHandler("myCanvas1");
new AnimationHandler("myCanvas2");
new AnimationHandler("myCanvas3");

<强> RequestAnimationFrame

另外,请考虑使用requestAnimationFrame而不是setInterval。它是浏览器用于并发动画的优化API,如果不在活动标签中则会暂停(节省电池/提高性能)。

Paul Irish解释说here

答案 2 :(得分:0)

修改 我的代码不起作用,但您仍然可以将值与比例相提并论,并为每个dx和dy使用不同的变量


不是使用dx和dy来表示每个球的速度,而是使用相应的画布和球数:

var $template; // undefined
...
_.each($template.get(0)....) // $template is still undefined