我是javascript的新手,并试图学习桨的碰撞检测。
这可能很简单,但我不知道如何创建我创建的桨的碰撞检测器。这是如何工作的以及我为了创建碰撞检测需要做些什么?
(我不需要了解砖块,我只需要创建简单的动画/游戏javascript页面。)
哦,你知道我使用的是什么样的javascript吗?因为有时它是完全不同的编码所以很难找到我可以遵循的编码类型..
三江源!
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);
答案 0 :(得分:0)
首先,您应该评估矩形和圆形之间的距离:如果中心之间的距离大于矩形宽度的一半和球的半径之和 - 则没有碰撞。
如果您不关心像素完美评估,则将圆视为方形更容易。在这种情况下,当上述距离小于总和时 - 你有碰撞
我正在编写太空侵略者的克隆(我是一个业余爱好者,我这样做是为了好玩):https://github.com/yurybond/stackowerflow-rocks/commit/a1c1540abd453773b3ce6445d01e51ad336bbe84,我在那里写了像素完美碰撞,示例/摘录波纹管(如果两者之间存在碰撞则确定actors(在代码中的其他位置定义 - 检查Codepen链接以获取详细信息):
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()
我希望这可以帮助你开始。