O sistema de detecção de colisão Javascript não ignora colisões bloqueadas
Estou tendo problemas durante um desenvolvimento de minigame usandoEaselJS com o meu sistema de detecção de colisões e preciso da ajuda de alguém. O problema ocorre quando o herói (um bitmap de círculo) colide com um objeto e há outro objeto atrás do primeiro, o herói colide com os dois objetos, mesmo se a segunda colisão estiver bloqueada. Aqui está uma explicação da imagem:
A causa do problema é realmente simples, mesmo que o problema em si não seja:
Esse sistema de detecção de colisão é baseado na posição futura do círculo (e não na sua posição atual); se a próxima posição do círculo cruzar um retângulo, ele retornará. O problema é que, se a posição futura cruzar dois retângulos, o círculo saltará nos dois retângulos - mesmo se o movimento real do círculo estiver bloqueado por outro retângulo e não puder alcançar o segundo.
Atualizar: Observe que esse problema ocorre apenas quando a seta para cima está sendo retida devido à ordem de criação correta.
Aqui está o código javascript relevante:
rects.forEach(function (rect) { // Affect all rects
// Collision detection:
// (This MUST BE after every change in xvel/yvel)
// Next circle position calculation:
var nextposx = circle.x + event.delta / 1000 * xvel * 20,
nextposy = circle.y + event.delta / 1000 * yvel * 20;
// Collision between objects (Rect and Circle):
if (nextposy + height(circle) > rect.y &&
nextposx + width(circle) > rect.x &&
nextposx < rect.x + rect.width &&
nextposy < rect.y + rect.height) {
if (circle.y + height(circle) < rect.y) {
cls("top");
}
if (circle.x + width(circle) < rect.x) {
cls("left");
}
if (circle.x > rect.x + rect.width) {
cls("right");
}
if (circle.y > rect.y + rect.height) {
cls("bottom");
}
}
// Stage collision:
if (nextposy < 0) { // Collided with TOP of stage. Trust me.
cls("bottom"); // Inverted collision side is proposital!
}
if (nextposx < 0) {
cls("right");
}
if (nextposx + width(circle) > stage.canvas.width) {
cls("left");
}
if (nextposy + height(circle) > stage.canvas.height) {
cls("top");
}
});