LIBGDX MVC

De MediaWiki
Saltar a: navegación, buscar

UNIDADE 2: Modelo-Vista-Controlador

Modelo-Vista-Controlador

A miña idea inicial era non facer esta parte obrigatoria e poñer todo o control do xogo na clase PantallaXogo, facendo optativo o que vou explicar a continuación, pero resultaría demasiado complicado de manter as dúas opcións nun curso a distancia xa que o sitio onde van ir os métodos variaría.

A idea é crear unha clase Controladora que vai mover e controlar todo o que pasa no noso xogo. Quen non queira facer esta parte tería que implementar todos os métodos na clase PantallaXogo, pero eu recomendo facelo como vou explicar a continuación.

Empecemos:

Tal cal fixemos no exercicio anterior poderíamos establecer o movemento de todos os personaxes, pero nos estamos a seguir un modelo no que separamos o control (mover os gráficos) da súa visualización (render), e desta forma non o faríamos.

O concepto é moi sinxelo.


Dividimos o xogo en tres partes:

  • Modelo: onde están definidas as clases que nos serven de base para o noso mundo. Isto xa o estamos a facer agora. Serían as clases Mundo, Personaxe, Piexe, Gancho, Pescador.
  • Vista: aquí só se debuxan os obxectos que conforman o noso mundo e a cámara en base as súas propiedades de posición e tamaño.
  • Controlador: controla todo o que sucede no noso mundo e modifica as propiedades dos obxectos que pertencen ó Modelo.

A maiores imos ter unha zona de nome Pantallas que serán cada unha das pantallas do noso xogo e que terán as interfaces que permiten xestionar os eventos e que informarán á clase controladora de que evento se trata.


Polo tanto imos ter:

  • Paquete modelo: onde estarán as clases que nos van servir para gardar a información de cada personaxe do noso xogo. Aquí estará a clase Mundo e unha clase por cada tipo de personaxe que conforme o noso xogo (incluído disparos, plataformas,...).
  • Paquete renderer: clase que vai visualizar os personaxes do noso mundo. Só vai debuxar, non vai ningún tipo de control.
  • Paquete pantalla: clases que derivan da clase Screen e que van a implementar as interface´s que nos van permitir iteracionar co xogo (pulsar a pantalla e recoller dito evento) e chamar á clase Controladora informando de dito evento.
  • Paquete controlador: onde se atopan as clases que van encargarse de controlar todos os eventos (choque entre dous personaxes, disparo que alcanza a un inimigo,...) e recoller a información sobre a iteración do usuario coa pantalla dende a clase que se atopa no paquete pantalla.


Graficamente será algo parecido a isto:


LIBGDX Teoria 03.jpg


Agora por cada pantalla:


LIBGDX Teoria 04.jpg



Aplicando estes conceptos ó noso xogo:

  • Creamos o paquete com.plategaxogo2d.renderer e movemos a clase RendererXogo a dito paquete.
  • Creamos o paquete com.plategaxogo2d.controlador.
  • Dentro de dito paquete creamos a clase ControladorXogo.
  • Modificamos o constructor de dita clase para pasarlle un obxecto da Mundo xa que o imos necesitar para controlar os personaxes do noso mundo.
  • Creamos un método update cun parámetro delta que vai ser chamado pola clase PantallaXogo de forma continua.
  • Creamos dentro da clase PantallaXogo un obxecto da clase controladora (ó igual que fixemos coa renderer) e chamamos ó método update.


Traducido a código, creremos unha nova clase de nome ControladorXogo nun paquete novo de nome com.plategaxogo2d.controlador:

Código da clase ControladorXogo

  1. package com.plategaxogo2d.controlador;
  2.  
  3. import com.plategaxogo2d.modelo.Mundo;
  4.  
  5. public class ControladorXogo {
  6.         Mundo meuMundo;
  7.        
  8.         public ControladorXogo (Mundo mundo){
  9.                 this.meuMundo=mundo;
  10.                
  11.          }
  12.        
  13.         /**
  14.          * Vai chamar a todos os métodos para mover e controlar os personaxes
  15.          * Tamén xestionará os eventos producidos polo usuario e que veñen dende a clase PantallaXogo
  16.          * @param delta
  17.          */
  18.         public void update(float delta){
  19.                
  20.                
  21.         }
  22.  
  23. }


Código da clase PantallaXogo
Obxectivo: modificamos a clase para que chame á clase ControladorXogo.

  1. public class PantallaXogo implements Screen {
  2.  
  3.         private MeuXogoGame meuXogoGame;
  4.         private RendererXogo rendererXogo;
  5.         private ControladorXogo controladorXogo;
  6.        
  7.         Mundo meuMundo;
  8.  
  9.         public PantallaXogo(MeuXogoGame meuXogoGame) {
  10.                
  11.                 meuMundo = new Mundo();
  12.  
  13.                 this.meuXogoGame = meuXogoGame;
  14.                 rendererXogo = new RendererXogo(meuMundo);
  15.                 controladorXogo = new ControladorXogo(meuMundo);
  16.         }
  17.  
  18.         @Override
  19.         public void render(float delta) {
  20.                 // TODO Auto-generated method stub
  21.  
  22.                 rendererXogo.render(delta);
  23.                 controladorXogo.update(delta);
  24.         }
  25.  
  26.         ................

Movendo os gráficos co MVC

Agora para mover os gráficos só será necesario chamar o método update de cada personaxe e que sexa dito método o que cambie a posición en función da velocidade.

Cando a posición cambie, a clase RendererXogo visualizará a nova posición.

En código:

Código da clase ElementoMobil
Obxectivo: modificamos a clase para que mova o elemento móbil en función da velocidade.

  1. public class ElementoMobil extends Personaxe{
  2.  
  3.         public ElementoMobil(Vector2 posicion, Vector2 tamano, float velocidade_max) {
  4.                 super(posicion, tamano, velocidade_max);
  5.                 setVelocidade(velocidade_max);
  6.         }
  7.         @Override
  8.         public void update(float delta) {
  9.                 // TODO Auto-generated method stub
  10.                
  11.                 posicion.add((velocidade*delta),0);
  12. }
  13.  
  14. }


Código da clase Controlador
Obxectivo: chamamos ó método update de cada coche. O nome do método será controladorCoches xa que a parte de mover tamén terá código de control (visto posteriormente).

  1. public class ControladorXogo {
  2.  
  3.         Mundo meuMundo;
  4.  
  5.         public ControladorXogo(Mundo mundo) {
  6.                 this.meuMundo = mundo;
  7.  
  8.         }
  9.  
  10.         private void controlarCoches(float delta){
  11.                
  12.                 for(ElementoMovil coche: meuMundo.getCoches()){
  13.                         coche.update(delta);
  14.                 }
  15.                
  16.         }
  17.         /**
  18.          * Vai chamar a todos os métodos para mover e controlar os personaxes Tamén
  19.          * xestionará os eventos producidos polo usuario e que veñen dende a clase
  20.          * PantallaXogo
  21.          *
  22.          * @param delta
  23.          */
  24.         public void update(float delta) {
  25.  
  26.                 controlarCoches(delta);
  27.         }
  28.  
  29. }


Se probades o código podedes comprobar como os coches se moven á velocidade indicada na clase Mundo cando as instanciamos...




-- Ángel D. Fernández González -- (2015).