LIBGDX Fontes

De Manuais Informática - IES San Clemente.
Ir a la navegación Ir a la búsqueda

UNIDADE 2: Fontes

Información da wiki: https://github.com/libgdx/libgdx/wiki/Bitmap-fonts

Normalmente nos xogos imos ter que escribir texto na pantalla.

Para facelo imos ter que utilizar a clase BitMapFont.


Empecemos indicando que é un BitMap. Para nos un BitMap é unha imaxe que representa unha letra. Dita letra (imaxe) pode ser escalada (aumentar ou reducir de tamaño).

Dependendo do tamaño inicial da letra, este escalado pode dar lugar a letras con dentes de serra. O ideal para que isto non suceda é ter o tamaño de letra igual de grande que na visualización para non ter que facer escalado de 'aumento'.

Inconveniente que teñen os BitMap: o tamaño que ocupan en disco. Se temos un xogo cunha única fonte ó mellor non é problema, pero se temos moitos tipos de fonte e estamos en Android si pode dar lugar a inconvenientes.

Para solucionalo mellor utilizar as fontes TrueType xa que ocupan moito menos espazo. Para aprender a utilizar este tipo de fontes podedes visitar este enlace: https://github.com/libgdx/libgdx/wiki/Gdx-freetype


Neste itinerario imos utilizar o BitMapFont por defecto que ten como inconveniente que non escala moi ben e pode dar lugar a texto cun aspecto malo (dentes de serra).

O proceso para utilizalas é moi sinxelo.


Preparación: Agora ides facer unha copia da clase RendererXogo, xa que imos modificala para amosarvos como se utilizan os BitMapFont. Premede co rato sobre a clase, botón dereito e escollede a opción Copy. Despois repetides a operación pero escolledes a opción Paste. Vos preguntará un nome para a clase. Indicade UD2_6_RendererXogo.

Código da clase UD2_6_RendererXogo
Obxectivo: utilizar BitMapFont.

 1 import com.badlogic.gdx.Gdx;
 2 import com.badlogic.gdx.graphics.Color;
 3 import com.badlogic.gdx.graphics.GL20;
 4 import com.badlogic.gdx.graphics.OrthographicCamera;
 5 import com.badlogic.gdx.graphics.g2d.BitmapFont;
 6 import com.badlogic.gdx.graphics.g2d.SpriteBatch;
 7 import com.plategaxogo2d.modelo.Mundo;
 8 
 9 /*
10  * Comprobamos como utilizar as BitMapFont.
11  */
12 
13 public class UD2_6_RendererXogo {
14 
15     private OrthographicCamera camara2d;
16     private SpriteBatch spritebatch;
17     
18 
19     public UD2_6_RendererXogo(Mundo mundo) {
20 
21     	camara2d = new OrthographicCamera();
22         spritebatch = new SpriteBatch();
23         
24     }
25 
26     
27 	
28 	public OrthographicCamera getCamara2d(){
29 		return camara2d;
30 	}
31 	
32     /**
33      * Debuxa todos os elementos graficos da pantalla
34      *
35      * @param delta
36      *            : tempo que pasa entre un frame e o seguinte.
37      */
38     public void render(float delta) {
39 		Gdx.gl.glClearColor(0, 0, 0, 1);
40 		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
41 
42 		
43 		spritebatch.begin();
44 		
45 		
46 		spritebatch.end();
47 		
48     }
49 
50 
51 
52     public void resize(int width, int height) {
53 
54 		camara2d.setToOrtho(false, Mundo.TAMANO_MUNDO_ANCHO,
55 				Mundo.TAMANO_MUNDO_ALTO);
56 		camara2d.update();
57 
58 		spritebatch.setProjectionMatrix(camara2d.combined);
59 		
60 
61     }
62 
63     public void dispose() {
64     	spritebatch.dispose();
65     }
66 
67 
68 }


Modificade a clase PantallaXogo para que chame a esta clase. Ó iniciar o xogo aparece a pantalla de presentación. Debedes premer Novo Xogo para que chame a esta pantalla.


Clase BitMapFont. Por defecto utiliza unha fonte que ven integrada no jar do Libgdx. Ten un tamaño de 15 puntos e é Arial.

Métodos máis importantes:



Código da clase UD2_6_RendererXogo
Obxectivo: Exemplo de uso da clase BitMapFont.

 1 public class UD2_6_RendererXogo {
 2 
 3     private OrthographicCamera camara2d;
 4     private SpriteBatch spritebatch;
 5     private BitmapFont bitMapFont;
 6     
 7 
 8     public UD2_6_RendererXogo(Mundo mundo) {
 9 
10     	camara2d = new OrthographicCamera();
11         spritebatch = new SpriteBatch();
12         
13         bitMapFont = new BitmapFont();
14     }
15 
16     
17 	
18 	public OrthographicCamera getCamara2d(){
19 		return camara2d;
20 	}
21 	
22     /**
23      * Debuxa todos os elementos graficos da pantalla
24      *
25      * @param delta
26      *            : tempo que pasa entre un frame e o seguinte.
27      */
28     public void render(float delta) {
29 		Gdx.gl.glClearColor(0, 0, 0, 1);
30 		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
31 
32 		
33 		spritebatch.begin();
34 		
35         bitMapFont.setColor(Color.RED);
36         bitMapFont.setScale(10);
37 		bitMapFont.draw(spritebatch, "TEXTO ESCALADO A 10 VECES O SEU TAMAÑO", 0, 250);
38 
39         bitMapFont.setColor(Color.YELLOW);
40         bitMapFont.setScale(0.5f, 2);
41 		bitMapFont.draw(spritebatch, "TEXTO ESCALADO", 0, 350);
42 
43 		spritebatch.end();
44 		
45     }
46 
47 
48 
49     public void resize(int width, int height) {
50 
51 		camara2d.setToOrtho(false, Mundo.TAMANO_MUNDO_ANCHO,
52 				Mundo.TAMANO_MUNDO_ALTO);
53 		camara2d.update();
54 
55 		spritebatch.setProjectionMatrix(camara2d.combined);
56 		
57 
58     }
59 
60     public void dispose() {
61     	bitMapFont.dispose();
62     	spritebatch.dispose();
63     }
64 
65 
66 }



Dará como resultado isto:

LIBGDX UD2 12 Fontes 1.jpg


Nota: Loxicamente se a escala ou cor no van modificarse nunca é conveniente levar estas ordes ó constructor para só se executen unha vez.


Outro factor a ter en conta cando manexamos cadeas é o de optimizar o uso da memoria. Cando queremos concatenar dúas cadeas normalmente faríamos isto:

1  		String cad1 = "CAD1";
2  		String cad2 = "CAD2";
3  		
4  		String cad3 = cad1 + cad2;

Esta forma de concatenar ten como inconveniente que crear unha nova zona de memoria para a nova cadea. Se o facemos dentro do método render, estaremos creando novas cadeas continuamente. Para evitalo debemos facer uso da clase StringBuilder.

Tedes unha explicación do seu uso neste enlace.

Un exemplo de uso:

Código da clase UD2_6_RendererXogo
Obxectivo: Usa a clase StringBuilder para crear novas cadeas e concatenar.

 1 public class UD2_6_RendererXogo {
 2 
 3     private OrthographicCamera camara2d;
 4     private SpriteBatch spritebatch;
 5     private BitmapFont bitMapFont;
 6     private StringBuilder sbuffer;
 7     
 8 
 9     public UD2_6_RendererXogo(Mundo mundo) {
10 
11     	camara2d = new OrthographicCamera();
12         spritebatch = new SpriteBatch();
13         
14         bitMapFont = new BitmapFont();
15         sbuffer = new StringBuilder();
16         sbuffer.append("TEXTO ALEAOTORIO:");
17     }
18 
19     
20 	
21 	public OrthographicCamera getCamara2d(){
22 		return camara2d;
23 	}
24 	
25     /**
26      * Debuxa todos os elementos graficos da pantalla
27      *
28      * @param delta
29      *            : tempo que pasa entre un frame e o seguinte.
30      */
31     public void render(float delta) {
32 		Gdx.gl.glClearColor(0, 0, 0, 1);
33 		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
34 
35 		
36 		spritebatch.begin();
37 		
38                 bitMapFont.setColor(Color.RED);
39                 bitMapFont.setScale(10);
40 		bitMapFont.draw(spritebatch, "TEXTO ESCALADO A 10 VECES O SEU TAMAÑO", 0, 250);
41 
42                 bitMapFont.setColor(Color.YELLOW);
43                 bitMapFont.setScale(0.5f, 2);
44 		bitMapFont.draw(spritebatch, "TEXTO ESCALADO", 0, 350);
45 
46                 bitMapFont.setColor(Color.WHITE);
47         
48                 if (sbuffer.length()>50) {
49                    sbuffer.setLength(0);  	// Borramos
50                    sbuffer.append("TEXTO ALEATORIO:");
51                 }
52                 sbuffer.append(MathUtils.random(9));
53          	bitMapFont.draw(spritebatch, sbuffer, 0, 50);
54 
55 		spritebatch.end();
56 		
57     }
58 
59 
60 
61     public void resize(int width, int height) {
62 
63 		camara2d.setToOrtho(false, Mundo.TAMANO_MUNDO_ANCHO,
64 				Mundo.TAMANO_MUNDO_ALTO);
65 		camara2d.update();
66 
67 		spritebatch.setProjectionMatrix(camara2d.combined);
68 		
69 
70     }
71 
72     public void dispose() {
73     	bitMapFont.dispose();
74     	spritebatch.dispose();
75     }
76 
77 
78 }


Nota: Volvede a modificar á clase PantallaXogo para que chame á clase RendererXogo.


Engadindo un cronómetro ó noso xogo

Imos engadir un tempo ó noso xogo, de tal forma que ó rematar iremos á pantalla de marcadores.


Para facelo imos definir unha constante de clase que gardará o tempo inicial (serán 120 segundos) e outra propiedade de clase de nome cronometro que, como di o seu nome, será un cronómetro :) .

Código da clase Mundo
Obxectivo: definimos un cronómetro.

 1 public class Mundo {
 2 
 3         ..................
 4 	 private final static int TEMPO_INICIAL=120;
 5 	 private float cronometro;
 6 
 7         ..................
 8         public Mundo(){
 9        	   alien = new Alien(new Vector2(100,20), new Vector2(15,15),100);
10     	   nave = new Nave(new Vector2(0,480),new Vector2(40,20),60);
11     	
12     	   vehiculos = new Elementos(1.5f,3f,20);
13     	   troncos = new Elementos(2f,5f,6);
14     	   rocas = new Elementos(2f,5f,3);
15     	
16     	   cronometro=TEMPO_INICIAL;
17     	
18         }
19 
20 	public int getCronometro() {
21 		return (int)cronometro;
22 	}
23 
24 	public void setCronometro(float cronometro) {
25 		this.cronometro = cronometro;
26 	}
27 	
28 	public void updateCronometro(float delta){
29 		cronometro-=delta;
30 	}
31 	
32         ..................
33 }

Agora só temos que restar delta a cronometro no controlador do xogo.

Código da clase ControladorXogo
Obxectivo: actualizamos o cronómetro.

 1 	public void update(float delta) {
 2 
 3 		meuMundo.updateCronometro(delta);
 4 		
 5 		controlarCoches(delta);
 6 		controlarRochas(delta);
 7 		controlarTroncos(delta);
 8 		
 9 		controlarNave(delta);
10 		controlarAlien(delta);
11 		
12 		procesarEntradas();
13 
14 	}



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




Tarefas avanzadas



TAREFA AVANZADA: Esta parte está asociada á realización dunha tarefa avanzada. Fontes Avanzadas..




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