Estoy trabajando en un simple juego de rompecabezas basado en bloques.
El juego consiste básicamente en mover bloques alrededor del área de juego, por lo que es una simulación de física trivial. Sin embargo, mi implementación, en mi opinión, está lejos de ser ideal y me pregunto si puede darme algunos consejos sobre cómo hacerlo mejor.
He dividido el código en dos áreas: lógica de juego e interfaz de usuario, como lo hice con muchos juegos de rompecabezas:
- La lógica del juego es responsable de las reglas generales del juego (por ejemplo, el sistema de reglas formales en el ajedrez)
- La interfaz de usuario muestra el área de juego y las piezas (por ejemplo, tablero de ajedrez y piezas) y es responsable de las animaciones (por ejemplo, movimiento animado de piezas de ajedrez)
La lógica del juego representa el estado del juego como una cuadrícula lógica, donde cada unidad es el ancho / alto de una celda en la cuadrícula. Entonces, para una cuadrícula de ancho 6, puede mover un bloque de ancho 2 cuatro veces hasta que colisione con el límite.
La interfaz de usuario toma esta cuadrícula y la dibuja convirtiendo tamaños lógicos en tamaños de píxeles (es decir, la multiplica por una constante). Sin embargo, dado que el juego apenas tiene lógica de juego, mi capa de lógica de juego [1] no tiene mucho que hacer, excepto la detección de colisiones. Así es como funciona:
- El jugador comienza a arrastrar una pieza.
- La interfaz de usuario solicita la lógica del juego para el área de movimiento legal de esa pieza y permite que el jugador la arrastre dentro de esa área
- El jugador suelta una pieza
- La interfaz de usuario ajusta la pieza a la cuadrícula (para que esté en una posición lógica válida)
- La interfaz de usuario le dice a la lógica del juego la nueva posición lógica (a través de métodos mutantes, que prefiero evitar)
No estoy muy contento con eso:
- Estoy escribiendo pruebas unitarias para mi capa de lógica de juego, pero no para la interfaz de usuario, y resultó que todo el código complicado está en la interfaz de usuario: evitar que la pieza colisione con otros o el límite y encajarlo en la cuadrícula.
- No me gusta el hecho de que la interfaz de usuario le dice a la lógica del juego sobre el nuevo estado, prefiero que llame a un
movePieceLeft()
método o algo así, como en mis otros juegos, pero no llegué lejos con ese enfoque, porque la lógica del juego no sabe nada sobre el arrastre y el ajuste que es posible en la interfaz de usuario.
Creo que lo mejor sería deshacerme de mi capa de lógica de juego e implementar una capa de física. Tengo algunas preguntas al respecto:
- ¿Es común esta capa de física o es más típico que la capa de lógica del juego haga esto?
- ¿El ajuste a la cuadrícula y al código de arrastre de piezas pertenecerían a la interfaz de usuario o la capa de física?
- ¿Una capa física de este tipo normalmente funcionaría con tamaños de píxel o con algún tipo de unidad lógica, como la capa lógica de mi juego?
- Una vez vi una detección de colisión basada en eventos en la base de código de un juego, es decir, el jugador simplemente arrastraba la pieza, la interfaz de usuario lo mostraba obedientemente y notificaba al sistema físico, y el sistema físico llamaba a un método onCollision () en la pieza una vez que se detecta una colisión. ¿Qué es más común? Este enfoque o preguntando por el área de movimiento legal primero?
[1] capa probablemente no sea la palabra correcta para lo que quiero decir, pero el subsistema suena exagerado y la clase es errónea, porque cada capa puede consistir en varias clases.