LIBGDX Cambiando de pantalla

De MediaWiki
Saltar a: navegación, buscar

UNIDADE 2: Cambiando de pantalla

Cambiando de pantalla

Tal como comentamos anteriormente neste punto a forma de proceder para cambiar de pantalla é chamando ó método setScreen da clase Game.


Nota: Lembrar que no exemplo que estamos a seguir, mandamos o obxecto que deriva da clase Game como parámetro na chamada ó método setScreen, para que a outra pantalla poda ter referencia ó mesmo e poida volver a chamar ó método setScreen.


No noso exemplo....

Imos cambiar a pantalla inicial para que en vez de ir ó xogo directamente pase pola pantalla principal.


Preparación:

  • Subide o seguinte gráfico ó cartafol GRAFICOS dentro do cartafol assets no proxecto Android.


LIBGDX itin1 pantallapresentacion.png
  • Agora imos modificar a clase PantallaPresentacion para crear unha cámara e visualizar o gráfico anterior.

Código da clase PantallaPresentacion
Obxectivo: visualizar a pantalla de presentación.

  1. public class PantallaPresentacion implements Screen, InputProcessor{
  2.         private MeuXogoGame meuxogogame;
  3.  
  4.     private OrthographicCamera camara2d;
  5.     private SpriteBatch spritebatch;
  6.     private static Texture fondo;
  7.        
  8.         public PantallaPresentacion(MeuXogoGame meuxogogame){
  9.                 this.meuxogogame=meuxogogame;
  10.  
  11.                 camara2d = new OrthographicCamera();
  12.                 spritebatch = new SpriteBatch();
  13.                 fondo = new Texture(Gdx.files.internal("GRAFICOS/LIBGDX_itin1_pantallapresentacion.png"));
  14.                
  15.         }
  16.  
  17.         @Override
  18.         public void render(float delta) {
  19.                 // TODO Auto-generated method stub
  20.                
  21.                 spritebatch.begin();
  22.                
  23.                 spritebatch.draw(fondo,0,0,Mundo.TAMANO_MUNDO_ANCHO,Mundo.TAMANO_MUNDO_ALTO);
  24.                
  25.                 spritebatch.end();
  26.                
  27.                
  28.         }
  29.  
  30.         @Override
  31.         public void resize(int width, int height) {
  32.                 // TODO Auto-generated method stub
  33.                
  34.                 camara2d.setToOrtho(false, Mundo.TAMANO_MUNDO_ANCHO, Mundo.TAMANO_MUNDO_ALTO);
  35.                 camara2d.update();
  36.                
  37.                 spritebatch.setProjectionMatrix(camara2d.combined);
  38.                 spritebatch.disableBlending();
  39.                
  40.         }
  41.  
  42.         @Override
  43.         public void show() {
  44.                 // TODO Auto-generated method stub
  45.                 Gdx.input.setInputProcessor(this);
  46.                
  47.         }
  48.  
  49.         @Override
  50.         public void hide() {
  51.                 // TODO Auto-generated method stub
  52.                 // Neste caso non fai falta poñelo xa que imos ser nos o que chamemos a dispose cando cambiemos de pantalla.
  53.                 //dispose();
  54.                
  55.         }
  56.  
  57.         @Override
  58.         public void pause() {
  59.                 // TODO Auto-generated method stub
  60.                 Gdx.input.setInputProcessor(null);
  61.                
  62.         }
  63.  
  64.         @Override
  65.         public void resume() {
  66.                 // TODO Auto-generated method stub
  67.                 Gdx.input.setInputProcessor(this);
  68.                
  69.         }
  70.  
  71.         @Override
  72.         public void dispose() {
  73.                 // TODO Auto-generated method stub
  74.                 Gdx.input.setInputProcessor(null);
  75.        
  76.                 spritebatch.dispose();
  77.                 fondo.dispose();
  78.                
  79.         }
  80.  
  81.         @Override
  82.         public boolean keyDown(int keycode) {
  83.                 // TODO Auto-generated method stub
  84.                 return false;
  85.         }
  86.  
  87.         @Override
  88.         public boolean keyUp(int keycode) {
  89.                 // TODO Auto-generated method stub
  90.                 return false;
  91.         }
  92.  
  93.         @Override
  94.         public boolean keyTyped(char character) {
  95.                 // TODO Auto-generated method stub
  96.                 return false;
  97.         }
  98.  
  99.         @Override
  100.         public boolean touchDown(int screenX, int screenY, int pointer, int button) {
  101.                 // TODO Auto-generated method stub
  102.                 return false;
  103.         }
  104.  
  105.         @Override
  106.         public boolean touchUp(int screenX, int screenY, int pointer, int button) {
  107.                 // TODO Auto-generated method stub
  108.                 return false;
  109.         }
  110.  
  111.         @Override
  112.         public boolean touchDragged(int screenX, int screenY, int pointer) {
  113.                 // TODO Auto-generated method stub
  114.                 return false;
  115.         }
  116.  
  117.         @Override
  118.         public boolean mouseMoved(int screenX, int screenY) {
  119.                 // TODO Auto-generated method stub
  120.                 return false;
  121.         }
  122.  
  123.         @Override
  124.         public boolean scrolled(int amount) {
  125.                 // TODO Auto-generated method stub
  126.                 return false;
  127.         }
  128.  
  129.  
  130. }
  • Liña 38:

