问题
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?
(I don't need know about bricks, I just have to create simple animated/game javascript page.)
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..
Thankyou!
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);
回答1:
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;
},
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.
来源:https://stackoverflow.com/questions/46972308/collision-detection-for-paddle-pong-breaking-block-game