Как правильно нарисовать границы столкновений в LibGDX? - PullRequest
2 голосов
/ 27 февраля 2020

Я пытаюсь сделать основную c RPG игру, покемоны выглядят одинаково. Моя проблема в том, что я не могу понять, как правильно рисовать коллизии в моей игре. Я не знаю, как и почему, но кажется, что они не масштабируются, как ожидалось. Здесь я показываю пример: Wrong drawing collission И вот как это должно выглядеть: Good drawing collission Вот код, первая часть - родительский класс.

public class BaseScreen implements Screen {
    protected Juego game;
    protected World world;
    protected Actores stage;
    protected Stage pantalla;
    protected TiledMap map;
    protected static int WIDTH; //Aquí almacenaremos la anchura en tiles
    protected static int HEIGHT; //Aquí almacenaremos la altura en tiles
    protected MapProperties properties;
    protected AssetManager manager;
    protected int tileWidth, tileHeight,
            mapWidthInTiles, mapHeightInTiles,
            mapWidthInPixels, mapHeightInPixels;
    protected OrthographicCamera camera;
    protected Jugador jugador;
    public static final float unitScale = 1 / 32f;//Nos servirá para establecer que la pantalla se divide en tiles de 32 pixeles
    public static final float pixelsPorCuadro=32f;
    protected OrthogonalTiledMapRenderer renderer;
    protected ShapeRenderer shapeRenderer;
    protected TiledMapTileLayer terrainLayer,terrainLayer2,terrainLayer3;
    protected Colisiones colisiones;


    public BaseScreen(Juego g){

        game=g;

    }
    @Override
    public void show() {
    }

    @Override
    public void render(float delta) {

    }


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

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    } 

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {
        manager.dispose();
        jugador.dispose();
        renderer.dispose();
        pantalla.dispose();
    }

}

И второй расширяется:

public class Mapa1 extends BaseScreen {
    private Juego juego;
    public Mapa1(Juego g){
        super(g);
        this.juego=g;
        shapeRenderer=new ShapeRenderer();


        TiledMap map = new TmxMapLoader().load("Mapas/InteriorCasaInicialFinal.tmx");
        renderer = new OrthogonalTiledMapRenderer(map,unitScale);
        camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
        camera.translate(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
        camera.update();
        MapProperties properties = map.getProperties();
        tileWidth = properties.get("tilewidth", Integer.class);
        tileHeight = properties.get("tileheight", Integer.class);
        mapWidthInTiles = properties.get("width", Integer.class);
        mapHeightInTiles = properties.get("height", Integer.class);
        mapWidthInPixels = mapWidthInTiles * tileWidth;
        mapHeightInPixels = mapHeightInTiles * tileHeight;


        jugador=new Jugador(map,camera,280,40,mapWidthInPixels/20 ,mapHeightInPixels/20 );
        System.out.println(mapWidthInTiles);//El sout de mapWidthInTiles y Heigh da la altura y anchura del mapa, el de Gdx da el viewportWidth y Heigth
        System.out.println(mapHeightInTiles);
        //

        //Establecemos el zoom de la cámara. 0.1 es más cercano que 1.
        WIDTH = ((TiledMapTileLayer) map.getLayers().get(0)).getWidth(); //Obtenemos desde el mapa el número de tiles de ancho de la 1º Capa
        HEIGHT = ((TiledMapTileLayer) map.getLayers().get(0)).getHeight(); //Obtenemos desde el mapa el número de tiles de alto de la 1º Capa
        System.out.println(WIDTH);
        System.out.println(HEIGHT);
        camera.setToOrtho(false, WIDTH,HEIGHT); //Establecemos la cámara, y le decimos cuanto tiene que ocupar. Doc:

        camera.position.x=WIDTH/2;
        camera.position.y=HEIGHT/2;
        camera.position.set(WIDTH/2,HEIGHT/2,1);



        MapLayers mapLayers = map.getLayers();

        terrainLayer = (TiledMapTileLayer) mapLayers.get("Suelo");
        terrainLayer2 = (TiledMapTileLayer) mapLayers.get("Cosas");


        colisiones=new Colisiones();
        colisiones.checkCollision(map,jugador);


        InputMultiplexer multiplexer = new InputMultiplexer();
        multiplexer.addProcessor(new TecladoJugador(jugador));
        Gdx.input.setInputProcessor(multiplexer);
        pantalla=new Stage();
        pantalla.setDebugAll(true);
        pantalla.addActor(jugador);

        for(int b=0;b<colisiones.getActores().length-1;b++){
            pantalla.addActor(colisiones.getActores()[b]);

        }
        System.out.println(colisiones.getActores().length);
    }

    public OrthographicCamera getCamera() {
        return camera;
    }

    public int getMapWidthInPixels() {
        return mapWidthInPixels;
    }

    public int getMapHeightInPixels() {
        return mapHeightInPixels;
    }

    @Override
    public void show() {


    }

    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(0, 0, 0, 1);

        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        super.render(delta);
        renderer.getBatch().begin();
        renderer.renderTileLayer(terrainLayer);
        renderer.getBatch().end();
        jugador.dibujarConHitbox();

        renderer.getBatch().begin();
        renderer.renderTileLayer(terrainLayer2);
        renderer.getBatch().end();


        renderer.setView(camera);
        camera.update();
        pantalla.act(Gdx.graphics.getDeltaTime());
        pantalla.draw();



    }

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

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    public void dispose() {
        manager.dispose();
        jugador.dispose();
        renderer.dispose();
        pantalla.dispose();
    }

    public TiledMap getMap() {
        return map;
    }

}

Может быть, я кое-что забыл загрузить, не стесняйтесь, сообщите мне в комментариях, любая помощь очень ценится!

