Plataformas 2D sin nombre.

sergilazaro

Estoy trabajando en ratos libres en un plataformas en Unity 2D. Por ahora no tengo pensado hacer nada de juego, sólo quiero ir implementando las físicas 2D, los elementos básicos de gameplay, y cosillas así. Cuando lo tenga más avanzado ya pensaré en hacer un juego con él (tengo algunas ideas pero no quiero complicarlo por ahora).

Lo empezé poco antes de la MV gamejam, no terminé de hacer un juego en si, y lo dejé a medias. Desde entonces lo he retomado para ir mejorando ciertas cosillas.

Lo que tenía cuando acabó el deadline de la jam era esto:

La mecánica básica iba a ser eso, aplastar bloques en un lado para que salgan en el extremo opuesto. Pero como he dicho, eso lo dejo aparte por ahora.

Mi objetivo por ahora es llegar a tener un motor básico 2D, más los elementos básicos, que permitirían implementar un juego como Spelunky. Que se controle parecido, vamos.

El tema es para compartir algunos detalles para quien le interese, pero especialmente para mantener un diario y forzarme a ir avanzando, aunque sea 30min al día. A ver si es verdad.

2
sergilazaro

Lo que tengo implementado hasta ahora es:

  • Físicas 2D predictivas. Implementadas a mano encima de Unity, porque usar un motor de físicas basado en fuerzas/impulsos es una mala idea para un plataformas. También porque sólo quiero AABBs (rectángulos sin rotación). También porque es una espinita que tengo clavada desde hace tiempo y quiero hacerlo y aprender.

    Físicas predictivas significa que en vez de mover los objetos, detectar solapamientos y corregirlos, uso el Separating Axis Theorem para detectarlos antes de que ocurran, y colocar los objetos en el punto/momento de colisión y seguir en la dirección de deslizamiento.

  • Movimiento básico de saltar, correr, agacharse, más el SMASH que tenía implementado para la jam.

  • Squash and stretch, para simular la deformación de objetos manteniendo el área, dando la impresión de animación básica.

  • Triggers (con eventos Enter, Stay y Exit).

  • One-way Platforms. Se puede subir a ellas pero no descender, por ahora.

  • Escaleras verticales. No terminan de funcionar bien aún.

NO implementado aún:

  • Soporte para más de un objeto moviéndose. Ahora mismo todo es estático excepto el personaje.
  • Rampas de ningún tipo.
  • ... un wishlist enorme de cosas que quiero añadir.

Se ve algo así:

1
arrecio

Buena iniciativa, seguiré tus progresos.

Sobre lo de que usar el motor de fuerzas impulsos es una mala idea para un plataformas no lo comparto. Lo uso en mi Castle Escape (dispoble para testing en android en https://play.google.com/store/apps/details?id=com.zbgames.thecastleescape&hl=es) y el box2d come menos de 2 ms por cada segundo. El autor se lució haciéndolo que no se si sabeis que es programador de físicas en blizzard, los ragdoll de diablo 3 son suyos por ejemplo. Cierto que un plataformas no lo necesita pero tampoco lo veo una mala idea, ahorra trabajo para aquel que no haya hecho nunca ninguno y no tenga su propia libreria de colisiones y sensores preparada.

1 respuesta
sergilazaro

#3 Bueno, era una afirmación tajante, evidentemente no es tan sencillo. La idea es que si intentas hacer un juego en el que la respuesta del mundo y los objetos y personajes tiene que ser perfecto, y quieres poder definir parámetros que no son puramente físicos de bajo nivel (masa, coeficientes, cosas así) sino más de comportamiento (velocidad máxima, altura máxima, tiempo en el aire...), quizás tiene más sentido pasar un poco de la realidad y usar algo más ad-hoc.

En el artículo que enlazé hay algunos ejemplos de casos concretos en los que Box2D podría tocar un poco los huevos, mientras que una solución específica diferente lo podría tener fácil por defecto.

Encima, yo en concreto estoy reimplementando cosas que podría usar de Unity, como los triggers, pero ya que estoy haciendo un "motor de físicas 2D", he ido a hacerlo todo. Más o menos, la idea es que teóricamente pudiera usar el mismo código C# tal cual fuera de Unity sin tener que hacer muchos cambios (excepto los callbacks de Updates, las modificaciones de Transforms y los tipos básicos rollo Vector3, etc.). No porque lo vaya a hacer nunca, sino por la propia práctica.

Y por supuesto, que si sólo quisiera hacer un juego plataformas no me mataría con esto, usaría algo ya hecho. El problema de tener este tipo de inquietudes es que te hace perder el tiempo que usarías para avanzar proyectos reales :)

Tentaculo

Muy buena pinta!!

Creo que con fisicas AABB hechas a mano es más que suficiente.
Yo he probado Box2D en móviles y no es lo más óptimo. En pc me imagino que estará mil veces más optimizado.

PD: Me encanta el efecto de gelatina que tiene el cuadrado :P

8 días después
sergilazaro

TL;DR: He implementado Spatial Hashing.

He avanzado un poco. Quería añadir una plataforma one-way a la parte superior de la escalera. Pero por la forma en que tenía implementadas las físicas ahora mismo no podía.

Hasta hoy, para buscar vecinos para encontrar colisiones utilizaba la grid de los tiles del mapa. Es decir, tengo un array 2D para pasar de ID de tile a el tile concreto. Esto tiene el inconveniente de que sólo hay un objeto por tile, y para hacer lo de la escalera necesito dos objetos en el mismo cuadro (el trigger de la escalera, y el bloque one-way).

Podría haber hecho la chapucilla de hacer que el array 2D contiene una lista de tiles, pero como igualmente iba a cambiar esto en algun momento, lo he hecho bien ya.

Como hasta ahora sólo hacia colisiones Player -> Mapa, para poderlo extender necesitaba algun tipo de sistema broad-phase para encontrar tanto vecinos estáticos como dinámicos. Podría haber implementado un quadtree pero al tener mapas acotados y que están ya en forma de grid, he preferido usar Spatial Hashing. Es bastante sencillo de implementar y como optimización ya irá bastante bien. No voy a pensar en eficiencia hasta que no sea un problema, está claro.

En esta imagen se pueden ver en rojo los objetos potenciales de colisión en este frame. El resto de gizmos son: En amarillo los triggers, lila las paredes de colisión (se hace culling de las paredes colindantes con otras paredes), y blanco para el hitbox del player.

3
20 días después
sergilazaro

He tenido un poco más de tiempo para acabar lo que tenía a medias.

He implementado una versión super sencilla de una State Machine. Para no complicarme por ahora hasta que no lo necesite, sólo consiste en un enum con unos cuantos estados. Las transiciones las hago manualmente, y donde me interesa hago un switch para hacer cosas diferentes dependiendo del estado actual.

Los estados son:

  • Standing: cuando se está en contacto con el suelo, moviéndose o no.
  • Jumping: si se ha saltado y se está en el aire.
  • Smashing: cuando se empieza el "smash" estando saltando.
  • Crouching: como standing, pero cuando se está agachado, también moviéndose o no.
  • Climbing: agarrado a una escalera.
  • Falling: cayendo, es decir, en el aire sin haber saltado.

Al principio tenía más pero con estos queda simple y ya cumple la función que es poder cambiar cosas más fácilmente.

Gracias a estos cambios, he podido acabar de implementar las escaleras: Te agarras apretando hacia arriba, de descuelgas cuando llegas al extremo inferior o si saltas, y no deja subir más si llegas encima del todo.

3
sergilazaro

Voy a mejorar un poco la física para poder coger rocas y lanzarlas. He probado de poner más objetos dinámicos para ver que el cambio que hice es correcto: las colisiones van bien con varios objetos moviéndose.

4
Hipnos

¿Qué tienes pensado hacer con el motor 2D?

sergilazaro

Quiero poder tener la base típica de un plataformas 2D, con los elementos básicos. Quiero implementar lo básico para aprender, y también para poder tener la barrera más baja para hacer jueguillos de plataformas. Es decir, que sólo haga falta arte, programar cosillas específicas, y hacer niveles (sé que nunca es tan sencillo, pero se me entiende).

Sé que hay cosas ya implementadas de este tipo, pero como me lo paso bien programando y pensando como hacer estas cosas, pues he tirado por aquí.

Más específicamente, tengo un juego en mente que creo que voy a empezar a implementar una vez tenga hecho lo que necesito. Pero no lo tengo muy definido aún. Más o menos voy a ir haciendo tres cosas en paralelo: implementar el "motor", definir el juego en términos de mecánicas, en papel, y intentar hacer algun mockup para la estética del juego.

rowualfo

Se ve genial! Le veo mucho potencial a la base que estas programando...a ver que se te ocurre hacer con ella :)

1 1 respuesta
sergilazaro

#11 Gracias :)

Bueno, ya que estoy, pongo esto aquí también, porque va conectado con los "mockups" y otras pruebas estéticas que quiero ir haciendo para el juego. Son pruebas de animación y partículas, no lo había probado nunca aún:


Estéticamente la idea que tengo es que todo esté basado en rectángulos, pero eso se tiene que ir probando y viendo que tiene sentido.

2 1 respuesta
Potito

#12 Me gusta mucho la antorcha :D

Pero si quieres basarlo en rectangulos porq hay triangulos por todas partes ? MUERTE AL TRIANGULO!

2 respuestas
sergilazaro

#13 Muerte a Euclides!

1 respuesta
GreyShock

#13 #14 di que no hombre, que son cuadrados rotados 45º xD

1 año después
sergilazaro

Desde hace unos días (luego de un año justo sin tocarlo) me he metido a arreglar algunos bugs de físicas que tenía, actualicé a la última versión de Unity, pasé a usar Sprites 2D en vez de quads, cambié todos los sprites para que fueran más molones, y añadí Image Effects que quedan muy bien.

Tadáaa!

Me encanta el efecto vignette + aberración cromática <3

I

Me mola, la idea me gusta bastante y visualmente se ve bien, solo que las escaleras dan un poco el cante.

1 respuesta
sergilazaro

He añadido el código que tengo a GitHub.

#17 Gracias! La estética es básicamente placeholders, la escena es de prueba para ir probando las físicas. Intenta ser algo inspirado en diagramas técnicos, estética neutra / genérica, etc.

1