¿Cómo manejar la física de plataformas móviles en un juego de plataformas?

8

Entonces, después de algunas horas de búsqueda en Internet, todavía tengo que encontrar una respuesta agradable sobre cómo manejar plataformas móviles en un juego de plataformas 2D. Así que decidí hacer un prototipo simple donde interactúes con 2 plataformas diferentes, una que se mueve verticalmente y otra horizontalmente. Me encantaría obtener ayuda para analizar y ver qué no funciona y cómo solucionarlo. He enviado el archivo .fla + .as archivo a continuación, acompañado con un enlace al .swf jugable.

El objetivo es hacer que el Héroe interactúe con las plataformas como si fueran objetos sólidos sobre los que pueda pararse, empujarse, saltar sobre / debajo, etc.

Los problemas con mi prototipo son estos:

  • Cuando te paras en la plataforma que se mueve horizontalmente, sin moverte (sin tocar ninguna tecla), el Héroe se mueve junto con la plataforma, pero con un ligero retraso, el héroe se desliza un poco hacia atrás.

  • Cuando te paras en la plataforma en movimiento horizontal y saltas, te mueves junto con la plataforma en el aire (algunos juegos prefieren tenerlo así, pero no se siente natural y no se quiere aquí). Lo que podría ser causado por el héroe que retiene la velocidad en el eje X desde la plataforma.

  • Cuando saltas hacia la parte inferior de la plataforma en movimiento vertical, mientras la plataforma se mueve hacia abajo, te hundes dentro de ella por un breve segundo. El héroe penetra como si la colisión no existiera por un momento.

  • Cuando saltas sobre una plataforma que se mueve verticalmente, la velocidad en el eje Y se mantiene, por lo que cuando sales de la plataforma, caes a una velocidad más alta. Con la velocidad de la velocidad retenida, se agrega + gravedad (esto se debe principalmente a que no puedo encontrar una manera de restablecer la velocidad en el eje Y a 0 cuando aterrizas en la plataforma, sin que el jugador se congele en el aire).

Soy un programador novato, así que estoy seguro de que hay MEJORES formas de hacer esto, y me encantaría escucharlos a todos. Cualquier idea sobre cómo mejorar el código u otros métodos en los que puede implementar plataformas móviles en un juego basado en Tile es bienvenida. Al final, estoy tratando de encontrar una forma sólida de manejar plataformas móviles en plataformas 2D.

SWF jugable: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.html (moverse con las teclas de flecha, saltar con la tecla X, correr con la tecla Z)

Código fuente AS-file: http://dl.dropbox.com/u/28271061/Platformerhowto.as

SourcefileFLA: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.fla

Si prefiere leer el código a través de Pastie en línea: http://pastie.org/2266764

Niño
fuente
Relevante (duplicado improbable): ¿Cómo manejo las plataformas móviles en un juego de plataformas? .
doppelgreener
Leí ese hilo, pero como no uso nodos de ninguna manera, parece que no resolvió el problema. El juego que estoy construyendo está basado en mosaicos, pero las plataformas móviles se implementarán como anteriormente (movimiento libre). El uso de nodos requeriría una reescritura de mi motor en su conjunto, en el que ya pasé mucho tiempo. Supongo que esperaba que alguien mirara el código y ofreciera una solución similar a la propuesta, o encontrara una mejora en el código.
Niño
Usted podría ser el uso de nodos una vez que se implemente esta solución a las plataformas móviles, incluso si ese es el único lugar de usarlos. Resolvería su problema de deslizamiento.
doppelgreener
2
"(algunos juegos prefieren tenerlo así, pero no se siente natural y no se quiere aquí)" ¿Cómo no se "siente natural"? Google Inertia and Momentum ...
Riki
1
@Felheart, natural en términos de juego, no en el mundo físico real. Si juegas a Super Mario Bros o cualquiera de los juegos de plataformas clásicos, notarás que NO conservan el impulso al saltar sobre plataformas en movimiento. Altera la sensación de estar de pie e interactuar con una plataforma en movimiento.
Niño

Respuestas:

17

Separemos su problema en sus problemas distintos ...

Una palabra sobre la calidad del código

Tu código actualmente tiene tus plataformas controlando directamente la velocidad de tu jugador e incluso la constante de gravedad del mundo . Es hacky, y es de procedimiento cuando debe estar orientado a objetos. Una vez que comiences a expandir este juego, las cosas se pondrán feas rápidamente .

Necesita refactorizar su código. Implemente una clase de jugador, una clase de plataforma y una clase de piso. Separe sus preocupaciones: haga que el jugador interprete los controles del teclado y controle cómo corre y salta, y haga que las plataformas alteren su impulso según sea necesario (agregando su propia velocidad a la velocidad ya determinada del jugador, cuando sea necesario).

