Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 击球后停球_Javascript_Canvas - Fatal编程技术网

Javascript 击球后停球

Javascript 击球后停球,javascript,canvas,Javascript,Canvas,我想知道当一个移动的球碰到一个物体时,你怎么能阻止它。我用帆布做这个。 这里有一个小例子: <!DOCTYPE html> <html> <head> <title>Ball Race</title> </head> <body> <script src="https://code.jquery.com/jquery-2.1.0.js"></s

我想知道当一个移动的球碰到一个物体时,你怎么能阻止它。我用帆布做这个。 这里有一个小例子:

    <!DOCTYPE html>
  <html>
  <head>
      <title>Ball Race</title>
  </head>

  <body>

      <script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<canvas id="canvas" width="800" height="200"></canvas>
      <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) {
  ctx.beginPath();
  ctx.arc(x, y, radius, 0, Math.PI * 2, false);
  if (fillCircle) {
    ctx.fill();
  } else {
    ctx.stroke();
  }
};

var drawRect = function (x, y) {
ctx.fillRect(x, y, 20, 20)
}

var Object = function (xPos, yPos) {
this.x = xPos;
this.y = yPos;
}
// The Ball constructor
var Ball = function () {
  this.x = width / 2;
  this.y = height / 2;
  this.xSpeed = 0;
  this.ySpeed = 0;
  this.radius = 10;
};

// 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;
  }
};

// Draw the ball at its current position
Ball.prototype.draw = function () {
  circle(this.x, this.y, 10, true);
};

Object.prototype.draw = function () {
    drawRect(this.x, this.y)
}

//collision types



Object.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)
      ;
}

function draw() {
    ctx.clearRect(0, 0, width, height);

    ball.draw();
    object1.draw();
    object2.draw();
    object3.draw();
    object4.draw();
    object5.draw();

    ctx.strokeRect(0, 0, width, height);
}

function simulate() {
  for (z = 0; z < 5; z++) {
    var prev_ball_x = ball.x;
    var prev_ball_y = ball.y;
    ball.move();
    // handle collision here
    if (object1.checkCollision() || object2.checkCollision() || object3.checkCollision() || object4.checkCollision() || object5.checkCollision()) {
        ball.setDirection('stop');
        // reset ball's position so they do not overlap
        ball.x = prev_ball_x;
        ball.y = prev_ball_y;
    }

  }

  if ($("body").keyup()) {
      ball.setDirection('stop');
    }
}

setInterval(function () {
    // separate drawing and simulating phases
    simulate();
    draw();
}, 30);

// Set the ball's direction based on a string
Ball.prototype.setDirection = function (direction) {
  if (direction === "up") {
     this.xSpeed = 0;
     this.ySpeed = -1;
  } else if (direction === "down") {
     this.xSpeed = 0;
     this.ySpeed = 1;
  } else if (direction === "left") {
     this.xSpeed = -1;
     this.ySpeed = 0;
  } else if (direction === "right") {
     this.xSpeed = 1;
     this.ySpeed = 0;
  } else if (direction === "stop") {
     this.xSpeed = 0;
     this.ySpeed = 0;
  }
};

// Create the ball object
var ball = new Ball();
var object1 = new Object(50, 0);
var object2 = new Object(50, 20);
var object3 = new Object(50, 40);
var object4 = new Object(50, 60);
var object5 = new Object(50, 80);


// An object to convert keycodes into action names
var keyActions = {
  32: "stop",
  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);
});



       </script>
   </body>
   </html>