На самом деле, я не использую ShapeRenderer, я использовал его, но он мне больше не нужен. Вот часть кода, которая может понадобиться:

public class Jugador extends Actor {
    private int x,y;
    private Sprite sprite;
    private Boolean colliding;
    private Texture texture;

    private Animation animation;
    private TextureRegion textureRegion;
    private TextureRegion[][] tmp;
    private String jugadorVista;
    private float tiempo;
    private TextureRegion[] regions;


    private OrthographicCamera camara; //La necesito para que me siga
    private Vector3 posicionTiles;
    private Batch batch;// La uso para dibujar en este batch al jugador. Podría pasarlo por constructor. Es decisión nuestra como programadoeres.
    private Boolean colision;
    //Variables para poder redimensionar al jugador según el zoom
    private TiledMap mapa; //Necesito el mapa para poder redimensionar al jugador
    private int anchuraMapaPixels; //Anchura del mapa donde nos movemos en pixels
    private int alturaMapaPixels; //Altura del mapa donde nos movemos en pixels
    private int anchuraMapaTiles; //Anchura del mapa donde nos movemos en  tiles
    private int alturaMapaTiles; //Anchura del mapa donde nos movemos en tiles
    private Rectangle rectangle;
    private Rectangle[]rectangles;
    private Colisiones colisiones;
     float anchoJugador, largoJugador;
    public Jugador(TiledMap mapa, OrthographicCamera c,int posicionPersonajeX, int posicionPersonajeY, float anchoJugador, float largoJugador) {
        this.x=posicionPersonajeX;
        this.y=posicionPersonajeY;
        this.anchoJugador=anchoJugador;
        this.largoJugador=largoJugador;
        texture=new Texture(Gdx.files.internal("Sprites/gfx/character.png"));
        this.sprite = new Sprite(texture);
        colliding=new Boolean(false);
        this.camara = c;
        colisiones=new Colisiones();
        colisiones.checkCollision(mapa,this);
        rectangles=colisiones.getRect();
        rectangle=new Rectangle(posicionPersonajeX,posicionPersonajeY,texture.getWidth(),texture.getHeight());
        posicionTiles=new Vector3();
        batch=new SpriteBatch();
        anchuraMapaTiles = ((TiledMapTileLayer) mapa.getLayers().get(0)).getWidth(); //Obtenemos desde el mapa el número de tiles de ancho de la 1º Capa
        alturaMapaTiles = ((TiledMapTileLayer) mapa.getLayers().get(0)).getHeight(); //Obtenemos desde el mapa el número de tiles de alto de la 1º Capa
        System.out.println(sprite.getX());
        System.out.println(sprite.getY());
        anchuraMapaPixels=anchuraMapaTiles*(int)mapa.getProperties().get("width");
        alturaMapaPixels=alturaMapaTiles*(int)mapa.getProperties().get("height");
        //sprite.setPosition(250,250);
        sprite.setBounds(posicionPersonajeX,posicionPersonajeY,anchoJugador,largoJugador);
        //x e y es donde aparece el personaje, width y height altura y anchura
       jugadorVista="";
        tmp = TextureRegion.split(texture, texture.getWidth() / 17, texture.getHeight() / 8);
        regions = new TextureRegion[4];
        for (int b = 0; b < regions.length; b++) {
            regions[b] = tmp[0][0];
            animation = new Animation((float) 0.2, regions);
            tiempo = 0f;
        }
    }


    /**
     * Esta función redimensiona el sprite del jugador según el tamaño del mapa,
     * el tamaño de la propia textura del jugador, y el zoom actual. Debería llamarse
     * en dibujar.
     */

    public Rectangle getHitBox(){
        return sprite.getBoundingRectangle();
    }

    public void dibujarConHitbox( SpriteBatch batch){

        tiempo += Gdx.graphics.getDeltaTime();
        textureRegion = (TextureRegion) animation.getKeyFrame(tiempo, true);
        setBounds(x,y,anchoJugador-1,largoJugador-5);
        batch.draw(textureRegion, x, y,anchoJugador,largoJugador);



    }

Кроме того, вот код, который вызывает aws столкновения объектов:

public class Colisiones {
    private Actor[]actores;
    private Rectangle[]rect;
    private Rectangle jugador;
    public void checkCollision(TiledMap map, Jugador personaje) {
        jugador=new Rectangle();
        jugador.set(personaje.getX(),personaje.getY(),personaje.getWidth(),personaje.getHeight());
        MapObjects mons = map.getLayers().get("Colisionables").getObjects();
       // MapObjects mons2 = map.getLayers().get("Entrada").getObjects();
        actores=new Actor[mons.getCount()];
        rect=new Rectangle[mons.getCount()];
        for (int i = 0;i < mons.getCount(); i++) {
            RectangleMapObject obj1 = (RectangleMapObject) mons.get(i);
            Rectangle rect1 = obj1.getRectangle();
            rect[i]=rect1;
            rect[i].set(rect1.x,rect1.y,rect1.width,rect1.height);
            actores[i]=new Actor();
            actores[i].setBounds(rect1.x,rect1.y,rect1.width,rect1.height);
        }
    }

    public Actor[] getActores() {
        return actores;
    }

    public Rectangle[] getRect() {
        return rect;
    }
}

1 Ответ

1 голос
/ 28 февраля 2020

Попробуйте использовать Stage в сочетании с Viewport:

OrthographicCamera camera = new OrthographicCamera();
camera.setToOrtho(false, x, y);
FitViewport viewport = new FitViewport(x, y, camera); // change this to your needed viewport
SpriteBatch batch = new SpriteBatch();
Stage s = new Stage(viewport, batch);
...