LIBGDX Tarefas entregar UD4

De MediaWiki
Saltar a: navegación, buscar

ACLARACIÓNS TAREFAS UD4


Lembrar que na unidade 3D se pode escoller unha das dúas opcións.



A máis doada de facer son as tarefas.




TAREFAS

Nota: Se escolledes facer as tarefas non será necesario entregar o xogo.

Tarefa 4.1

ENLACE A MIRAR.

Deseña un cadrado que vaia dende -0.5f a 0.5f, tanto no eixe x como no y.

Podes facelo de dúas formas:

  • Con dous triángulos (crear dous obxectos mesh).
  • Debuxar un cadrado.

Pistas:

  • Definir un único Mesh que tería catro vértices e seis índices.
  • Con 3 índices formas un triángulo. Con 6 podes formar dous facendo un cadrado. Se empezas a numerar de abaixo-dereita-arriba-esquerda (os catro vértices) coa secuencia de índices: 0-1-2 (forma un triángulo) e 0-2-3 (formas o outro triángulo) temos un cadrado.
  • Lembra modificar o número de índices no método render do Mesh e no constructor o número de índices e vértices.


  • Comprimide o código fonte de dita clase nun zip co voso nome e apelidos e subídeo xunto coas outras actividades.

Tarefa 4.2

ENLACE A MIRAR.

Modifica a clase UD4_2_Camara2D e fai que a cámara ortográfica non visualice o triángulo verde. modificando o ViewFrustrum da cámara (planos far e near).


  • Comprimide o código fonte de dita clase nun zip co voso nome e apelidos e subídeo xunto coas outras actividades.

Tarefa 4.3

ENLACE A MIRAR.

Modifica o arquivo vertex.vert e fai que o triángulo mida o dobre de alto.


  • Comprimide o arquivo vertex.vert nun zip co voso nome e apelidos e subídeo xunto coas outras actividades.


Tarefa 4.4

ENLACE A MIRAR.

Crea unha nova clase de nome UD4_TAREFA_4_4 partindo do código da clase UD4_4_ProgramShader (o código está posto ó final do enlace e mirar) fai que a cámara rote arredor do triángulo vermello.

Pistas:

Dito método espera recibir como parámetros os seguintes:
  • Primeiro parámetro: Un punto cara onde ten que mirar a cámara. No noso caso é o: new Vector3(0,0,0).
  • Segundo parámetro: O vector que ten que rotar.
Para sabelo repasa o gráfico da regra da man dereita. Para saber o eixe tedes que imaxinar unha lanza atravesando a vosa testa. Así, se a lanza é o eixe X moveredes a cabeza de arriba-abaixo,....e así por cada eixe. Se queredes que se mova nun eixe determinado poñeredes como segundo parámetro: new Vector3(1,0,0). Neste caso se movería arriba-abaixo.
  • Terceiro parámetro: o ángulo a rotar. Teredes que multiplicalo por Gdx.graphics.getDeltaTime() para indicar que rote X grados cada segundo.

Lembrar chamar ó método update da cámara e engadir o código ó método render.

Nota: Lembrar que segundo vimos nos consellos de programación é mellor facer un só new no constructor e poñer: vector.set(x,y,z) para darlle un valor.

  • Comprimide a clase nun zip co voso nome e apelidos e subídeo xunto coas outras actividades.

Tarefa 4.5

ENLACE A MIRAR: Animacións en 3D.

ENLACE A MIRAR: Carga Modelos3D.


Imos crear un novo escenario no que dispoñemos de naves que temos que levar á Terra. As naves están na parte superior e a Terra está xirando na inferior.

Aviso: Neste código non estamos a separar o Modelo-Vista-Controlador como fixemos na parte 2D. Isto o facemos por motivos de tempo, pudendo aplicar todos os conceptos aprendidos no desenvolvemento do xogo 2D.

Unha imaxe do que queremos conseguir:

LIBGDX UD4 Tarefa 4 6 1.jpg


Preparacion:

  • Crea unha clase de nome Terra, que teña este código:

