帆布碰撞

时间:2016-08-15 14:35:01

标签: javascript canvas

我是javascript的新手,并试图找出如何与球和木板碰撞,这将停止游戏并提醒玩家“你输了”。但是我只希望红球击中木板而蓝色传递而不接触。这是我正在处理的代码。 (我不介意你是否可以帮助只与两个球发生碰撞)

var spawnRate = 100;

var spawnRateOfDescent = 2;

var lastSpawn = -10;

var objects = [];

var startTime = Date.now();

function spawnRandomObject() {


var t;

if (Math.random() < 0.50) {
    t = "red";
} else {
    t = "blue";
}


var object = {
    type: t,
    x: Math.random() * (canvas.width - 30) + 15,
    y: 0

}

objects.push(object);
}



function animate() {

var time = Date.now();

if (time > (lastSpawn + spawnRate)) {
    lastSpawn = time;
    spawnRandomObject();
}

for (var i = 0; i < objects.length; i++) {
    var object = objects[i];
    object.y += spawnRateOfDescent;
    ctx.beginPath();
    ctx.arc(object.x, object.y, 8, 0, Math.PI * 2);
    ctx.closePath();
    ctx.fillStyle = object.type;
    ctx.fill();

    }

    }



var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var paddleHeight = 10;
var paddleWidth = 60;
var paddleY = 480
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false;
var leftPressed = false;

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);

function keyDownHandler(e) {
if(e.keyCode == 39) {
    rightPressed = true;
}
else if(e.keyCode == 37) {
    leftPressed = true;
}
}
function keyUpHandler(e) {
if(e.keyCode == 39) {
    rightPressed = false;
}
else if(e.keyCode == 37) {
    leftPressed = false;
}
}



function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, paddleY, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}




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

if(rightPressed && paddleX < canvas.width-paddleWidth) {
    paddleX += 3;
}
else if(leftPressed && paddleX > 0) {
    paddleX -= 3;
}

}

setInterval(draw, 10);

谢谢!

1 个答案:

答案 0 :(得分:1)

如果您有这样的对象:

let ball = { type: 'red', x: 10, y: 10, width: 10, height: 10 };

您可能需要考虑向此方法添加一个方法,以检查它是否与任何其他矩形重叠:

ball.overlapsBall = function( otherBall ){
    return !( 
        otherBall.x + otherBall.width < this.x 
        && otherBall.y + otherBall.height < this.y 
        && otherBall.y > this.y + this.height 
        && otherBall.x > this.x + this.height
    );
}

你可以通过检查是否重叠来做到这一点,只有当一个盒子完全在另一个盒子之外时才会这样做(通过if语句读取并尝试将其可视化,实际上是相当简单)

在你的绘图功能中,你现在可以添加一个循环来查看是否发生任何重叠:

var overlap = objects.filter(function( ball ) { return paddle.overlapsBall( ball ) });

您甚至可以发出if语句来检查它的类型! (filter将带您完整的球阵列并检查重叠,并从数组中删除任何不返回true的内容。现在您可以使用overlaps.forEach(function( ball ){ /* ... */});对所有内容执行某些操作与你的球拍重叠的球。)

最后一件事,如果您计划使用许多对象进行此操作,您可能需要考虑使用这样的简单类为您制作的每个球拍或球:

class Object2D {

    constructor(x = 0, y = 0;, width = 1, height = 1){
        this.x = x;
        this.y = x;
        this.width = width;
        this.height = height;
    }

    overlaps( otherObject ){
        !( otherObject.x + otherObject.width < this.x && otherObject.y + otherObject.height < this.y && otherObject.y > this.y + this.height && otherObject.x > this.x + this.height );
    }

}

这允许您使用此简单表达式创建一个新对象,该对象自动具有检查与类似对象重叠的方法:

var paddle = new Object2D(0,0,20,10);
var ball = new Object2D(5,5,10,10);
paddle.overlaps( ball ); // true!

除此之外,您确保任何Object2D都包含您计算所需的值。您可以使用paddle instanceof Object2Dtrue)检查此对象是否为正确类型。

注意请注意,正如@Janje在下面的评论中不断指出的那样,我们在这里做了一个矩形重叠,它可能会产生一些误报&#39;对于所有不是圆形的矩形块。这对于大多数情况来说已经足够了,但是您可以通过快速谷歌搜索轻松找到其他重叠和碰撞的数学。

更新:简单实施

请参阅下文,了解重叠如何运作的一个非常简单的示例:

&#13;
&#13;
var paddle = { x: 50,  y: 50,  width: 60,  height: 20 };
var box = { x: 5, y: 20, width: 20, height: 20 };

var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');

document.body.appendChild( canvas );

canvas.width = 300;
canvas.height = 300;

function overlaps( a, b ){
  return !!( a.x + a.width > b.x &&  a.x < b.x + b.width
    && a.y + a.height > b.y &&  a.y < b.y + b.height );
}

function animate(){
  ctx.clearRect( 0, 0, canvas.width, canvas.height );
  
  ctx.fillStyle = overlaps( paddle, box ) ? "red" : "black";
  ctx.fillRect( paddle.x, paddle.y, paddle.width, paddle.height );
  ctx.fillRect( box.x, box.y, box.width, box.height );
	
  window.requestAnimationFrame( animate );
}

canvas.addEventListener('mousemove', function(event){
  paddle.x = event.clientX - paddle.width / 2;
  paddle.y = event.clientY - paddle.height / 2;
})

animate();
&#13;
&#13;
&#13;