简体   繁体   中英

Collision Detection using javascript

I'm a highschool student in Japan trying to learn how to program. I recently viewed https://vimeo.com/105955605 this video, and decided I could use the beginning section to start building pong in javascript.

I'm pretty much a complete novice with programming and/or javascript and I still have a long way to go.

I got to the collision detection part, and I can't seem to get the syntax correct because things stop loading, or the ball goes off screen.

The lady in the video simply deletes objects once they collide, but I want the ball to go the opposite direction. At this point I haven't considered changing the velocity of the ball based on the section of the paddle or paddle velocity.

Here is my HTML

<html>
 <head>
  <meta charset="UTF-8">
  <title>Pong</title>
  <link type="text/css" rel="stylesheet" href="css/stylesheet.css">
 </head>
 <body>
  <h1>Pong</h1><br/>
  <input type="button" id="start" value="Click To Begin"/> <br/>
  <canvas id="screen" width="310" height="210"></canvas>
  <script src="js/pong.js"></script>
 </body>
</html>

Here is my js code.

(function(){ // It was there all along, just not formated correctly for the code block thingie on SO
    //Main game function
    //tells objects in bodies array to update.
    //stores gameSize pulled from canvasId
    var Game = function(canvasId){
        var canvas = document.getElementById(canvasId);
        var screen = canvas.getContext('2d');
        var gameSize = {x: canvas.width, y: canvas.height};
        var self = this;
//bodies array
        this.bodies = [new Player1(this, gameSize), new Player2(this, gameSize),new Ball(self, gameSize)];
//update function
        var tick = function(){
        self.update();
        self.draw(screen,gameSize);
        requestAnimationFrame(tick);
        };
        tick();
    };
//constructor for game() function. tells bodies to update, and draw
    Game.prototype = {
        update: function(){
 //           new collision(this.bodies[2],this.bodies[1]);
 //           new collision(this.bodies[2],this.bodies[0]);
            for(var i =0 ; i < this.bodies.length; i++){
                this.bodies[i].update();
            }
        },
        draw:function(screen,gameSize){
            screen.clearRect(0,0,gameSize.x,gameSize.y);
            for(var i =0 ; i < this.bodies.length; i++){
                drawRect(screen, this.bodies[i]);
            }
        }
    };
//P1 object, declares size and start position of P1
    var Player1= function(game, gameSize){
        this.size = {x:30,y:gameSize.y / 3};
        this.game = game;
        this.gameSize = gameSize;
        this.center = {x: 0, y:gameSize.y/2};
        this.keyboarder = new Keyboarder();
       requestAnimationFrame(this.update);
    };
//constructor for P1, updates position based on keyboard input
    Player1.prototype = {
        update:function(){
            if (this.keyboarder.isDown(this.keyboarder.KEYS.S) && this.center.y < (5*this.gameSize.y / 6)){
               this.center.y += 4;
            }else if(this.keyboarder.isDown(this.keyboarder.KEYS.W) && this.center.y > this.size.y /2 ){
                this.center.y -= 4;
            }
        }
    };
//P2, same as P1 aside from position
    var Player2= function(game, gameSize){
        this.size = {x:30,y:gameSize.y / 3};
        this.game = game;
        this.gameSize = gameSize;
        this.center = {x: gameSize.x, y:gameSize.y/2};
        this.keyboarder = new Keyboarder();
        requestAnimationFrame(this.update);
    };
//constructor for P2, same as P1
    Player2.prototype = {
        update:function(){
            if (this.keyboarder.isDown(this.keyboarder.KEYS.DOWN) && this.center.y < (5*this.gameSize.y / 6)){
                this.center.y += 4;
            }else if(this.keyboarder.isDown(this.keyboarder.KEYS.UP) && this.center.y > this.size.y /2 ){
                this.center.y -= 4;
            }
        }
    };
//Ball function, gives ball random velocity, tells it to start at the center.
    var Ball = function(game , gameSize){
        var plusOrMinus = Math.random() < 0.5 ? -1 : 1;
        var rand = Math.random();
        this.velocity = {x: plusOrMinus * (3 + Math.random()) * rand , y: plusOrMinus * (1 + Math.random()) * rand };
        this.size = {x : 15, y : 15 };
        this.center = {x: gameSize.x /2 , y: gameSize.y /2};
        this.gameSize = gameSize;

    };
//Ball constructor, tells ball to bounce and add velocity.
    Ball.prototype = {
        update: function () {
            if(this.center.x < 0 || this.center.x > this.gameSize.x) {
                this.velocity.x = -this.velocity.x + (-this.velocity.x * 0.1);
            };
        this.center.x += this.velocity.x;
        if(this.center.y < 0 || this.center.y > this.gameSize.y) {
            this.velocity.y = -this.velocity.y + (-this.velocity.y * 0.1);
        };
        this.center.y += this.velocity.y;
         requestAnimationFrame(this.update);
        }
    };

//Draw function, draws object
    var drawRect = function(screen, body){
        screen.fillRect(body.center.x - body.size.x /2,
                body.center.y - body.size.y /2, body.size.x,body.size.y);
    };
//Keyboard input function
    //reads if keys are being pressed and takes the event code
    //isDown() returns boolean of key down = true, key up = false
    var Keyboarder = function(
        ){
        var keyState = {};

        window.addEventListener('keydown' , function(e){
            keyState[e.keyCode] = true;
        });
        window.addEventListener('keyup' , function(e){
            keyState[e.keyCode] = false;
        });
        this.KEYS = {DOWN: 40, UP:38,W:87 , S: 83};

        this.isDown = function(keyCode){
            return keyState[keyCode] === true;
        };

    };

/*    var collision = function (b1, b2) {
       if(
           b1 === b2 ||
           b1.center.x + this.size.x /2 < b2.center.x + b2.size.x /2 ||
           b1.center.y + this.size.y /2 < b2.center.y + b2.size.y /2 ||
           b1.center.x - this.size.x /2 > b2.center.x - b2.size.x /2 ||
           b1.center.y - this.size.y /2 > b2.center.y - b2.size.y /2
           ){

            }else{
                b1.velocity.x = -b1.velocity.x + (-b1.velocity.x * 0.1);
            };

    };
*/
//calls game() function when button is pressed
    var start = document.getElementById('start');
    start.addEventListener('click' , function(e){
       new Game('screen');
    });
})();

I have commented out the collision function used by the lady in the video as I'm not too sure how to use it for my needs. If anyone could point me in a direction of thinking, it would be appreciated.

It's quite simple.

At some point (normally when the positions of your objects have changed) you need to check for collisions. To do so, you can utilize the given function.

DEMO

var collision = function (ball, paddle) {      
   if(
      ((ball.center.y +  (ball.size.y / 2)) < (paddle.center.y - (paddle.size.y / 2))) || //ball is under paddle
      ((ball.center.y -  (ball.size.y / 2)) > (paddle.center.y + (paddle.size.y / 2))) || //ball is over paddle
      ((ball.center.x +  (ball.size.x / 2)) < (paddle.center.x - (paddle.size.x / 2))) || //ball is left from the paddle
      ((ball.center.x -  (ball.size.x / 2)) > (paddle.center.x + (paddle.size.x / 2))) //ball is right from the paddle 
   ){
        //no collision
   }else{
     alert("collision");
     ball.velocity.x = -ball.velocity.x + (-ball.velocity.x * 0.1);
   }
};

Some tips:

  • use proper names (ball is more readable than b1 and paddle more than b2)
  • debug you code (a good way to understand how JS is working and why your code wont do what it should is to use a debugger and check step by step what is wrong. Every browser has some built in functionality for that and in most you can access it by pressing F12.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM