【问题标题】:breakout collision detection突破碰撞检测
【发布时间】:2017-01-31 16:33:20
【问题描述】:

我正在使用 Javascript 编写一个 Breakout 游戏。我学习了 MDN 教程和另一个教程,并尝试使用 OOP 方法修改原始教程。到目前为止,一切正常,除了与桨的碰撞检测。这没有发生。这是为什么?这是我的代码。有人可以帮忙吗?谢谢!

var canvas = document.getElementById('game');
var theLoop;
var paddleSpeed = 4;

//OBJECTS
//Game
function Game() {
  this.width = canvas.width;
  this.height = canvas.height;
  this.ctx = canvas.getContext('2d');
  this.ctx.fillStyle = "white";
  this.p = new Paddle(0, 130);
  this.p.x = (this.width - this.p.width) / 2;
  this.keys = new Keylistener();
  this.ball = new Ball();
  this.ball.x = this.width / 2;
  this.ball.y = 125;
  this.ball.vy = Math.floor(Math.random() * 12 - 6);  
  this.ball.vx = 7 - Math.abs(this.ball.vy);
}

Game.prototype.draw = function() {
  this.ctx.clearRect(0, 0, this.width, this.height);
  this.p.draw(this.ctx);
  this.ball.draw(this.ctx);
};

Game.prototype.update = function() {
  if (this.paused) return;
  this.ball.update();
  //Right Paddle's Directions
  if (this.keys.isPressed(37)) { // LEFT
    this.p.x = Math.max(0, this.p.x - paddleSpeed);
  } else if (this.keys.isPressed(39)) { // RIGHT
        
    this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
  }


  if (this.ball.x < this.ball.ballRadius || this.ball.x > this.width - this.ball.ballRadius) { //LEFT & RIGHT
    this.ball.vx = -this.ball.vx;
  }
  if (this.ball.y < this.ball.ballRadius) { //TOP
    this.ball.vy = -this.ball.vy;
  } else if (this.ball.y > this.height - this.ball.ballRadius) {
    if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {
      this.ball.vy = -this.ball.vy;
      console.log('hit');
    } else {
      //      console.log(this.ball.x);
    }
  }
};

/////Paddle
function Paddle(x, y) {
  this.x = x;
  this.y = y;
  this.width = 30;
  this.height = 5;
  this.score = 0;
}

Paddle.prototype.draw = function(p) {
  p.fillRect(this.x, this.y, this.width, this.height);
};

///KEY LISTENER
function Keylistener() {
  this.pressedKeys = [];
  this.keydown = function(e) {
    this.pressedKeys[e.keyCode] = true;
  };
  this.keyup = function(e) {
    this.pressedKeys[e.keyCode] = false;
  };
  document.addEventListener("keydown", this.keydown.bind(this));
  document.addEventListener("keyup", this.keyup.bind(this));
}

Keylistener.prototype.isPressed = function(key) {
  return this.pressedKeys[key] ? true : false;
};

Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
  document.addEventListener("keypress", function(e) {
    if (e.keyCode == keyCode) callback(e);
  });
};

///BALL
function Ball() {
  this.x = 0;
  this.y = 0;
  this.vx = 0;
  this.vy = 0;
  this.ballRadius = 5;
}

Ball.prototype.update = function() {
  this.x += this.vx;
  this.y += this.vy;
};

Ball.prototype.draw = function(p) {
  p.beginPath();
  p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
  p.fill();
  p.closePath();
};


//Initialize the game
var game = new Game();

//the Main Engine
function mainLoop() {
  theLoop = setInterval(function() {
    game.update();
    game.draw();
  }, 33.3333);
}

//calling the Main Engine
mainLoop();
#game {
  width: 800px;
  height: 400px;
  background-color: #353535;
}
&lt;canvas id="game"&gt;&lt;/canvas&gt;

