桨的碰撞检测(乒乓/破块游戏) [英] collision detection for paddle (pong/breaking block game)

查看:101
本文介绍了桨的碰撞检测(乒乓/破块游戏)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是javascript的新手,并试图学习桨的碰撞检测。

I'm new to javascript, and trying to learn the collision detection for the paddle.

这可能很简单,但我不知道如何创建我创建的桨的碰撞检测器。这是如何工作的以及我为了创建碰撞检测需要做些什么?

This might be simple, but I don't know how to create collision detector of the paddle I created. How do this work and what do I have to put in order to create collision detection?

(我不需要了解砖块,我只需要创建简单的动画/游戏javascript页面。)

(I don't need know about bricks, I just have to create simple animated/game javascript page.)

哦,你知道我使用的是什么样的javascript吗?因为有时它是完全不同的编码所以很难找到我可以遵循的编码类型..

Oh and do you know what kind of javascript am I using? because sometimes it is totally different coding so it's really hard to find my type of coding I can follow of..

谢谢!

 var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width/2;
var y = canvas.height-50;
var dx = 2;
var dy = -2;
var ball = drawBall 
var paddleHeight = 10;
var paddleWidth = 50;
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 drawBall() {
    ctx.beginPath();
    ctx.arc(x,y, ballRadius, 0, Math.PI*2);
    ctx.fillStyle = "coral";
    ctx.fill();
    ctx.closePath();
}

function drawPaddle() {
    ctx.beginPath();
    ctx.rect(paddleX, 400, 50, 10);
    ctx.fillStyle = "lightcoral";
    ctx.fill();
    ctx.closePath();
}

function collisionDetector (){

}

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

    if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
        dx = -dx;
    }
    if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {
        dy = -dy;
    }

    if(rightPressed && paddleX < canvas.width-paddleWidth) {
        paddleX += 7;
    }
    else if(leftPressed && paddleX > 0) {
        paddleX -= 7;
    }
    x += dx;
    y += dy;
}
setInterval(draw, 10);


推荐答案

首先,您应该评估矩形和圆形之间的距离:如果中心之间的距离大于矩形宽度和球半径之和的总和 - 没有碰撞。

如果你不关心像素完美评估,那么它更容易将圆视为正方形。在这种情况下,当上述距离小于总和时 - 你有碰撞。

我正在编写太空入侵者的克隆(我是一个业余爱好者,我这样做是为了好玩): Codepen链接,其中我写了像素完美碰撞,示例/摘录波纹管(如果存在则确定碰撞在两个actor之间(在代码中的其他位置定义 - 检查Codepen链接以获取详细信息):

First you should evaluate the distance between the rectangle and circle: if the distance between the centers is greater than the sum of half a width of rectangle and radius of the ball - there is no collision.
If you don't care for pixel perfect evaluation, it's easier to treat circle as as square. In that case, when the above distance is less than the sum - you have collision.
I am just in the process of writing clone of Space Invaders (I am an amateur, I do this for fun): Codepen link, where I wrote pixel perfect collision, example/excerpt bellow (collision is determined if exist between two actors (defined elsewhere in code - check Codepen link for details):

collision: function(actor1, actor2) {
    var X = Math.abs(actor1.x - actor2.x);
    var Y = Math.abs(actor1.y - actor2.y);
    if (Y >= INI.COLLISION_SAFE) return false;
    if (X >= INI.COLLISION_SAFE) return false;
    var w1 = parseInt(actor1.width / 2, 10);
    var w2 = parseInt(actor2.width / 2, 10);
    var h1 = parseInt(actor1.height / 2, 10);
    var h2 = parseInt(actor2.height / 2, 10);
    var T = Math.sqrt((h1 + h2) ** 2 + (w1 + w2) ** 2);
    if (
        MIN(X, Y) === 0 &&
        MAX(X, Y) >= MAX(actor1.width, actor1.height, actor2.width, actor2.height)
    )
        return false;
    var D = Math.sqrt(X ** 2 + Y ** 2);
    if (D > T) return false; // not close enough
    var minWH = MIN(w1, w2, h1, h2);
    if (D <= minWH) return true; //ultra close
    ///////// pixel perfect evaluation ////////////
    var act1 = new Vector(actor1.x, actor1.y);
    var act2 = new Vector(actor2.x, actor2.y);
    var direction = act1.direction(act2);
    var point1 = new Vector(
        actor1.x + direction.x * w1,
        actor1.y + direction.y * h1
    );
    var point2 = new Vector(
        actor2.x - direction.x * w2,
        actor2.y - direction.y * h2
    );
    var x = MIN(point1.x, point2.x);
    var y = MIN(point1.y, point2.y);
    var w = MAX(point1.x, point2.x) - MIN(point1.x, point2.x);
    var h = MAX(point1.y, point2.y) - MIN(point1.y, point2.y);
    if (w === 0 && h === 0) return false;
    if (w === 0) {
        w = MIN(w1, w2);
        x = x - w;
        w = w * 2;
    }
    if (h === 0) {
        h = MIN(h1, h2);
        y = y - h;
        h = h * 2;
    }
    var area = new Square(x, y, w, h);
    var area1 = new Square(
        (area.x - actor1.x) * direction.x + w1 * direction.x,
        (area.y - actor1.y) * direction.y + h1 * direction.y,
        area.w,
        area.h
    );
    var area2 = new Square(
        (area.x - actor2.x) * direction.x * -1 + w2 * direction.x * -1,
        (area.y - actor2.y) * direction.y * -1 + h2 * direction.y * -1,
        area.w,
        area.h
    );
    var CTX1 = LAYER.temp;
    var CTX2 = LAYER.temp2;
    ENGINE.draw("temp", 0, 0, SPRITE[actor1.name]);
    ENGINE.draw("temp2", 0, 0, SPRITE[actor2.name]);
    var data1 = CTX1.getImageData(area1.x, area1.y, area1.w, area1.h);
    var data2 = CTX2.getImageData(area2.x, area2.y, area2.w, area2.h);
    var DL = data1.data.length;
    var index;
    for (index = 3; index < DL; index += 4) {
        if (data1.data[index] > 0 && data2.data[index] > 0) return true;
    }
    return false;
},

如果这个例子,我检查矩形是否重叠(如上所述) ),我计算精灵的哪些部分实际上重叠,然后检查每个精灵是否在同一个点(重叠的矩形)中有非透明像素。

我还建议使用requestAnimationFrame()而不是setInterval()。

我希望这可以帮助你开始。

If this example, after I check if the rectangles overlap (as described above), i calculate which parts of the sprite actually overlaps, then check whether each of the sprite have non transparent pixels in the same spot (in the overlapping rectangle).
I also recommend using requestAnimationFrame() instead of setInterval().
I hope this helps you start.

这篇关于桨的碰撞检测(乒乓/破块游戏)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