球和桨之间的碰撞在pong比赛在帆布

时间:2017-05-06 19:16:22

标签: javascript canvas bounding-box pong

球似乎从球拍的一侧反弹,但当它从侧面传来时,它会在球拍中出现故障。我无法找到一种方法,它真的困扰我。我正在使用一些逻辑门来定义球的方向需要被暴露的位置



function startGame() {
    GameArea.start();
	Ball1 = new CircleComp('white' , window.innerWidth - 200 , window.innerHeight - 20);
	Ball1.ySpeed = 13.5;
	Ball1.xSpeed = 6;
	Paddle1 = new PaddleComp( 87, 83, 0, window.innerHeight / 2.5, 10, 70);
	Paddle2 = new PaddleComp( 38, 40, window.innerWidth - 10, window.innerHeight / 2.5, 10 , 70);
}
var GameArea = {
	canvas : canvas = document.querySelector("canvas"),
	start : function (){
		this.canvas.width = window.innerWidth;
		this.canvas.height = window.innerHeight;
		this.ctx = this.canvas.getContext('2d');
		this.interval = setInterval(updateGameArea, 20);
        window.addEventListener('keydown', function (e) {
            GameArea.keys = (GameArea.keys || []);
            GameArea.keys[e.keyCode] = true;
        })
        window.addEventListener('keyup', function (e) {
            GameArea.keys[e.keyCode] = false; 
        })
    }, 
	clear : function() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
}
function CircleComp(color, x , y){
	this.x = x;
	this.y = y;
	this.width = 8;
    this.height = 8;
	var context1 = GameArea.ctx;
	this.update = function(){
		context1.beginPath();
		context1.fillStyle = color;
		context1.fillRect(this.x, this.y, this.width, this.height);
		context1.fill();
		context1.stroke();
		this.updatePosition();
	}
	this.updatePosition = function(){
		this.y += this.ySpeed;	
		this.x += this.xSpeed;
		if(this.x + this.width > GameArea.canvas.width){
			this.xSpeed = -this.xSpeed;
		}
		if(this.y + this.height > GameArea.canvas.height){
			this.ySpeed = -this.ySpeed;;	
		}
		if(this.x - this.width < 0){
			this.xSpeed = -this.xSpeed;
		}	
		if(this.y - this.height < 0){
			this.ySpeed = -this.ySpeed;
		}
		if(this.y + this.height > Paddle2.y && this.y - this.width < (Paddle2.y + 130) && this.x + this.width > Paddle2.x ){
			this.xSpeed = -this.xSpeed;
		}	
		if(this.y + this.height > Paddle1.y && this.y - this.width < (Paddle1.y + 70) && this.x - this.height < Paddle1.x + 10){
			this.xSpeed = -this.xSpeed;
		}
	}
}
function PaddleComp(Upkey, Downkey, x, y, width, height){
	this.x = x;
	this.y = y;
	this.width = width;
	this.height = height;
	this.ySpeed = 0;
	var context2 = GameArea.ctx;
	this.update = function(){
	context2.fillStyle = 'white';
	context2.fillRect(x,this.y,this.width,this.height);	
	this.updatePosition();
	}
	this.updatePosition = function() {
		this.ySpeed = 0;	
		if (GameArea.keys && GameArea.keys[Upkey]) {
			this.ySpeed = -15; //console.log('Up');
		}
		if (GameArea.keys && GameArea.keys[Downkey]) {
			this.ySpeed = 15; //console.log('Down');
		}
		if ((GameArea.keys && GameArea.keys[Downkey]) && this.y + 130 > window.innerHeight){
			this.ySpeed = this.ySpeed -15 ;	
		}
		if ((GameArea.keys && GameArea.keys[Upkey]) && this.y < 0 ){
			this.ySpeed = this.ySpeed +15 ;	
		}
		this.y += this.ySpeed;			
	}
}
function updateGameArea(){
	GameArea.clear();
	Paddle1.update();
	Paddle2.update();
	Ball1.update();
}
&#13;
<html>
	<head>
		<meta charset='urf-8'>
		<style>
			canvas{
				border: 0px solid black;
				background-color: black;
			}
			body{
				margin: 0;
				overflow: hidden;
			}
		</style>
	</head>
	<body onload='startGame()'>
		<canvas></canvas>
		<script src='Pong.js'></script>
	</body>
</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

无法直接看到你的代码出现了什么问题,所以我只是在球对象中重写了球,蝙蝠(桨)测试功能,并从球员对象中调用。 ball.checkPad(播放器);测试球是否击中了球员蝙蝠。为了帮助描绘正在发生的事情,我已经放慢了速度,让蝙蝠成为真正的蠢货。当球击中球棒时,球会变黄,球棒会变红一秒左右。

您询问的部分有很多评论,

希望有所帮助

从OP问题中复制演示。