Atención:: Na liña 38 temos a seguinte instrución:

  1. spritebatch.disableBlending();

O que fai dita liña é deshabilitar o uso de transparencias. Isto o facemos nesta pantalla xa que o fondo da mesma ocupa todo e non imos engadir novos gráficos que teñan transparencias.

No resto de pantallas (como a de Marcadores) imos escribir texto que vai ter transperencias polo que dita orde non se debe poñer ou se a poñemos (por ter un fondo por exemplo) deberemos chamar a orde contraria (spritebatch.enableBlending()) antes de debuxar o gráfico con transparencias.


Modificamos agora a clase principal MeuXogoGame para que chame á nova pantalla...

Código da clase MeuXogoGame
Obxectivo: chama á pantalla principal.

  1. public class MeuXogoGame extends Game {
  2.  
  3.        
  4.         @Override
  5.         public void create() {
  6.                 // TODO Auto-generated method stub
  7.                
  8.                 AssetsXogo.cargarTexturas();
  9.                 setScreen(new PantallaPresentacion(this));
  10.         }
  11.  
  12.         @Override
  13.         public void dispose(){
  14.                 super.dispose();
  15.  
  16.                 AssetsXogo.liberarTexturas();
  17.         }
  18. }


Agora temos que comprobar se pulsamos cada unha das opcións (botóns) e obrar en consecuencia. Debemos crear un rectángulo por cada unha das opcións (xa visto na sección das colisións) e comprobar se o dedo toca cada unha delas.



TAREFA 2.10 A FACER: Esta parte está asociada á realización dunha tarefa.


Facendo pause

En case todos os xogos podemos facer un pause do xogo para seguir posteriormente así como a opción de saír.

No caso do pause temos dúas opcións:

  • Quedarnos na mesma pantalla e no caso de que o xogo pase ó estado de pause debuxar un gráfico no centro da pantalla que indique que está en pause.

Para esta opción só teríamos que non chamar ó método controladorXogo.update(delta) dentro do método render da clase PantallaXogo. Desta forma ningún personaxe se moverá. Teríamos que cambiar a variable booleana pause a true e facela static e public para que dende a clase RendererXogo poidamos verificar o seu valor e no caso de que valga true poñer o gráfico de pause no centro da pantalla. Teríamos que controlar o método touchdown para que no caso de estar en pause e tocar a pantalla volver a poñer o valor a false.

  • Cambiar de pantalla e que ó premer volvamos ó xogo no punto onde o deixamos.

