entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

1voto

¿Libgdx para que dos texturas interactúen?

¿Como hago para que una textura este encima de otra textura? es decir que una textura este encima de una plataforma cuando se desplace o salte ,que no traspase y se quede encima
de ella.

¿Como se debería hacer?

1 Respuesta

1voto

white Puntos75880

Hola @carla_Maria,

Lo que mencionas en el mundo del desarrollo de videojuegos se lo conoce como colisiones, Hay varias formas de detectar una colisión, la mas usada es la colisión rectangular ( bounding box collision ), hay colisiones por píxeles o algoritmos para cuando tu sprite es circular o irregular.

Según entiendo tu pregunta, lo que deseas es un escenario donde haya gravedad y una plataforma, tienes 2 opciones:

  • defines tu la gravedad y la plataforma, actualizando en el render la posicion de tus sprites.
  • usar un motor de físicas para tu proyecto, como Libgdx, Chipmunk2D, etc. generalmente estos motores vienen ya incluidos en los motores de videojuegos como libgdx, cocos2d-x, unity, etc

Usando Box2D y Libgdx:

Para poder usar Box2D en conjunto con Libgdx es necesario que definas el mundo y la gravedad, asi como agregar los cuerpos con sus propiedades, hay varios tipos de cuerpos, los estaticos, los dinamicos y los kinematicos.

Primero define las variables en tu clase:

public class ExampleGame extends ApplicationAdapter {
    private SpriteBatch batch;
    private Sprite player;  
    private World world;
    private Body spriteBody;
    private Body floorBody;
    private final float PX_TO_METERS = 80f;

batch el batcher para el render
player el sprite del juego
world el mundo
spriteBody el cuerpo del sprite para el mundo
floorBody el cuerpo estatico del piso
PX_TO_METERS Ya que box2d no usa pixeles sino metros ( MKS ) tenemos que tener una relacion para las medidas, ( http://box2d.org/2011/12/pixels/ )


en tu metodo create define el mundo, el sprite y crea los cuerpos.

@Override
public void create () {

    // definimos el batch
    batch = new SpriteBatch();

    // definimos el nuevo mundo con gravedad
    world = new World(new Vector2(0, -98f), true);

    // creamos el sprite con textura y definimos el tamaño y su posicion
    player = new Sprite(new Texture(Gdx.files.internal("player.png")));
    player.setSize(50, 50);
    player.setPosition(
        Gdx.graphics.getWidth() / 2 - player.getWidth() / 2,
        Gdx.graphics.getHeight() / 2
    );

    // definimos el cuerpo del sprite
    setSpriteBody();

    // definimos el cuerpo del piso
    setFloorBody();
}

las funciones setSpriteBody y setFloorBody` definen los cuerpos y sus propiedades.

setSpriteBody:

private void setSpriteBody() {

    // creamos el cuerpo
    BodyDef bodyDef = new BodyDef();

    // definimos el tipo de cuerpo y su posicion en el mundo
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    bodyDef.position.set(player.getX(), player.getY());

    // agregamos el cuerpo al mundo
    spriteBody = world.createBody(bodyDef);

    // creamos un poligono en forma de caja con medidas de
    // acuerdo al sprite
    PolygonShape shape = new PolygonShape();
    shape.setAsBox(player.getWidth()/2 / PX_TO_METERS, player.getHeight() /2 / PX_TO_METERS);

    // definimos las propiedades del cuerpo
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 1f;

    // agregamos las propiedades al cuerpo
    Fixture fixture = spriteBody.createFixture(fixtureDef);

    // la forma del cuerpo no servira mas de ahora en adelante
    shape.dispose();
}

setFloorBody:

private void setFloorBody()
{
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.StaticBody;
    bodyDef.position.set(0, 0);

    floorBody = world.createBody(bodyDef);

    PolygonShape shape = new PolygonShape();
    shape.setAsBox(Gdx.graphics.getWidth(), 0);

    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 1f;

    Fixture fixture = floorBody.createFixture(fixtureDef);

    shape.dispose();
}

El metodo render:

@Override
public void render()
{
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // actualizamos el mundo en cada frame
    world.step(Gdx.graphics.getDeltaTime(), 6, 2);

    // actualizamos la posicion del sprite de acuerdo a la posicion del cuerpo
    // en el mundo
    player.setPosition(spriteBody.getPosition().x, spriteBody.getPosition().y);

    batch.begin();
    player.draw(batch);
    batch.end();
}

el resultado:

libgdx box2D


si deseas ver todo el codigo te dejo el proyecto: https://db.tt/W80kcXx2


Enlaces interesantes:

Libgdx Box2d Github
LibGDX Tutorial 13: Physics with Box2D Part 1: A Basic Physics Simulations.
http://tutoriales.tiarsoft.com/p/tutoriales-de-box2d-con-libgdx.html

0voto

carla_Maria comentado

Cual es la diferencia entre que defina yo la gravedad y la plataforma con
usar un motor de física para mi proyecto(Box2D) ?

¿Cual sería la mejor opción ?

0voto

white comentado

si defines tu la gravedad y el escenario vas a tener que encargarte de las fisicas y los calculos por tu cuenta. la cuestion es mover el sprite constantemente hacia abajo.

// si el sprite ha llegado a la posicion Y del piso, lo mantenemos en esta posicion
if( sprite.getY() < piso.getY() )
    sprite.setPositionY( piso.getY() );

else // movemos al sprite constantemente hacia abajo
    sprite.setPositionY( sprite.getY() - (GRAVEDAD * delta) );

Que sucederia si quieres que haya factores como el viento, el peso del sprite, etc. vas a tener que hacer calculos y algoritmos.

Todo depende de la complejidad de tu juego, box2D viene con opciones para detectar colisiones entre cuerpos agregar fuerza e impulso a un cuerpo, etc

si tu juego es simple no uses fisicas, esta muy por demás, podria afectar tu performance, en juegos un retraso de segundos es circustancial.

libgdx tiene varios metodos para detectar colisiones

Rectangle player = new Rectangle(10, 10, 20, 20);
Rectangle enemigo = new Rectangle(15, 15, 20, 20);

if( Intersector.overlaps(player, enemigo) )
{
    // aca hay una colision entre player y enemigo
    // tomemos medidas
}

http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/Intersector.html

0voto

carla_Maria comentado

Gracias por tu respuesta :)

0voto

carla_Maria comentado

Y si la plataforma es una subida y quiero que cambiase de movimiento mi personaje seria exactamente igual?

0voto

carla_Maria comentado

Y si la plataforma es una subida y quiero que cambiase de movimiento mi personaje seria exactamente igual?

0voto

white comentado

es igual, solo que hablamos de que el sprite continuamente esta moviendose para el eje + Y

sprite.setPosition( sprite.getY() + (velocidad_subida * delta) );

if( sprite.getY() >= tope )
    sprite.setPosition( tope );

si tienes mas dudas mientras implementas esto, siempre puedes abrir un nuevo tema cuando desees.

saludos!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta