Web Analytics

turnos I

Lo malo de estar vivo es que unomira hacia atrás y no ve nada más que fallos.

Recogí mi código viejo. Tengo un cuatro en ralla hecho por turnos con el que se puede jugar por red en teléfonos android. Hice unas milongas para poder jugar en escritorio, sin depender del dispositivo vamos. Así pude programar la lógica independiente de la presentación. Retomando la cosa ahora veo que es horrible. La presentación en android está chula (dentro de lo que doy de si, que las cosas visuales nunca se me han dado bien).

Pero es que en un equipo de uno, mi  código es inmantenible, demasiado complejo de modificar, probar y de todo. Lo veo ahora y vaaaaya puta mierda que me inventé. Además la idea original era poder tener una especie de framework base con el que poder soltar más juegos en menos tiempo.

Creo que voy a hacer un reboot. Voy a intentar pensarlo desde cero pero a ver si sustituyo el escribir por el pensar para no llegar a donde llegué con un engendro como ese. Prefiero ni analizar si puedo reutilizar algo y hasta el dibujo de los mapas, tiles y sprites casi que lo sustituiré por alguna librería que las hay muy buenas para android.

¿Cómo carajo aplicar MVC a un juego en Android?

Está chunga la cosa. En android mvc se implementaría como en j2me o swing, con sus listeners y sus cositas que te hacen avanzar en lo visual a velocidad del rayo. Pero hay mucho más factor a tener en cuenta en el percal en que me quiero mover. De hecho debería tomar las bases de cualquier juego y abstraerme para poder tener un esqueleto básico que completar sin joder demasiado el rendimiento (no mucha instancia, no mucha lógica de una vez, todas esas cosas). Además, con un tres en raya, la lógica es simple, con un monopoly, la cosa va empeorando y un colonization puede ser mortal.

habría que unificar un ciento de cosas que entiendo básicas para hacer esto por las buenas sin empezar a soltar código por que sí. A ver si listo todo y no me dejo nada para empezar a filosofar sobre ello:

  • un juego debería funcionar sin entorno gráfico o ser independiente del mismo
  • puede haber n jugadores
  • un jugador puede ser NPC, jugador local o jugador remoto
  • un turno se compone de turnos a su vez
    • en el cuatro en raya habrá un sólo movimiento por turno
    • en monopoly el jugador mueve su ficha y luego puede comprar, vender...
    • en algo tipo colonization o advance wars hay muchas fichas a mover y cada una puede mover y luego atacar, cargar, reparar, desplegar unidades cargadas
  • los turnos deben de poder persistirse en un medio físico
    • un turno debe tener una lógica común en todos los clientes y unos parámetros que se puedan separar de esta.
    • un turno debe poder visualizarse igual en el cliente que lo genera que en el que lo recibe en caso de se rmultijugador
  • la presentación debe ser independiente no sólo del dispositivo para facilitar la programación y prueba de la lógica de negocio sino de quién lo esté viendo
    • está claro que ningún jugador verá lo mismo pero deben poder llegar a tener la misma calidad de percepción del juego, no me explico bien pero creo que yo lo tengo claro.
    • Esto incluiría lo que cité antes de que un jugador mueva una pieza, vea la animación del ataque y los resultados. Su oponente debería recibir la misma animación aunque el turno ya haya acabado hace días cuando el primero lo ejecutó.
  • un juego por turnos no tiene por qué ser síncrono
    • Nadie necesita estar mirando al tablero para que su oponente adelante un peón. moverá el peón y ya lo veremos cuando volvamos a mirar al tablero. Se deberá ver la animación completa con sus resultas.
  • aunque no haya un tablero, piezas o toda la pesca, deberíamos tenerlo en cuenta sea cual sea el juego.
    • ¿hay tablero para aquel famoso adivina un número? ¿Y para estos juegos print and play que consisten en tirar dados y anotar cálculos?
    • pues no hay pero hay que escupir en la cara del usuario los resultados de alguna manera
    • esto entra en terrenos visuales aunque se puede tomar el tablero o escena como un conjunto de datos que ya se verá más tarde cómo pintar.

Si me dejo algo lo iré añadiendo.

Partiendo de toda esta mierda, ¿a dónde puedo llegar? Uf... He estado viendo frameworks, que los hay por ahí, para implementar juegos por turnos, te van aislando de unos y otros componentes. Pero son impracticables en un teléfono actual, van pasando xmls o cosas así. Esto debería ser más sencillo, carajo, ya estoy sudanding y no tengo más que una lista preliminar de requisitos del framework, ni siquiera un juego básico, jaja.

Vamos a empezar por pensar que no sabemos dónde se va a pintar el juego y que tendremos los datos necesarios para poner la mesa. La repampolla. Porque ocurre que en algún sitio hay que poner una lógica para pintar, ¿donde? Pues según MVC en la V. M sería el modelo, los datos del tablero, V la vista, el cartón a poner en el tapete, las cartas, los dados... 

C es el controlador. Dios mueve al jugador y este la pieza. Pues el controlador no es ninguno de esos. Dios estará regido por el controlador. Es un ente supremo y superior a todo sin el que el juego no tiene lógica. Por mucho que Dios o el jugador quieran, el peón no puede mover de tres en tres, el seis de triunfos puede más que cualquier as de otro palo, etc. El controlador debería conocer la lógica del juego y no salirse ni permitir salir a nadie de la misma. El resto es cartón y tinta.

¿Cuándo y cómo pintar? Carajo qué dilema. Es que es uno de los fallos de mi anterior implementación y, además, es una jodienda básica para el tema en cuestión. Vamos a un caso básico de una aplicación en consola:
mientras no haya que parar
pinta
procesa entrada de usuario
fin mientras.

Así de fácil. Carajo. pero no va tan bien cuando componetizas el tema. Vamos a ponerlo un poco más complicado:
mientras no haya que salir de la aplicación
pintar partidas guardadas
procesar entrada de usuario--> loadSavegame
mientras no haya que salir del juego
pinta
procesa el turno de un jugador
fin mientras juego
fin mientras app

Ya la jodimos. La frasecita esa "procesa el turno de un jugador" se las trae. Y el Pinta puede ser la rehostia porque no es poner la ficha en la casilla, se tiene que actualizar el tablero entero, con animaciones y que no se pierda la entrada del usuario. Se podría estar escribiendo, pulsando en el zoom y la animación corriendo sin detenerse. Me trae de cabeza. Porque, además, ¿implica que si se anima algo tengamos que modificar el modelo para que se pinte en esa posición? ¿Quién provoca que se dispare esa animación?

Vamos por partes. El controlador debería disparar esa animación pero tenemos un conflicto entre presentación y modelo. Si usase una librería para la representación gráfica, prácticamente no me quedaría otra que hacer que una ficha, una pieza cualquiera de mi juego, heredase o agregase la funcionalidad de su representación gráfica de una clase dada por el framework. El controlador estaría, por tanto, a la vez cambiando el modelo y la vista. Mmmh... lajodimos luis.

Vamos a pensar en no romper las capas...