Para esta segunda opción imos modificar a clase PantallaPause para cargar o seguinte gráfico:

LIBGDX itin1 pantallapause.jpg

Levade este gráfico ó cartafol assets/GRAFICOS da versión Android e dádelle de nome LIBGDX_itin1_pantallapause.jpg.

Modificade o código da clase PantallaPause para que cargue o gráfico anterior.

Lembrar incluír a interface InputProcessor como xa vimos anteriormente.

Tamén deberedes liberar os recursos cando pase polo método hide (chamar ó método dispose nese intre e liberade a textura e o spritebach).


Preparando a clase PantallaXogo e RendererXogo:

Modificamos agora o código da RendererXogo para que visualice dúas iconas na parte inferior esquerda.

Aquí temos os gráficos a engadir no cartafol assets/GRAFICOS/CONTROIS da versión Android:

Como sempre os cargarmos na clase AssetsXogo cos nome indicados entre parénteses.

Despois modificamos a clase RendererXogo para que debuxe os novos controis. Como imos ter que indicar onde debuxalos podemos definir a súa posición e tamaño na clase Controis.


Código da clase Controis
Obxectivo: definir posición e tamaño das iconas pausa e saír.

  1. public class Controis {
  2.  
  3.         public final static Rectangle FONDO_NEGRO = new Rectangle(0, 0,
  4.                         Mundo.TAMANO_MUNDO_ANCHO, 12);
  5.         public final static Rectangle CONTROL = new Rectangle(10, 40, 50, 70); 
  6.         public final static int POSVIDAS = 60;
  7.  
  8.         public final static Rectangle CONTROL_PAUSE = new Rectangle(30,0,10,10);
  9.         public final static Rectangle CONTROL_SAIR = new Rectangle(45,0,10,10);
  10.  
  11.        
  12. }


Código da clase RendererXogo
Obxectivo: visualiza as iconas pausa e saír.

  1.         private void debuxarControis(){
  2.                
  3.                 // Fondo negro
  4.                 spritebatch.draw(AssetsXogo.texturePuntoNegro, Controis.FONDO_NEGRO.x,Controis.FONDO_NEGRO.y,Controis.FONDO_NEGRO.width,Controis.FONDO_NEGRO.height);
  5.  
  6.                 spritebatch.draw(AssetsXogo.control, Controis.CONTROL.x,Controis.CONTROL.y,
  7.                          Controis.CONTROL.width,Controis.CONTROL.height);
  8.  
  9.                 spritebatch.draw(AssetsXogo.texturePausa, Controis.CONTROL_PAUSE.x,Controis.CONTROL_PAUSE.y,Controis.CONTROL_PAUSE.width,Controis.CONTROL_PAUSE.height);
  10.                 spritebatch.draw(AssetsXogo.textureSair, Controis.CONTROL_SAIR.x,Controis.CONTROL_SAIR.y,Controis.CONTROL_SAIR.width,Controis.CONTROL_SAIR.height);
  11.         }


Agora controlamos se prememos a opción de pausa e saír.

Código da clase PantallaXogo
Obxectivo: xestionamos a opción de premer pausa e saír.

  1.         @Override
  2.         public boolean touchDown(int screenX, int screenY, int pointer, int button) {
  3.                
  4. //              if (Gdx.app.getType()!=ApplicationType.Android) return false;
  5.                
  6.                 // TODO Auto-generated method stub
  7.                 Vector3 vecTemporal = new Vector3(screenX,screenY,0);
  8.                 rendererXogo.getCamara2d().unproject(vecTemporal);
  9.                
  10.                 Rectangle recTemporal = new Rectangle();
  11.  
  12.                 ...........................
  13.                 // Falta o código feito na tarefa 2.8.B no que se controla cando prememos no control do alien
  14.  
  15.  
  16.                 recTemporal.set(Controis.CONTROL_PAUSE.x,Controis.CONTROL_PAUSE.y,Controis.CONTROL_PAUSE.width,Controis.CONTROL_PAUSE.height);
  17.                 if (Intersector.overlaps(dedo, recTemporal)){
  18.                         pause = true;
  19.                 }
  20.                
  21.                 recTemporal.set(Controis.CONTROL_SAIR.x,Controis.CONTROL_SAIR.y,Controis.CONTROL_SAIR.width,Controis.CONTROL_SAIR.height);
  22.                 if (Intersector.overlaps(dedo, recTemporal)){
  23.                         dispose();
  24.                         meuXogoGame.setScreen(new PantallaPresentacion(meuXogoGame));
  25.                 }
  26.  
  27.                
  28.                
  29.                 return false;
  30.         }