Haga que su jugador determine dónde está en lo que respecta a un objeto de tipo piso (las plataformas y los pisos tendrían un BodyType = BodyTypes.Flooro algo así) y determinar por sí mismo dónde está en relación con el objeto, cómo debe reaccionar y si está cayendo o no. en el piso.

Esto puede merecer un tema separado ya que es un tema bastante diferente de todo lo que has mencionado. Sin embargo, tendrás que hacerlo en algún momento.

Inercia horizontal / vertical al salir de una plataforma

Para resolver sus problemas de velocidad vertical y horizontal, tenga en cuenta dos cosas:

  • Con respecto a la velocidad horizontal: su código solo establece la velocidad horizontal en 0 cuando el jugador toca el suelo (en la línea 200 de Pastie) o una plataforma.
  • En cuanto a la velocidad vertical: su jugador tiene una aceleración de caída constante. Cuando sale de la plataforma vertical, esta aceleración descendente se sigue sumando a su movimiento ya descendente.

Su jugador simplemente sufre de inercia : su impulso se mantiene hasta que algo lo detiene.

Solución: Ambos problemas se resolverían con la solución de jSepia a ¿Cómo manejo las plataformas móviles en un juego de plataformas? ya que separaría completamente el proceso de movimiento del jugador de cómo las plataformas lo mueven. Simplemente no caerías más rápido caminando desde una plataforma vertical y no preservarías tu impulso horizontal saltando de una horizontal, porque las plataformas ya no afectarán vx y vy de tu jugador .

Nota: Es posible que tenga algunas dificultades para implementar la solución de jSepia antes de que se refactorice su código.

Deslizarse de lado a lado alrededor de la plataforma horizontal

Su jugador no se mueve horizontalmente tan rápido como se mueve la plataforma. No es obvio para mí por qué. Este problema probablemente también se resolvería implementando la solución de jSepia y refactorizando adecuadamente su código (este último simplemente haría obvia la causa).

Detección de colisión: superposición con la plataforma vertical

Vea la línea 381 de Pastie: cada paso es restablecer la vy del jugador a 0 siempre que el jugador colisione con la parte inferior de la plataforma vertical. En el siguiente paso, vy aumenta con la aceleración de la gravedad y luego el jugador se mueve (y luego se restablece a 0 nuevamente).

Esto significa que mientras su jugador colisione con la parte inferior de la plataforma, se moverá hacia abajo a una velocidad constante (la constante de gravedad). La plataforma vertical es más rápida que eso, por lo que se superpone. Si la plataforma vertical se moviera a una distancia mayor, se deslizaría a través de él hasta que el jugador se registrara como parado en la plataforma.

Solución: no restablezca la vy del jugador a 0. Simplemente configure la vy del jugador a la velocidad vertical de la plataforma ( si la plataforma se desplaza hacia abajo ). Su jugador se alejará de la plataforma vertical al menos tan rápido como la plataforma y acelerará alejándose de ella.

doppelgreener
fuente
¡Excelente! En primer lugar, gracias por la solución para saltar y penetrar en la plataforma vertical (¡funciona!). Y segundo, tienes razón, el código es terrible en este estado. Aunque este no es el juego en sí mismo, este es un prototipo rápido hecho para experimentar y comprender mejor las plataformas móviles. Sin embargo, si voy a traducir esto al código de los juegos reales, debería mantener un código más estructurado y orientado a objetos. Alisará la transferencia. Ahora, con respecto a la solución jSpeias, creo que obtengo el concepto de árbol de nodos, es solo que no sé cómo implementarlo correctamente.
Niño
Mi primer pensamiento es hacer valores booleanos que describan el estado de los jugadores, como: "onFloor", "onPlatform", "onGround", "falling", "jumping", etc. Y luego ejecutar una instrucción if en el Evento enterFrame que comprueba el estado actual y cambia las propiedades de los jugadores en consecuencia (?) Por ejemplo: if (Hero.onPlatform == true) {Player.x = platform.x (en relación con los jugadores x globales);}. Algo de esa manera.
Niño
Estoy trabajando en ello mientras hablamos, pero al mismo tiempo estoy separando el código en diferentes clases como sugirió, lo que también es un poco confuso (comunicar entre clases de plataforma / colisión / jugador es alucinante).
Niño
@Kid: Playertiene un método GetPositiony variables internas parent(para su nodo padre) y position(para su posición con respecto a su padre). Player.GetPosition()vuelve position + parent.GetPosition(). Su padre hace lo mismo hasta que llegas a la raíz del árbol: el nodo mundial. Cuando tu jugador se mueve, solo tratas con la positionvariable privada . Su jugador se dibuja en la pantalla del juego según GetPosition()el valor de. Te dejaré descubrir cómo la transición entre nodos. ;)
doppelgreener
Tener una clase de jugador que sepa cómo modificar su propia velocidad, por supuesto, no respalda la separación de preocupaciones
Andy Ray