球赛
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var width=canvas.width;
var height=canvas.height;
变量圆=函数(x、y、半径、圆角圆){
ctx.beginPath();
弧(x,y,半径,0,数学π*2,假);
如果(填充圆){
ctx.fill();
}否则{
ctx.stroke();
}
};
var drawRect=函数(x,y){
ctx.fillRect(x,y,20,20)
}
var对象=函数(xPos、yPos){
x=xPos;
y=yPos;
}
//球构造函数
var Ball=函数(){
这.x=宽度/2;
这.y=高度/2;
this.xSpeed=0;
这个.ySpeed=0;
这个半径=10;
};
//根据球的速度更新球的位置
Ball.prototype.move=函数(){
this.x+=this.xSpeed;
this.y+=this.y速度;
如果(此.x<11){
这个x=11;
}else if(this.x>宽度-11){
x=宽度-11;
}否则,如果(此.y<11){
这个y=11;
}else if(this.y>高度-11){
y=高度-11;
}
};
//在当前位置绘制球
Ball.prototype.draw=函数(){
圆圈(这个.x,这个.y,10,真);
};
Object.prototype.draw=函数(){
drawRect(this.x,this.y)
}
//碰撞类型
Object.prototype.checkCollision=函数(方向){
返回(ball.x-ball.radiusthis.x)
&&(ball.y-ball.radiusthis.y)
;
}
函数绘图(){
ctx.clearRect(0,0,宽度,高度);
ball.draw();
object1.draw();
object2.draw();
object3.draw();
object4.draw();
object5.draw();
ctx.冲程(0,0,宽度,高度);
}
函数模拟(){
对于(z=0;z<5;z++){
var prev_ball_x=ball.x;
var prev_ball_y=ball.y;
ball.move();
//在这里处理碰撞
if(object1.checkCollision()| | object2.checkCollision()| | object3.checkCollision()| | object4.checkCollision()| | object5.checkCollision()){
球。设置方向(“停止”);
//重置球的位置,使它们不会重叠
ball.x=上一个球;
ball.y=上一个ball\u y;
}
}
if($(“body”).keyup(){
球。设置方向(“停止”);
}
}
setInterval(函数(){
//分别绘制和模拟阶段
模拟();
draw();
}, 30);
//根据线设置球的方向
Ball.prototype.setDirection=功能(方向){
如果(方向==“向上”){
this.xSpeed=0;
这个.ySpeed=-1;
}否则如果(方向==“向下”){
this.xSpeed=0;
该速度为1;
}否则如果(方向==“左”){
this.xSpeed=-1;
这个.ySpeed=0;
}否则,如果(方向==“右”){
this.xSpeed=1;
这个.ySpeed=0;
}否则如果(方向==“停止”){
this.xSpeed=0;
这个.ySpeed=0;
}
};
//创建球对象
var ball=新的ball();
var object1=新对象(50,0);
var object2=新对象(50,20);
var object3=新对象(50,40);
var object4=新对象(50,60);
var object5=新对象(50,80);
//将键代码转换为操作名称的对象
var键操作={
32:“停止”,
37:“左”,
38:“向上”,
39:“对”,
40:“向下”
};
//每次按键都将调用的keydown处理程序
$(“body”).keydown(函数(事件){
var direction=keyActions[event.keyCode];
球。设定方向(方向);
});

我知道可以将速度设置为0,但设置间隔会自动更新速度,以便再次移动。我如何解决这个问题使球停止?

碰撞时可以将速度设置为0。但请注意,对象将保持重叠,因此即使用户尝试移动球,碰撞检查也会将速度设置回0

我也会把这两个音程合并成一个音程,因为第二个音程做了很多工作 不必要的工作

这是编写物理引擎时要迈出的第一大步。幸运的是,这里只有球在移动,并不是基于物理原理,所以我们可以通过在碰撞时将球重新定位到非重叠位置来进行一些“破解”

Object.prototype.checkCollision = function (direction) {
    var colx = (ball.x-ball.radius<this.x&&ball.x+ball.radius>this.x)||(ball.x-ball.radius<this.x+20&&ball.x+ball.radius>this.x+20);
    var coly = (ball.y-ball.radius<this.y&&ball.y+ball.radius>this.y)||(ball.y-ball.radius<this.y+20&&ball.y+ball.radius>this.y+20);

    // it really just checks but takes no action
    return colx&&coly;
}

// ...

function draw() {
    ctx.clearRect(0, 0, width, height);

    ball.draw();
    object.draw();
    drawLives();

    ctx.strokeRect(0, 0, width, height);
}

function simulate() {
    var prev_ball_x = ball.x;
    var prev_ball_y = ball.y;
    ball.move();
    // handle collision here
    if (object.checkCollision()) {
        ball.setDirection('stop');
        // reset ball's position so they do not overlap
        ball.x = prev_ball_x;
        ball.y = prev_ball_y;
    }
}

setInterval(function () {
    // separate drawing and simulating phases
    simulate();
    draw();
}, 30);
当从顶部接近时,会有一个间隙,因为球会重新定位到前一帧中的位置。通过正确的重新定位,您可以做得更好

这很难,因为有很多方面需要考虑

是的,的确如此。这就是为什么我建议这个“移到以前的位置”黑客

通过采取更多的小步骤,您可以使这种粗糙的方法看起来更好。您可以将ball.speed设置为1而不是5,并在for循环中执行五次
simulate

编辑:更改后的完整代码

球赛
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var width=canvas.width;
var height=canvas.height;
var=3;
var=function(){
ctx.font=“20px快递”;
ctx.fillStyle=“黑色”;
ctx.textAlign=“左”;
ctx.textb基线=“顶部”;
ctx.fillText(“生命左:”+生命,10,10);
};
变量圆=函数(x、y、半径、圆角圆){
ctx.beginPath();
弧(x,y,半径,0,数学π*2,假);
如果(填充圆){
ctx.fill();
}否则{
ctx.stroke();
}
};
var drawRect=函数(x,y){
ctx.fillRect(x,y,20,20)
}
变量对象=函数(){
这.x=宽度/4;
这.y=高度/4;
}
//球构造函数
var Ball=函数(){
这.x=宽度/2;
这.y=高度/2;
this.xSpeed=0;
这个.ySpeed=0;
这个半径=10;
};
//根据球的速度更新球的位置
Ball.prototype.move=函数(){
this.x+=this.xSpeed;
this.y+=this.y速度;
如果(此.x<11){
这个x=11;
}else if(this.x>宽度-11){
x=宽度-11;
}否则,如果(此.y<11){
这个y=11;
}否则如果(this.y>hei
Object.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)
      ;
}
<!DOCTYPE html>
  <html>
  <head>
      <title>Ball Race</title>
  </head>

  <body>

      <script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<canvas id="canvas" width="800" height="200"></canvas>
      <script>

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
var lives = 3;

var drawLives = function () {
    ctx.font = "20px Courier";
    ctx.fillStyle = "Black";
    ctx.textAlign = "left";
    ctx.textBaseline = "top";
    ctx.fillText("Lives left: " + lives, 10, 10);
  };

var circle = function (x, y, radius, fillCircle) {
  ctx.beginPath();
  ctx.arc(x, y, radius, 0, Math.PI * 2, false);
  if (fillCircle) {
    ctx.fill();
  } else {
    ctx.stroke();
  }
};

var drawRect = function (x, y) {
ctx.fillRect(x, y, 20, 20)
}

var Object = function () {
this.x = width / 4;
this.y = height / 4;
}
// The Ball constructor
var Ball = function () {
  this.x = width / 2;
  this.y = height / 2;
  this.xSpeed = 0;
  this.ySpeed = 0;
  this.radius = 10;
};

// 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;
  }
};