Código da clase Terra
Obxectivo: Clase que garda a información necesaria para mover a Terra.

  1. import com.badlogic.gdx.math.Vector3;
  2.  
  3. /**
  4.  * Elemento 3D con rotación
  5.  * @author ANGEL
  6.  *
  7.  */
  8. public class Terra extends Elemento3D{
  9.        
  10.         public float velocidadeRotar;
  11.         public Vector3 eixeRotar;
  12.         private float anguloRotacion;
  13.        
  14.         public final float POSINICALX=-400;
  15.         public final float POSFINALX=400;
  16.  
  17.        
  18.         public Terra(Vector3 pos, float escala,Vector3 velocidade,float velocidadeRotar,Vector3 eixeRotar){
  19.                 super(pos,escala,velocidade);
  20.                 this.velocidadeRotar=velocidadeRotar;
  21.                 this.eixeRotar = eixeRotar;
  22.                
  23.         }
  24.        
  25.         public void update(float delta){
  26.  
  27.                 super.update(delta);
  28.                
  29.                 anguloRotacion +=delta*velocidadeRotar;
  30.                 matriz.rotate(eixeRotar,anguloRotacion);
  31.                
  32.                
  33.         }
  34.  
  35. }


  • Descomprime o arquivo seguinte e copia o seu contido (tierra.obj / tierra.jpg) ó cartafol /assets/modelos/ da versión Android.

Media:Tierra.zip


  • Crea unha nova clase que derive de Game de nome UD4_6_TAREFA_4_6. Cambia os diferentes proxectos para que carguen a nova clase.

A continuación vos deixo o código da clase pero faltan liñas por programar. Indico o que hai que facer nos comentarios dentro do código:

Código da clase UD4_TAREFA_4_5
Obxectivo: Implementar o escenario pedido.

  1. import java.util.ArrayList;
  2.  
  3. import com.badlogic.gdx.Game;
  4. import com.badlogic.gdx.Gdx;
  5. import com.badlogic.gdx.assets.loaders.ModelLoader;
  6. import com.badlogic.gdx.files.FileHandle;
  7. import com.badlogic.gdx.graphics.GL20;
  8. import com.badlogic.gdx.graphics.Mesh;
  9. import com.badlogic.gdx.graphics.PerspectiveCamera;
  10. import com.badlogic.gdx.graphics.Texture;
  11. import com.badlogic.gdx.graphics.g3d.Model;
  12. import com.badlogic.gdx.graphics.g3d.loader.ObjLoader;
  13. import com.badlogic.gdx.graphics.glutils.ShaderProgram;
  14. import com.badlogic.gdx.math.Vector3;
  15. import com.plategaxogo3d.exemplos.Elemento3D;
  16. import com.plategaxogo3d.exemplos.Terra;
  17.  
  18. /**
  19.  * Tarefa modelos 3D
  20.  * @author ANGEL
  21.  */
  22.  
  23. public class UD4_TAREFA_4_5 extends Game {
  24.  
  25.         private Mesh meshNave;
  26.         private Mesh meshTerra;
  27.        
  28.         private ArrayList<Elemento3D> naves;
  29.         private  Terra terra;
  30.        
  31.         private ShaderProgram shaderProgram;
  32.  
  33.         private Texture texturaNave;
  34.         private Texture texturaTerra;
  35.         private PerspectiveCamera camara3d;
  36.        
  37.  
  38.        
  39.         @Override
  40.         public void create() {
  41.                 // TODO Auto-generated method stub
  42.  
  43.                 shaderProgram = new ShaderProgram(Gdx.files.internal("vertex.vert"), Gdx.files.internal("fragment.frag"));
  44.                 if (shaderProgram.isCompiled() == false) {
  45.                         Gdx.app.log("ShaderError", shaderProgram.getLog());
  46.                         System.exit(0);
  47.                 }
  48.        
  49.  
  50.                 ModelLoader loader = new ObjLoader();
  51.         Model model = loader.loadModel(Gdx.files.internal("modelos/ship.obj"));
  52.         meshNave = model.meshes.get(0);
  53.        
  54.  
  55.         /* CÓDIGO POR FACER
  56.          * Falta cargar o meshTerra có modelo gardado en modelos/tierra.obj
  57.          */
  58.  
  59.        
  60.                 FileHandle imageFileHandle = Gdx.files.internal("modelos/ship.png");
  61.                 texturaNave = new Texture(imageFileHandle);
  62.                 imageFileHandle = Gdx.files.internal("modelos/tierra.jpg");
  63.                 texturaTerra = new Texture(imageFileHandle);
  64.                
  65.                 camara3d = new PerspectiveCamera();
  66.                
  67.                 naves = new ArrayList<Elemento3D>();
  68.                 naves.add(new Elemento3D(new Vector3(-380f,0f,-250f), 20f, new Vector3(0,0,0)));
  69.                 naves.add(new Elemento3D(new Vector3(-250f,0f,-250f), 20f, new Vector3(0,0,0)));
  70.                 naves.add(new Elemento3D(new Vector3(-120f,0f,-250f), 20f, new Vector3(0,0,0)));
  71.                 naves.add(new Elemento3D(new Vector3(+10f,0f,-250f), 20f, new Vector3(0,0,0)));
  72.                 naves.add(new Elemento3D(new Vector3(+140f,0f,-250f), 20f, new Vector3(0,0,0)));
  73.                 naves.add(new Elemento3D(new Vector3(+270f,0f,-250f), 20f, new Vector3(0,0,0)));
  74.  
  75.         /* CÓDIGO POR FACER
  76.          * Falta engadir unha nave na posición (+400f,0f,-250f)
  77.          * Falta instanciar a terra (propiedade terra) na posición (0,0,100f), escala 25f, velocidade (100f,0,0) e eixe a mover (0,1,1)
  78.          */
  79.                
  80.                
  81.         }
  82.        
  83.         private void controlarTerra(float delta){
  84.                 terra.update(delta);
  85.                 if ((terra.posicion.x >= terra.POSFINALX) | (terra.posicion.x <= terra.POSINICALX)){
  86.                         terra.velocidade.x=-1*terra.velocidade.x;
  87.                 }
  88.                
  89.         }
  90.        
  91.         @Override
  92.         public void render() {
  93.  
  94.                 Gdx.gl20.glClearColor(0f, 0f, 0f, 1f);
  95.                 Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT|GL20.GL_DEPTH_BUFFER_BIT);
  96.  
  97.                 Gdx.gl20.glEnable(GL20.GL_DEPTH_TEST);
  98.  
  99.         /* CÓDIGO POR FACER
  100.          * Falta colocar a cámara na posición (0,500f,0) e que mire cara a posición (0,0,0).
  101.          * Dependendo da resolución da vosa pantalla (e a resolución que utilizades na versión Desktop) pode ser necesario aumentar a distancia da cámara para ver todas as naves.
  102.          *   Podedes probar con diferentes valores ó de 500f máis alonxados como 600f,...
  103.          * LEMBRAR ACTUALIZAR A CAMARA
  104.          */
  105.  
  106.                 controlarTerra(Gdx.graphics.getDeltaTime());
  107.                 for (Elemento3D nave: naves){
  108.                         nave.update(Gdx.graphics.getDeltaTime());
  109.                 }
  110.                
  111.                 shaderProgram.begin();
  112.  
  113.                 texturaNave.bind(0);
  114.                 shaderProgram.setUniformi("u_texture", 0);
  115.                 for (Elemento3D nave: naves){
  116.                         shaderProgram.setUniformMatrix("u_worldView", camara3d.combined.cpy().mul(nave.matriz));
  117.                         meshNave.render(shaderProgram, GL20.GL_TRIANGLES);
  118.                 }
  119.  
  120.                        
  121.                 texturaTerra.bind(1);
  122.                 shaderProgram.setUniformi("u_texture", 1);
  123.                 shaderProgram.setUniformMatrix("u_worldView", camara3d.combined.cpy().mul(terra.matriz));
  124.                 meshTerra.render(shaderProgram, GL20.GL_TRIANGLES);
  125.  
  126.                 shaderProgram.end();
  127.                
  128.                 Gdx.gl20.glDisable(GL20.GL_DEPTH_TEST);
  129.  
  130.         }
  131.        
  132.         @Override
  133.         public void resize (int width,int height){
  134.                 // Definimos os parámetros da cámara
  135.                 float aspectRatio = (float) width / (float) height;
  136.                 camara3d.viewportWidth=aspectRatio*1f;
  137.                 camara3d.viewportHeight=1f;
  138.                 camara3d.far=5000f;
  139.                 camara3d.near=0.1f;
  140.                 camara3d.update();
  141.         }
  142.        
  143.         @Override
  144.         public void dispose(){
  145.                 shaderProgram.dispose();
  146.                 meshNave.dispose();
  147.  
  148.         }
  149.  
  150. }


  • Comprimide a clase nun zip co voso nome e apelidos e subídeo xunto coas outras actividades.

Tarefa 4.6

ENLACE A MIRAR.

Preparación: Partindo do código da clase UNIDADE4_TAREFA_4_5 feito na tarefa 4.5, crea unha nova clase de nome UNIDADE4_TAREFA_4_6 (copia e pega a tarefa anterior e vos pedirá un novo nome).


O obxectivo é facer que cando se preme na pantalla a nave se mova cara a terra e controlar se choca con ela ou se perde. Ó premer unha vez se moverá a primeira nave, ó premer outra vez a segunda e así continuamente ata que se acaben as naves. Nese intre volveremos a empezar.
Podedes descargar a versión PC desta tarefa neste enlace: Media:Tarefa4_6.zip
Esta é a versión máis sinxela.



Para controlar os choques tedes varias opcións:

  • A máis sinxela é utilizar a clase Sphere. Aínda que as naves non teñan esa forma se pode empregar sen problemas. Tede en conta a escala:

LIBGDX UD4 Tarefa 4 6 2.jpg

Así podedes controlar os choques de esfera con esfera.

  • Máis complexa: neste solución teredes que controlar o choque dunha esfera cun BoundingBox. Neste caso non temos a función que o controle e teríamos que implementala nos.

Unha opción é a implementada por Jim Arvo no se libro: A Simple Method for Box-Sphere Intersection Testing by Jim Arvo from "Graphics Gems", Academic Press, 1990:

  1. public static boolean intersectsWith(BoundingBox boundingBox, Sphere sphere) {
  2.     float dmin = 0;
  3.  
  4.     Vector3 center = sphere.center;
  5.     Vector3 bmin = boundingBox.getMin();
  6.     Vector3 bmax = boundingBox.getMax();
  7.  
  8.     if (center.x < bmin.x) {
  9.         dmin += Math.pow(center.x - bmin.x, 2);
  10.     } else if (center.x > bmax.x) {
  11.         dmin += Math.pow(center.x - bmax.x, 2);
  12.     }
  13.  
  14.     if (center.y < bmin.y) {
  15.         dmin += Math.pow(center.y - bmin.y, 2);
  16.     } else if (center.y > bmax.y) {
  17.         dmin += Math.pow(center.y - bmax.y, 2);
  18.     }
  19.  
  20.     if (center.z < bmin.z) {
  21.         dmin += Math.pow(center.z - bmin.z, 2);
  22.     } else if (center.z > bmax.z) {
  23.         dmin += Math.pow(center.z - bmax.z, 2);
  24.     }
  25.  
  26.     return dmin <= Math.pow(sphere.radius, 2);
  27. }



  • Para mover as naves só tedes que engadirlles unha velocidade ó eixe z.
  • Podedes variar a tarefa e facela tan complexa como queirades.
Así podedes (optativo):
  • Darlle a cada nave un valor aleatorio de velocidade, indicando cunha cámara ortográfica na parte superior á altura de cada nave á velocidade asinada.
  • Controlar cun raio cando o usuario preme na pantalla e o fai sobre a nave esta empece a moverse.
  • Levar un contador de naves que chegaron á Terra e nave que se perderon.
  • Facer que a cámara siga á nave cando estea en movemento ata que desapareza.



  • Comprimide a clase nun zip co voso nome e apelidos e subídeo xunto coas outras actividades.

XOGO PROPOSTO

Nota: Se escolledes facer o xogo non será necesario entregar as tarefas.

Por motivos de tempo non é necesario separar a programación en Modelo-Vista-Controlador, pero eu vos aconsello a lo menos facer a parte de Modelo creando as clases base para gardar a información das figuras 3D e a clase Mundo.

Despois podedes facer o control na propia clase que renderiza.

  • O xogo a descargar:


O xogo a desenvolver:

Nome e datos principais

  • NOME: ESQUIVA.
  • HISTORIA: Perdido polo espazo tes que chegar a Terra o antes posible. Estás polo que parece ser unha vía espacial no que non paran de aparecer grandes bloques de plasma.
A túa misión é aguantar 120 segundos ata chegar á Terra esquivando os bloques de plasma.
Cada 30 segundos conseguirás aumentar a velocidade da nave para chegar antes á Terra.
  • OBXECTIVO: SOBREVIVE DURANTE 120 SEGUNDOS.
  • CATEGORÍA: Casual.
LIBGDX UD4 Tarefas XogoProposto 1.jpg


Gráficos

Tedes neste zip os gráficos para realizar o xogo: Media:LIBGDX_assets3D.zip




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