&#13;
&#13;
const setting = {
    speed : 2, // of ball
    left : 0,
    width : 400,
    height : 200,
    padWidth : 50,
    padHeight : 80,
    padSpeed : 4, // double balls
    hitPauseCount : 30,  // nuber of frames to hold when there is a collisiotn so you
                          // can check all is good
}
const keys = {
    ArrowUp : false,
    ArrowDown : false,
    ArrowLeft : false,
    ArrowRight : false,
    keyEvent(e) { // dont use keyCode it has depreciated
        if (keys[e.code] !== undefined) {
            keys[e.code] = e.type === "keydown";
            e.preventDefault();
        }
    }
}
var ctx;
var ball1, paddle1, paddle2;
var gameArea = {
    start() {
        canvas.width = setting.width;
        canvas.height = setting.height;
        ctx = canvas.getContext('2d');
        requestAnimationFrame(updateGameArea);
    },
    clear() {
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    }
}
gameArea.start();
ball = new CircleComp('white', window.innerWidth - 200, window.innerHeight - 20);
ball.ySpeed = setting.speed;
ball.xSpeed = setting.speed;
paddle1 = new PaddleComp("ArrowUp", "ArrowDown", setting.left, setting.height / 2, setting.padWidth, setting.padHeight);
paddle2 = new PaddleComp("ArrowLeft", "ArrowRight", setting.width - setting.padWidth, setting.height / 2, setting.padWidth, setting.padHeight);
window.addEventListener('keydown', keys.keyEvent);
window.addEventListener('keyup', keys.keyEvent);


function CircleComp(color, x, y) {
    this.x = x;
    this.y = y;
    this.width = 8;
    this.height = 8;
    this.xSpeed = setting.speed;
    var hit = 0;
    var restartCount;
    var serveDirection;

    this.reset = function(){
        this.x = ctx.canvas.width /2;
        this.y = ctx.canvas.height / 2;
        this.xSpeed = -this.xSpeed
        this.ySpeed = setting.speed * Math.sign(Math.random() - 0.5);
        restartCount = 60;
    }
    this.draw = function () {
        if(hit > 0){ 
            hit -= 1;
            ctx.fillStyle = "yellow";
        }else{
            ctx.fillStyle = color;
        }
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
    // next funtion is called by the player objects
    this.checkPad = function (player) {
        if (player.x > canvas.width / 2) { // is player on left or right
            if (this.xSpeed > 0) { // player on right only check if ball moving rigth
                if (this.x + this.width > player.x) { // ball is in paddles zone
                    //if not  bottom of ball above top of bat or top of ball bellow bottom of bat
                    if (!(this.y + this.height <= player.y || this.y >= player.y + player.height)) {
                        // ball and bat in contact
                        // is ball moving down and the balls top edge above the player
                        // then ball has hit the top side of the bat
                        if(this.ySpeed > 0 && this.y <= player.y){ 
                            this.y = player.y - this.width;
                            this.ySpeed =  -setting.speed;
                        }else if(this.ySpeed < 0 && this.y + this.height >= player.y + player.height){ // do bottom check
                            this.y = player.y + player.height;
                            this.ySpeed =  setting.speed;
                        }else{  // ball hit front of bat
                            this.x = player.x - this.width;
                            this.xSpeed =  - setting.speed;
                        }
                        player.hit = setting.hitPauseCount;  // counters to show FX when a hit happens
                        hit = setting.hitPauseCount;
                    }
                }
            }

        } else { // player must be left
            if (this.xSpeed < 0) { // ball must move left
                if (this.x < player.x + player.width) { // ball is in paddles zone
                    if (!(this.y + this.height <= player.y || this.y >= player.y + player.height)) {
                        // ball and bat in contact
                        // ball and bat in contact
                        // is ball moving down and the balls top edge above the player
                        // then ball has hit the top side of the bat
                        if(this.ySpeed > 0 && this.y <= player.y){ 
                            this.y = player.y - this.width;
                            this.ySpeed =  -setting.speed;
                        }else if(this.ySpeed < 0 && this.y + this.height >= player.y + player.height){ // do bottom check
                            this.y = player.y + player.height;
                            this.ySpeed =  setting.speed;
                        }else{  // ball hit front of bat
                            this.x = player.x + player.width;
                            this.xSpeed = setting.speed;
                        }
                        player.hit = setting.hitPauseCount;  // counters to show FX when a hit happens
                        hit = setting.hitPauseCount;
                    }
                }
            }
        }
    }
    this.update = function () {
        if(restartCount > 0){ // wait for restart pause
            restartCount -= 1;
        }else{
            if(hit > 0){  // do nothing if paused
                return;
            }
            this.y += this.ySpeed;
            this.x += this.xSpeed;
            if (this.x + this.width >= canvas.width) {
                this.reset();  // point
            } else if (this.x < 0) {
                this.reset(); // point
            }
            if (this.y + this.height >= canvas.height) {
                this.y = canvas.height - this.height;
                this.ySpeed = -setting.speed;
            } else if (this.y < 0) {
                this.y = 0;
                this.ySpeed = setting.speed;
            }
        }
    }
    this.reset();
}
function PaddleComp(upKey, downKey, x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.hit = 0;
    this.draw = function () {
        if(this.hit > 0){ 
            this.hit -= 1;
            ctx.fillStyle = "red";
        }else{
            ctx.fillStyle = '#9CF';
        }
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
    this.update = function () {
        if (keys[upKey]) {
            this.y -= setting.padSpeed;
        };
        if (keys[downKey]) {
            this.y += setting.padSpeed;
        };
        if (this.y < 0) {
            this.y = 0;
        }
        if (this.y + this.height >= canvas.height) {
            this.y = canvas.height - this.height;
        }
        ball.checkPad(this);
    }
}
function updateGameArea() {
    gameArea.clear();
    paddle1.update();
    paddle2.update();
    ball.update();
    paddle1.draw();
    paddle2.draw();
    ball.draw();
    requestAnimationFrame(updateGameArea);
}
&#13;
<canvas id=canvas style='background:#69C;border:2px blue solid'></canvas>
&#13;
&#13;
&#13;