// Draw the ball at its current position
Ball.prototype.draw = function () {
  circle(this.x, this.y, 10, true);
};

Object.prototype.draw = function () {
    drawRect(this.x, this.y)
}

//collision types



Object.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)
      ;
}


// Set the ball's direction based on a string
Ball.prototype.setDirection = function (direction) {
  if (direction === "up") {
     this.xSpeed = 0;
     this.ySpeed = -1;
  } else if (direction === "down") {
     this.xSpeed = 0;
     this.ySpeed = 1;
  } else if (direction === "left") {
     this.xSpeed = -1;
     this.ySpeed = 0;
  } else if (direction === "right") {
     this.xSpeed = 1;
     this.ySpeed = 0;
  } else if (direction === "stop") {
     this.xSpeed = 0;
     this.ySpeed = 0;
  }
};

// Create the ball object
var ball = new Ball();
var object = new Object();
// An object to convert keycodes into action names
var keyActions = {
  32: "stop",
  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);
});

function draw() {
    ctx.clearRect(0, 0, width, height);

    ball.draw();
    object.draw();
    drawLives();

    ctx.strokeRect(0, 0, width, height);
}

function simulate() {
    for (var i = 0; i < 5; i++) {
      var prev_ball_x = ball.x;
      var prev_ball_y = ball.y;
      ball.move();
      // handle collision here
      if (object.checkCollision()) {
          ball.setDirection('stop');
          // reset ball's position so they do not overlap
          ball.x = prev_ball_x;
          ball.y = prev_ball_y;
      }
    }
}

setInterval(function () {
    // separate drawing and simulating phases
    simulate();
    draw();
}, 30);

       </script>
   </body>
   </html>