¿Cómo puedo detectar al jugador aplastado en un juego de plataformas 2D?

19

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.

ingrese la descripción de la imagen aquí

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í:

ingrese la descripción de la imagen aquí

IanLarson
fuente

Respuestas:

34

Creo que tendrás que tomar en cuenta el movimiento de la caja . Es decir, solo aplastar si la caja se mueve hacia el jugador.

Esto es similar a otros problemas en plataformas, donde el movimiento es importante. Por ejemplo, para las plataformas por las que puedes saltar desde abajo, no compruebes la colisión si el jugador se mueve hacia arriba.

Entonces, un bloque puede aplastar al jugador desde arriba solo si el bloque se mueve hacia abajo; desde abajo solo si el bloque se mueve hacia arriba; desde la izquierda solo si el bloque se mueve hacia la derecha, y así sucesivamente.

congusbongus
fuente
13
+1 Tenga en cuenta que el bloqueo está actuando aquí, no el jugador. Entonces, si marca si la casilla está aplastando al jugador en lugar de verificar si el jugador está siendo aplastado, el problema debería ser más fácil de resolver
Niels,
¿Qué pasa cuando los bloques no se mueven? Ahora me doy cuenta de que puse flechas en los bloques en el n. ° 5, pero se suponía que eran dos bloques estacionarios.
IanLarson
Si decides que los bloques estacionarios no deberían aplastarse, solo asegúrate de que el jugador no esté atascado y pueda moverse fuera del camino.
congusbongus
Argh, odio ser aplastado por dos objetos que en realidad se están alejando el uno del otro, solo porque lo hice perfecto en píxeles y marcos y el desarrollador fue perezoso.
rinoceronte
9

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í.

Pedro es
fuente
1
¿Te refieres a puntos de verificación de aplastamiento de adición "dentro" de los límites de los puntos de colisión? El problema que veo con eso es que la resolución de colisión ocurrirá en cada eje cuando uno de sus puntos de colisión se "dispare" antes de que el objeto tenga la oportunidad de alcanzar los puntos de control de aplastamiento interno.
IanLarson
6

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 .

Graham
fuente
3
Punto menor: no sabes cómo es su sprite. Por lo que sabemos, podría ser exactamente como se muestra en las imágenes anteriores, por lo que los casos 3 y 5 pueden ser completamente válidos.
Alex
1
Alex tiene razón. Hice una edición para aclarar. Estoy de acuerdo en que no hay nada peor que cajas de colisión inconstantes. Creo que entiendo su punto sobre no usar puntos separados para los diferentes ejes. Si lo hago, eso cambiaría el ejemplo anterior de tener ocho puntos a cuatro, uno en cada esquina, ¿correcto? De hecho, he hecho algunas pruebas con eso en mente (con resultados menos que deseables), pero dudo mucho en hacerlo, ya que tener las esquinas "separadas" logra el comportamiento que busco casi a la perfección. Estos son realmente los únicos escenarios problemáticos con los que me he encontrado.
IanLarson
0

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.

Zamfi
fuente
0

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.

Super gato
fuente
0

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.

Acumulacion
fuente
0

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:

  1. 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.

  2. Si el aplastamiento se confirma la segunda vez, proceda con el aplastamiento.

Nikaas
fuente