Como podemos comprobar a opción de saír non ten complicación, xa a temos vista na tarefa 2.10. A chamada ó método dispose non se atopa no método hide xa que cando vaiamos á pantalla de pausa non queremos 'borrar' nada do xogo. Queremos ir con todo o estado do xogo e recuperalo ó volver.

Como facemos isto ? Como sempre temos varias opcións...Algunha delas:

  • Poderíamos gardar o estado do xogo a disco e recuperalo ó volver. Esta opción non é aconsellable nunha pantalla de pausa e si no caso de querer gardar a partida para continuar outro día (neste xogo non ten moito sentido).
  • Mandar como parámetro ó constructor da clase PantallaPause o obxecto da clase PantallaXogo desta forma:

Código da clase PantallaPause
Obxectivo: modifcamos o constructor para obter unha referencia á PantallaXogo.

  1. public class PantallaPause implements Screen, InputProcessor{
  2.         ..............
  3.         private PantallaXogo pantallaXogo;
  4.    
  5.         public PantallaPause(MeuXogoGame meuXogoGame, PantallaXogo pantallaXogo){
  6.                
  7.                 this.meuxogogame=meuxogogame;
  8.                 this.pantallaXogo = pantallaXogo;
  9.  
  10.                 camara2d = new OrthographicCamera();
  11.                 spritebatch = new SpriteBatch();
  12.                 fondo = new Texture(Gdx.files.internal("GRAFICOS/LIBGDX_itin1_pantallapause.png"));
  13.                
  14.         }
  15.         ..............
  16. }

Agora no método render da clase PantallaXogo controlamos cando estamos en pause para mandar o control á PantallaPause:

Código da clase PantallaXogo
Obxectivo: controlamos se estamos en pause para ir á PantallaPause.

  1.         @Override
  2.         public void render(float delta) {
  3.                 // TODO Auto-generated method stub
  4.  
  5.                 rendererXogo.render(delta);
  6.                 controladorXogo.update(delta);
  7.                
  8.                 if (pause){
  9.                         meuXogoGame.setScreen(new PantallaPause(meuXogoGame, this));
  10.                         return;
  11.                 }
  12.         }

Nota importante: Debemos facer return despois de chamar a setScreen, xa que a pesar que o control pasa a nova pantalla, se sigue executando o código do método render ata finalizar. Se temos código a continuación podemos ter un erro de execución.

Fixarse como no método setScreen enviamos non só a referencia a clase MeuXogoGame (para poder facer o setScreen) se non tamén unha referencia á propia clase PantallaXogo.

Agora só temos que controlar se se preme na pantalla PantallaPause volver ó control á PantallaXogo, pero usando a referencia pasada.


Código da clase PantallaPause
Obxectivo: devolvemos o control á PantallaXogo se prememos na pantalla.

  1.         @Override
  2.         public boolean touchDown(int screenX, int screenY, int pointer, int button) {
  3.                 // TODO Auto-generated method stub
  4.                 meuxogogame.setScreen(pantallaXogo);
  5.                 return false;
  6.         }

