Generally to detect collisions in canvas games I use something like:
function collides(a, b) {
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}
But this only detects collisions if the objects are touching at the time the frame is processed. If I have a sprite whose speed (in pixels/frame) is greater than the width of an obstacle in its path, it will pass through the obstacle without the collision being detected.
How would I go about checking what's in between the sprite and its destination?
Generally to detect collisions in canvas games I use something like:
function collides(a, b) {
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}
But this only detects collisions if the objects are touching at the time the frame is processed. If I have a sprite whose speed (in pixels/frame) is greater than the width of an obstacle in its path, it will pass through the obstacle without the collision being detected.
How would I go about checking what's in between the sprite and its destination?
Share Improve this question asked May 9, 2013 at 12:56 SamSam 3135 silver badges17 bronze badges 3- 1 On each frame, check if a vector the length of you sprite speed intersects with the object. – Andrei Nemes Commented May 9, 2013 at 12:59
- 2 You might want to consider asking this on Game Development. – zzzzBov Commented May 9, 2013 at 15:57
- Also related: stackoverflow./questions/7364884/… – JayC Commented May 9, 2013 at 18:50
3 Answers
Reset to default 2That's a generally a hard problem and for high-quality solution something like Box 2D library will be useful.
A quick and dirty solution (that gives false positives on diagonally moving objects) — check collision between bounding boxes that cover position of object in current and previous frame.
Instead of a.x
use min(a.x, a.x - a.velocity_x)
, instead of a.x + a.width
use max(a.x + a.width, a.x + a.width - a.velocity_x)
, etc.
If the object that is moving fast is small (a bullet), then test collision between line (from its origin to origin + velocity) and boxes of other objects.
You should use the whole area swept (in the update interval) by the moving object as the bounding box to check against the obstacle.
check this out. try moving rect 1 with arrow keys and if it touches rect 2 it will alert "collided".
var rect1x = 0;
var rect1y = 0;
var rect1height = 10;
var rect1width = 10;
var rect2x = 200;
var rect2y = 0;
var rect2height = 10;
var rect2width = 10;
var speedX = 0;
var speedY = 0;
var ctx = document.getElementById("canvas").getContext("2d");
var interval = setInterval(function() {
document.addEventListener("keydown", function(e) {
if (e.key == "ArrowLeft") {
speedX = -1;
}
if (e.key == "ArrowRight") {
speedX = 1;
}
if (e.key == "ArrowUp") {
speedY = -1;
}
if (e.key == "ArrowDown") {
speedY = 1;
}
});
document.addEventListener("keyup", function() {
speedX = 0;
speedY = 0;
});
ctx.clearRect(rect1x, rect1y, rect1width, rect1height);
rect1x += speedX;
rect1y += speedY;
ctx.fillStyle = "blue";
ctx.fillRect(rect1x, rect1y, rect1width, rect1height);
ctx.fillStyle = "red";
ctx.fillRect(rect2x, rect2y, rect2width, rect2height);
if (((rect1x + rect1width > rect2x) && (rect1x < rect2x + rect2width)) && ((rect1y + rect1height > rect2y) && (rect1y < rect2y + rect2height))) {
clearInterval(interval);
alert("collided");
}
}, 0);
<canvas id="canvas" height="400" width="400" style="border: 1px solid black"></canvas>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745548534a4632454.html
评论列表(0条)