Top Banner
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles © 2011-2012 Depto. Ciencia de la Computación e IA Gráficos y multimedia Sesión 6: Motor de físicas y libgdx
25

Sesión 6: Motor de físicas y libgdx · 2017. 5. 8. · Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles © 2011-2012 Depto. Ciencia de la Computación

Feb 07, 2021

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    © 2011-2012 Depto. Ciencia de la Computación e IA

    Gráficos y multimedia

    Sesión 6: Motor de físicas y libgdx

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Puntos a tratar• Motor libgdx• Módulos de libgdx• Gráficos• Escena 2D

    • Motor Box2D• Objetos de Box2D• Tipos de cuerpos• Unidades de medida• Simulación física• Detección de colisiones

    2

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Motor libgdx

    • Framework para videojuegos en Java SE y Android

    • Implementamos dos proyectos para hacerlo multiplataforma

    • Proyecto Java SE• Se implementa el juego con Java genérico y libgdx• Se puede ejecutar como aplicación de escritorio

    • Proyecto Android• Depende del proyecto anterior• Aporta la actividad principal que ejecuta en Android el juego

    3

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Aplicación libgdx• Gestiona el ciclo OpenGL del juego• Aplicación Android

    • Aplicación libgdx

    4

    public  class  MiActividad  extends  Activity  {      protected  void  onCreate(Bundle  savedInstanceState)  {            super.onCreate(savedInstanceState);            ...      }}

    public  class  MiActividad  extends  AndroidApplication  {      protected  void  onCreate(Bundle  savedInstanceState)  {            super.onCreate(savedInstanceState);            initialize(new  MiApplicationListener(),  false);      }}

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    ApplicationListener

    5

    public  class  MiApplicationListener                                      implements  ApplicationListener  {   @Override   public  void  create()  {  ...  }

      @Override   public  void  pause()  {  ...  }

      @Override   public  void  resume()  {  ...  }     @Override   public  void  dispose()  {  ...  }

      @Override   public  void  resize(int  width,  int  height)  {  ...  }

      @Override   public  void  render()  {  ...   }}

    Ciclo del juego:•Actualizar la escena•Renderizar gráficos

    Cambio del tamaño de la pantalla (p. ej. cambio de orientación)

    Liberar recursos

    Reanudar el juego

    Inicializar el juego

    Pausar el juego (p. ej. llamada recibida)

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Módulos de libgdx

    • Utilidades para el desarrollo de videojuegos• Los encontramos disponibles como campos estáticos de Gdx

    6

    Gdx.graphics Acceso al contexto gráfico (OpenGL)

    Gdx.audio Reproducción de música y efectos de sonido

    Gdx.input Acceso a la entrada (pantalla táctil y acelerómetro)

    Gdx.files Acceso a los ficheros (assets)

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Gráficos en libgdx

    • Tenemos acceso al contexto OpenGL

    • Tiempo delta• Indica el tiempo transcurrido desde la anterior iteración

    7

    int  width  =  Gdx.graphics.getWidth();int  height  =  Gdx.graphics.getHeight();                      GL10  gl  =  Gdx.app.getGraphics().getGL10();gl.glClear(GL10.GL_COLOR_BUFFER_BIT  |  GL10.GL_DEPTH_BUFFER_BIT);gl.glViewport(0,  0,  width,  height);

    Gdx.graphics.getDeltaTime()

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Clases para gráficos

    8

    Texture Textura OpenGL (potencia de 2)

    TextureAtlas Textura con regiones (TexturePacker)

    TextureRegion Zona de una textura en memoria

    Sprite Región con posición y rotación

    BitmapFont Fuente bitmap (formato .fnt)

    SpriteBatch Dibujar múltiples sprites 2D

    Mesh Malla 3D

    ObjLoader Carga una malla 3D de un fichero .obj

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Carga de sprite sheets

    • Podemos cargar sprite sheets generados con TexturePacker• Contamos con una herramienta gratuita propia de libgdx• El formato generado es distinto al de Cocos2D

    • Las texturas en memoria (atlas) deberemos liberarlas con dispose() cuando no se vayan a utilizar más

    9

    TextureAtlas  atlas  =  new  TextureAtlas(Gdx.files.getFileHandle("sheet",                                                                              FileType.Internal));TextureRegion  regionPersonaje  =  atlas.findRegion("frame01");TextureRegion  regionEnemigo  =  atlas.findRegion("enemigo");  Sprite  spritePersonaje  =  new  Sprite(regionPersonaje);Sprite  spriteEnemigo  =  new  Sprite(regionEnemigo);

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Dibujar en un sprite batch

    • Dibujar sprites de una misma textura de forma consecutiva

    • Al cambiar de textura toda la geometría pendiente se envía a la GPU

    • Es importante liberar el batch al finalizar

    10

    public  class  MiJuego  implements  ApplicationListener  {        SpriteBatch  batch;        TextureAtlas  atlas;        Sprite  spritePersonaje;        Sprite  spriteEnemigo;                  @Override        public  void  create()  {                //  Inicializar  atlas  y  sprites                ...                batch  =  new  SpriteBatch();        }        @Override        public  void  dispose()  {                batch.dispose();                atlas.dispose();        }        @Override        public  void  render()  {                batch.begin();                spritePersonaje.draw(batch);                spriteEnemigo.draw(batch);                batch.end();                }                    }

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Tilemaps• Soporta formato TMX, pero necesitamos generar un fichero

    adicional con una herramienta incluida con libgdx• Creamos TiledMap (mosaico) y TileAtlas (textura en memoria)

    • Creamos TileMapRenderer para dibujar el mapa en pantalla

    • Dibujamos el mapa dentro del ciclo del juego

    11

    TiledMap  fondoMap  =  TiledLoader.createMap(            Gdx.files.getFileHandle("fondo.tmx",              FileType.Internal));              TileAtlas  fondoAtlas  =  new  TileAtlas(fondoMap,              Gdx.files.getFileHandle(".",  FileType.Internal));

    tileRenderer  =  new  TileMapRenderer(fondoMap,  fondoAtlas,  40,  40);

    tileRenderer.render();

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Grafo de la escena 2D

    • Sólo es útil para la UI en libgdx

    12

    Button Label

    ImageLabel Group Action

    Stage

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Acciones en la escena 2D• Creamos la escena

    • Añadimos un actor (nodo) a la escena

    • Añadimos acciones al actor

    • Actializamos y renderizamos la escena en el ciclo del juego

    13

    stage  =  new  Stage(width,  height,  false);

    Label  label  =  new  Label("gameover",  fuente,  "Game  Over");stage.addActor(label);

    FadeIn  fadeIn  =  FadeIn.$(1);FadeOut  fadeOut  =  FadeOut.$(1);Delay  delay  =  Delay.$(fadeOut,  1);Sequence  seq  =  Sequence.$(fadeIn,  delay);Forever  forever  =  Forever.$(seq);label.action(forever);

    @Overridepublic  void  render()  {        stage.act(Gdx.graphics.getDeltaTime());        stage.draw();}

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Motor de físicas Box2D• Físicas de cuerpos rígidos• Escrito en C++• Se incluye en casi todos los motores anteriores• AndEngine, Cocos2D, libgdx

    14

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Conceptos de Box2D

    15

    Body Cuerpo rígido. Puede ser estático, cinemático, o dinámico

    Fixture Fija las propiedades de un cuerpo, incluyendo su forma

    Shape Define la forma de un cuerpo (círculo o polígono)

    Constraint Limita los grados de libertad de un objeto

    Joint Define una unión de diferentes cuerpos

    World Simulación del mundo 2D. Contiene un conjunto de cuerpos

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Mundo de Box2D

    • Se encarga de realizar la simulación física

    • Podemos añadir al mundo diferentes cuerpos rígidos

    • Se crea con el vector de gravedad a aplicar• La gravedad se indica mediante un vector 2D (x, y)• El segundo parámetro nos permite optimizar el rendimiento,

    evitando que se simulen los cuerpos inactivos si es true

    • Podemos cambiar la gravedad con setGravity

    16

    World  world  =  new  World(new  Vector2(0,  -‐10),  true);

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Tipos de cuerpos en Box2D

    17

    Estático

    CinemáticoDinámico

  • • Usa el sistema métrico (m, kg)• Debemos fijar ratio de conversión píxeles-metros• Optimizado para manejar objetos de 1 metro

    Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Unidades de medida en Box2D

    18

        BodyDef  bodyDef  =  new  BodyDef();     bodyDef.type  =  BodyType.DynamicBody;       bodyDef.position.x  =  x  /  PTM_RATIO;     bodyDef.position.y  =  y  /  PTM_RATIO;

        Body  body  =  world.createBody(bodyDef);         PolygonShape  bodyShape  =  new  PolygonShape();     bodyShape.setAsBox((width/2)  /  PTM_RATIO,  (height/2)  /  PTM_RATIO);     body.createFixture(bodyShape,  1.0f);     bodyShape.dispose();  

    PTM_RATIO  =  32width  =  32  (1m)height  =  64  (2m)

    32  px1  m

    64  px2  m

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Límites del escenario• Podemos crearlos como objetos estáticos de tipo arista

    19

    BodyDef  limitesBodyDef  =  new  BodyDef();limitesBodyDef.position.x  =  x;limitesBodyDef.position.y  =  y;                                  Body  limitesBody  =  world.createBody(limitesBodyDef);EdgeShape  limitesShape  =  new  EdgeShape();limitesShape.set(new  Vector2(0.0f  /  PTM_RATIO,  0.0f  /  PTM_RATIO),                                    new  Vector2(width  /  PTM_RATIO,  0.0f  /  PTM_RATIO));limitesBody.createFixture(limitesShape,0).setFriction(2.0f);  limitesShape.set(new  Vector2(width  /  PTM_RATIO,  0.0f  /  PTM_RATIO),                                    new  Vector2(width  /  PTM_RATIO,  height  /  PTM_RATIO));limitesBody.createFixture(limitesShape,0);  limitesShape.set(new  Vector2(width  /  PTM_RATIO,  height  /  PTM_RATIO),                                    new  Vector2(0.0f  /  PTM_RATIO,  height  /  PTM_RATIO));limitesBody.createFixture(limitesShape,0);  limitesShape.set(new  Vector2(0.0f  /  PTM_RATIO,  height  /  PTM_RATIO),                                    new  Vector2(0.0f  /  PTM_RATIO,  0.0f  /  PTM_RATIO));limitesBody.createFixture(limitesShape,0);

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Simulación física• En cada iteración del ciclo del juego debemos actualizar la

    simulación del mundo físico• Debemos proporcionar el delta time en la actualización

    20

    //  Ejecuta  la  simulaciónworld.step(delta,  6,  2);world.clearForces();    //  Lee  datos  de  los  cuerpos  en  la  simulación  físicaVector2  pos  =  cuerpo.getPosition();float  rot  =  (float)Math.toDegrees(cuerpo.getAngle());

    Conviene acortarlo

    Iteraciones posición

    Iteraciones velocidad

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Datos de usuario de los cuerpos• Podemos asignar datos de usuarios genéricos a los cuerpos• Útil para adjuntar el sprite asociado al cuerpo

    • El cuerpo de Box2D sólo realiza simulación física• Nosotros debemos mostrarlo en pantalla mediante un sprite• Esto lo haremos tras la actualización del mundo

    21

    body.setUserData(sprite);

    Sprite  sprite  =  (Sprite)body.getUserData();Vector2  pos  =  body.getPosition();float  rot  =  (float)Math.toDegrees(body.getAngle());  sprite.setPosition((int)(pos.x  *  PTM_RATIO),  (int)(pos.y  *  PTM_RATIO));sprite.setRotation(rot);  batch.begin();sprite.draw(batch);batch.end();

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Detección de colisiones• Podemos definir listener de contacto (ContactListener)

    22

    @Overridepublic  void  beginContact(Contact  c)  {        //  Se  produce  un  contacto  entre  dos  cuerpos}  @Overridepublic  void  endContact(Contact  c)  {        //  El  contacto  entre  los  cuerpos  ha  finalizado            }  @Overridepublic  void  preSolve(Contact  c,  Manifold  m)  {        //  Se  ejecuta  antes  de  resolver  el  contacto.          //  Podemos  evitar  que  se  procese        }  @Overridepublic  void  postSolve(Contact  c,  ContactImpulse  ci)  {        //  Podemos  obtener  el  impulso  aplicado  sobre  los  cuerpos  en  contacto}

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Velocidad de impacto

    • WorldManifold da información sobre los puntos de contacto

    23

    public  void  beginContact(Contact  c)  {        Body  bodyA  =  c.getFixtureA().getBody();        Body  bodyB  =  c.getFixtureB().getBody();                          //  Obtiene  el  punto  de  contacto        Vector2  point  =  c.getWorldManifold().getPoints()[0];                          //  Calcula  la  velocidad  a  la  que  se  produce  el  impacto        Vector2  velA  =  bodyA.getLinearVelocityFromWorldPoint(point);        Vector2  velB  =  bodyB.getLinearVelocityFromWorldPoint(point);                          float  vel  =  c.getWorldManifold().getNormal().dot(velA.sub(velB));            ...}

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    Impulso durante el contacto

    • Nos informa de la fuerza ejercida entre los cuerpos mientras dura el contacto

    24

    public  void  postSolve(Contact  c,  ContactImpulse  ci)  {                  Body  bodyA  =  c.getFixtureA().getBody();        Body  bodyB  =  c.getFixtureB().getBody();                          float  impulso  =  ci.getNormalImpulses()[0];}

  • Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles

    Gráficos y multimedia © 2011-2012 Depto. Ciencia de la Computación e IA Motor de físicas

    ¿Preguntas...?

    25