Estoy comprobando la colisión de un personaje de plataformas como se muestra en el n. ° 1. Los puntos rojos son los píxeles que están marcados y las líneas grises indican los ejes a los que pertenecen. Me gustan los resultados que obtengo al verificar la colisión de esta manera (versus, por ejemplo, el cuadro delimitador). Todo funciona exactamente como me gustaría, excepto por un problema: la detección de aplastamiento.
En las siguientes imágenes, el cuadro azul claro representa el suelo, el cuadro naranja es un objeto y las flechas indican la dirección del movimiento.
La solución simple para detectar cuándo el jugador es aplastado es ver si los puntos de colisión en lados opuestos se disparan. Si lo están, el jugador está siendo aplastado. En el n. ° 2, puede ver un escenario de enamoramiento normal. El jugador está conectado a tierra y los puntos de colisión superiores se cruzan con el objeto que cae. Esto desencadena un flechazo.
# 3, 4 y 5 presentan escenarios problemáticos. En el n. ° 3, el jugador se mueve hacia el objeto, que se mueve hacia arriba. Un punto de colisión del lado derecho está golpeando el objeto, causando una colisión y deteniendo al jugador.
Ahora, si el objeto continúa subiendo y el jugador continúa moviéndose hacia la derecha (como se muestra en el n. ° 4), el objeto despeja el punto de colisión del lado derecho del jugador y el jugador se mueve hacia la derecha. Pero ahora, una vez hecho esto, el objeto está cruzando un punto de colisión superior causando un aplastamiento vertical no deseado.
Un escenario similar se muestra en el n. ° 5. Dos objetos están lo suficientemente separados como para despejar los puntos de colisión inferiores, lo que permite que el jugador caiga, pero no tanto como para permitir que los puntos de colisión laterales se despejen, causando un aplastamiento horizontal no deseado.
He estado investigando una solución, pero nada de lo que se me ocurrió ha funcionado particularmente bien, por lo que me pregunto si alguien por ahí tiene una idea o una idea de cómo resolver estos problemas.
Para aclarar alguna confusión, los puntos de colisión rojos estarían dentro del sprite y las líneas grises solo se usaron para denotar el eje relevante para cada punto de colisión. Por ejemplo, si el sprite del personaje fuera un simple cuadrado verde, los puntos de colisión se verían así:
Haga que los puntos de "prueba de aplastamiento" estén dentro del cuadro gris que se muestra en su imagen # 1, es decir, mate al jugador solo si detecta un golpe en uno de los píxeles allí.
fuente
Como alguien que creció con plataformas de los 80, mi primer comentario es que los puntos de contacto deben estar exactamente en el sprite, no en ningún lugar fuera de él. Hubo pocas experiencias más frustrantes que morir cuando un arma / triturador / enemigo estaba claramente a varios píxeles de distancia de tu personaje, y ese tipo de experiencia es lo que detiene a las personas que juegan.
Con eso en mente, la idea de tener puntos separados para la colisión horizontal y vertical simplemente no vuela. Entonces sus casos 3 y 5 no existen.
En cuanto a la detección de colisiones, como se ha dicho anteriormente, debe tener en cuenta la dirección del movimiento y debe tener en cuenta dos ejes de movimiento. Si una trituradora está caída, el jugador no debe poder caminar hacia adelante, debe actuar como una pared. Entonces, con los puntos de detección horizontales y verticales en el mismo lugar, no podría obtener el caso 4, incluso antes de agregar la dirección del movimiento a la mezcla.
La trituradora que se mueve hacia arriba agrega complejidad adicional. Si es tan rápido que el jugador no tiene oportunidad de escapar, entonces está bien. Pero si es más lento, el jugador esperará poder correr sobre la plataforma ascendente y saltar desde el otro lado. El jugador sprite se eleva hacia arriba en la trituradora, y la detección de aplastamiento ocurre en el techo .
fuente
Puede hacer que el objeto sea "más duro" que el suelo, lo que significa que, en caso de colisión, el jugador es empujado "hacia" el suelo, en lugar de ser empujado "hacia" el objeto en movimiento.
Esto supone que el jugador no es capaz de empujarse "dentro" de los objetos o del suelo.
fuente
Si puede detectar la superposición de objetos sin tener que esperar a que se muestren, un enfoque simple es procesar el movimiento para el jugador y otros objetos de forma independiente, un píxel a la vez, con controles de colisión separados después. Si el jugador se mueve libremente y chocaría con su objeto como resultado de dicho movimiento, retroceda. Si se produce una colisión con un objeto como resultado del movimiento del objeto, verifique si el jugador puede moverse en la misma dirección que ese objeto. Si es así, mueve al jugador. De lo contrario, maneje la situación de "aplastamiento" de manera apropiada (dañando o matando al jugador y / o moviendo el objeto colisionador hacia atrás, dependiendo del contacto).
Por cierto, si solo un número limitado de combinaciones de formas pueden colisionar, puede ser útil calcular previamente los mapas de bits de "detección de colisión" de modo que si un píxel se establece en el primer sprite en el desplazamiento (x1, y1) y en el segundo en el desplazamiento (x2, y2) del segundo, el píxel en el desplazamiento (x1-x2, y1-y2) se establecerá en el mapa de colisión. Tal mapa de colisión precalculado permitirá detectar colisiones entre los dos sprites al verificar el estado de un solo píxel en el mapa de colisión.
fuente
Se necesitan dos objetos para aplastar a un jugador. Su detección de aplastamiento debe verificar si el jugador está entre dos objetos, el espacio entre ellos es igual al tamaño del jugador y la distancia disminuye.
fuente
Me parece que ahora estoy trabajando hasta ahora. No requiere información "externa" sobre el movimiento de las trituradoras y resuelve el problema de los falsos positivos. Cuando se detecta un falso positivo, se trata como una colisión (y esto es lo que realmente es):
La idea es: por qué verificar si la trituradora se está moviendo cuando realmente nos importa si el personaje se está moviendo. Ambos pueden responder si el enamoramiento es falso positivo causado por el propio movimiento del personaje o el verdadero enamoramiento por el movimiento del objeto triturador.
Si el personaje se está moviendo y está aplastado (colisiones en lados opuestos para el cuadro entrante), verifique nuevamente si hay aplastamiento en las coordenadas del último cuadro / iteración:
Si no se confirma nuevamente, se debe al propio movimiento del personaje y el personaje debe volver a las últimas coordenadas de cuadro / iteración como una colisión.
Si el aplastamiento se confirma la segunda vez, proceda con el aplastamiento.
fuente