Se executades o código podedes comprobar que xa accedemos á pantalla de pausa cando prememos sobre o control, pero ó intentar continuar o xogo volve á pantalla de pausa. Isto é debido a que a variable pause segue valendo true cando regresamos e polo tanto volve a facer o setScreen da pantalla de pause.

Imos modificar isto para que o xogo cando entre en estado de pause (ó premer o botón de pause ou cando minimizamos (en desktop) ou cambiamos de aplicación (en móbil) ) poñamos a variable a true e cando volvamos (maximicemos ou volvamos nun móbil) cambie a false.


Código da clase PantallaXogo
Obxectivo: modificar a propiedade pause.

  1.         ................
  2.  
  3.         @Override
  4.         public void pause() {
  5.                 // TODO Auto-generated method stub
  6.                 Gdx.input.setInputProcessor(null);
  7.                 if (!finXogo) {
  8.                         pause = true;
  9.                 }
  10.                
  11.         }
  12.  
  13.         @Override
  14.         public void resume() {
  15.                 // TODO Auto-generated method stub
  16.                 Gdx.input.setInputProcessor(this);
  17.                 pause=false;
  18.                
  19.         }
  20.         @Override
  21.         public void show() {
  22.                 // TODO Auto-generated method stub
  23.                 Gdx.input.setInputProcessor(this);
  24.                 pause=false;
  25.         }
  26.  
  27.         ................


Nota: Fixarse como cando facemos a pausa do xogo minimizando a aplicación na versión desktop, pasamos polo evento pause, pero cando restauramos, non pasamos polo evento resume xa que cambiamos de pantalla (estamos na pantalla de pausa). Cando dende a pantalla de pausa chamamos ó método setScreen volvemos a pasar polo evento show.

Saíndo do xogo

Ó premer a icona de saír debemos ir á pantalla de presentación. Tamén imos engadir outra condición e é que se utilizamos máis de 15 vidas o xogo acaba.

Lembrar que temos que liberar os recursos.

Código da clase PantallaXogo
Obxectivo: Xestionar o fin do xogo.

  1.         @Override
  2.         public void render(float delta) {
  3.                 // TODO Auto-generated method stub
  4.  
  5.                 rendererXogo.render(delta);
  6.                 controladorXogo.update(delta);
  7.                
  8.                 if (meuMundo.getAlien().getNumVidas().size>=15)
  9.                         finXogo=true;
  10.  
  11.  
  12.                 if (pause){
  13.                         Audio.stopMusica();
  14.                         meuXogoGame.setScreen(new PantallaPause(meuXogoGame, this));
  15.                         return;
  16.                 }
  17.                 if (finXogo){
  18.                         meuXogoGame.setScreen(new PantallaMarcadores(meuXogoGame));
  19.                         // Facemos o return xa que continua a execución ata que remate o render.
  20.                         return;
  21.                 }
  22.                
  23.         }
  24.  
  25.         @Override
  26.         public boolean touchDown(int screenX, int screenY, int pointer, int button) {
  27.                
  28.                 vecTemporal.set(screenX,screenY,0);
  29.                 rendererXogo.getCamara2d().unproject(vecTemporal);
  30.                
  31.                 dedo.set(vecTemporal.x,vecTemporal.y,2);
  32.                 ..................
  33.  
  34.                                 recTemporal.set(Controis.CONTROL_SAIR.x,Controis.CONTROL_SAIR.y,Controis.CONTROL_SAIR.width,Controis.CONTROL_SAIR.height);
  35.                 if (Intersector.overlaps(dedo, recTemporal)){
  36.                         sair=true;
  37.                         meuXogoGame.setScreen(new PantallaPresentacion(meuXogoGame));
  38.                 }
  39.  
  40.                
  41.                
  42.                 return false;
  43.         }
  44.         @Override
  45.         public void hide() {
  46.                 // TODO Auto-generated method stub
  47.                 if ((finXogo) || (sair)) dispose();
  48.                
  49.         }




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