【问题讨论】:

    标签: javascript collision detection breakout


    【解决方案1】:

    var canvas = document.getElementById('game');
    var theLoop;
    var paddleSpeed = 4;
    
    //OBJECTS
    //Game
    function Game() {
      this.width = canvas.width;
      this.height = canvas.height;
      this.ctx = canvas.getContext('2d');
      this.ctx.fillStyle = "white";
      this.p = new Paddle(0, 130);
      this.p.x = (this.width - this.p.width) / 2;
      this.keys = new Keylistener();
      this.ball = new Ball();
      this.ball.x = this.width / 2;
      this.ball.y = 125;
      this.ball.vy = Math.floor(Math.random() * 12 - 6);  
      this.ball.vx = 7 - Math.abs(this.ball.vy);
    }
    
    Game.prototype.draw = function() {
      this.ctx.clearRect(0, 0, this.width, this.height);
      this.p.draw(this.ctx);
      this.ball.draw(this.ctx);
    };
    
    Game.prototype.update = function() {
      if (this.paused) return;
      this.ball.update();
      //Right Paddle's Directions
      if (this.keys.isPressed(37)) { // LEFT
        this.p.x = Math.max(0, this.p.x - paddleSpeed);
      } else if (this.keys.isPressed(39)) { // RIGHT
            
        this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
      }
    
    
      if (this.ball.x < this.ball.ballRadius || this.ball.x > this.width - this.ball.ballRadius) { //LEFT & RIGHT
        this.ball.vx = -this.ball.vx;
      }
      if (this.ball.y < this.ball.ballRadius) { //TOP
        this.ball.vy = -this.ball.vy;
      } else if (this.ball.y > this.p.y - this.ball.ballRadius && 
                this.ball.y < this.p.y + this.p.height + this.ball.ballRadius) {
    
       if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {
          this.ball.vy = -this.ball.vy;
          console.log('hit');
        } else {
          //      console.log(this.ball.x);
        }
      }
    };
    
    /////Paddle
    function Paddle(x, y) {
      this.x = x;
      this.y = y;
      this.width = 30;
      this.height = 5;
      this.score = 0;
    }
    
    Paddle.prototype.draw = function(p) {
      p.fillRect(this.x, this.y, this.width, this.height);
    };
    
    ///KEY LISTENER
    function Keylistener() {
      this.pressedKeys = [];
      this.keydown = function(e) {
        this.pressedKeys[e.keyCode] = true;
      };
      this.keyup = function(e) {
        this.pressedKeys[e.keyCode] = false;
      };
      document.addEventListener("keydown", this.keydown.bind(this));
      document.addEventListener("keyup", this.keyup.bind(this));
    }
    
    Keylistener.prototype.isPressed = function(key) {
      return this.pressedKeys[key] ? true : false;
    };
    
    Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
      document.addEventListener("keypress", function(e) {
        if (e.keyCode == keyCode) callback(e);
      });
    };
    
    ///BALL
    function Ball() {
      this.x = 0;
      this.y = 0;
      this.vx = 0;
      this.vy = 0;
      this.ballRadius = 5;
    }
    
    Ball.prototype.update = function() {
      this.x += this.vx;
      this.y += this.vy;
    };
    
    Ball.prototype.draw = function(p) {
      p.beginPath();
      p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
      p.fill();
      p.closePath();
    };
    
    
    //Initialize the game
    var game = new Game();
    
    //the Main Engine
    function mainLoop() {
      theLoop = setInterval(function() {
        game.update();
        game.draw();
      }, 33.3333);
    }
    
    //calling the Main Engine
    mainLoop();
    #game {
      width: 800px;
      height: 400px;
      background-color: #353535;
    }
    &lt;canvas id="game"&gt;&lt;/canvas&gt;

    【讨论】:

      【解决方案2】:

      你的问题就在这里。

      else if (this.ball.y > this.height - this.ball.ballRadius) {
          if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {
      

      除非球位于屏幕底部,否则您不会尝试用球拍记录击球。您需要检查球是否与球拍相交在您击中屏幕底部之前

      var paddleLeft = this.p.x;
      var paddleRight = paddleLeft + this.p.width;
      var paddleTop = this.p.y;
      var ballLeft = this.ball.x;
      var ballRight = ballLeft + this.ball.ballRadius;
      var ballBottom = this.ball.y + this.ball.ballRadius;
      var xCollision = (ballLeft <= paddleRight && ballRight >= paddleLeft);
      var yCollision = (ballBottom >= paddleTop);
      if (this.ball.y < this.ball.ballRadius) { //TOP
        this.ball.vy = -this.ball.vy;
      } else if (xCollision && yCollision) {
        this.ball.vy = -this.ball.vy;
        console.log('hit');
      }
      

      它正在你的游戏中运行。

      var canvas = document.getElementById('game');
      var theLoop;
      var paddleSpeed = 4;
      
      //OBJECTS
      //Game
      function Game() {
        this.width = canvas.width;
        this.height = canvas.height;
        this.ctx = canvas.getContext('2d');
        this.ctx.fillStyle = "white";
        this.p = new Paddle(0, 220);
        this.p.x = (this.width - this.p.width) / 2;
        this.keys = new Keylistener();
        this.ball = new Ball();
        this.ball.x = this.width / 2;
        this.ball.y = 125;
        this.ball.vy = Math.floor(Math.random() * 12 - 6);  
        this.ball.vx = 7 - Math.abs(this.ball.vy);
      }
      
      Game.prototype.draw = function() {
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.p.draw(this.ctx);
        this.ball.draw(this.ctx);
      };
      
      Game.prototype.update = function() {
        if (this.paused) return;
        this.ball.update();
        //Right Paddle's Directions
        if (this.keys.isPressed(37)) { // LEFT
          this.p.x = Math.max(0, this.p.x - paddleSpeed);
        } else if (this.keys.isPressed(39)) { // RIGHT
              
          this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
        }
      
        var leftBallCollision = this.ball.x < this.ball.ballRadius;
        var rightBallCollision = this.ball.x > this.width - this.ball.ballRadius;
        if (leftBallCollision || rightBallCollision) { //LEFT & RIGHT
          this.ball.vx = -this.ball.vx;
        }
        
        var paddleLeft = this.p.x;
        var paddleRight = paddleLeft + this.p.width;
        var paddleTop = this.p.y;
        var ballLeft = this.ball.x;
        var ballRight = ballLeft + this.ball.ballRadius;
        var ballBottom = this.ball.y + this.ball.ballRadius;
        var xCollision = (ballLeft <= paddleRight && ballRight >= paddleLeft);
        var yCollision = (ballBottom >= paddleTop);
        if (this.ball.y < this.ball.ballRadius) { //TOP
          this.ball.vy = -this.ball.vy;
        } else if (xCollision && yCollision) {
          this.ball.vy = -this.ball.vy;
          console.log('hit');
        }
      };
      
      /////Paddle
      function Paddle(x, y) {
        this.x = x;
        this.y = y;
        this.width = 30;
        this.height = 5;
        this.score = 0;
      }
      
      Paddle.prototype.draw = function(p) {
        p.fillRect(this.x, this.y, this.width, this.height);
      };
      
      ///KEY LISTENER
      function Keylistener() {
        this.pressedKeys = [];
        this.keydown = function(e) {
          this.pressedKeys[e.keyCode] = true;
        };
        this.keyup = function(e) {
          this.pressedKeys[e.keyCode] = false;
        };
        document.addEventListener("keydown", this.keydown.bind(this));
        document.addEventListener("keyup", this.keyup.bind(this));
      }
      
      Keylistener.prototype.isPressed = function(key) {
        return this.pressedKeys[key] ? true : false;
      };
      
      Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
        document.addEventListener("keypress", function(e) {
          if (e.keyCode == keyCode) callback(e);
        });
      };
      
      ///BALL
      function Ball() {
        this.x = 0;
        this.y = 0;
        this.vx = 0;
        this.vy = 0;
        this.ballRadius = 5;
      }
      
      Ball.prototype.update = function() {
        this.x += this.vx;
        this.y += this.vy;
      };
      
      Ball.prototype.draw = function(p) {
        p.beginPath();
        p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
        p.fill();
        p.closePath();
      };
      
      
      //Initialize the game
      var game = new Game();
      
      //the Main Engine
      function mainLoop() {
        theLoop = setInterval(function() {
          game.update();
          game.draw();
        }, 33.3333);
      }
      
      //calling the Main Engine
      mainLoop();
      #game {
        background-color: #353535;
      }
      &lt;canvas id="game" width="320" height="240"&gt;&lt;/canvas&gt;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-05
        相关资源
        最近更新 更多