简体   繁体   中英

LibGDX Tiled Map Collision Detection with Property and Layers

I am building a simple top down RPG game with libGDX but haven't found any precise pointers on how to detect collision on a tiled map.

I have a character class that looks like this

public class Son{

    SpriteBatch batch;
    Texture texture;
    Sprite sprite;

    private TiledMapTileLayer collisionLayer;


    public Son(float x, float y, TiledMapTileLayer collisionLayer){
        this.collisionLayer = collisionLayer;
        batch = new SpriteBatch();
        texture = new Texture(Gdx.files.internal("characters/xter1.png"));
        sprite = new Sprite(texture);
        sprite.setX(x);
        sprite.setY(y);

    }

    public void render(){

        processKeys();
        batch.begin();
        sprite.draw(batch);
        batch.end();

    }


    private void processKeys(){
        if(Gdx.input.isTouched()){
           //Gdx.app.exit();
            Gdx.app.log("x touched", Gdx.input.getX() + "");
            Gdx.app.log("y touched", Gdx.input.getY() + "");

            //480 by 840

            //left
            if(Gdx.input.getX() >= 0 && Gdx.input.getX() <= 80){
                if(Gdx.graphics.getHeight() - Gdx.input.getY() >= Gdx.graphics.getHeight()/6 && Gdx.graphics.getHeight() - Gdx.input.getY() <= Gdx.graphics.getHeight()/6 + 80){
                    sprite.setPosition(sprite.getX() - 10, sprite.getY());
                }
            }

            //right
            if(Gdx.input.getX() >= (int)(Gdx.graphics.getWidth()/8.4) && Gdx.input.getX() <= (int)(Gdx.graphics.getWidth()/8.4) + 80){
                if(Gdx.graphics.getHeight() - Gdx.input.getY() >= Gdx.graphics.getHeight()/6 && Gdx.graphics.getHeight() - Gdx.input.getY() <= Gdx.graphics.getHeight()/6 + 80) {
                    sprite.setPosition(sprite.getX() + 10, sprite.getY());
                }
            }


            //up
            if(Gdx.input.getX() >= (int)(Gdx.graphics.getWidth()/16.8) && Gdx.input.getX() <= (int)(Gdx.graphics.getWidth()/16.8) + 80){
                if(Gdx.graphics.getHeight() - Gdx.input.getY() >= Gdx.graphics.getHeight()/3.2 && Gdx.graphics.getHeight() - Gdx.input.getY() <= Gdx.graphics.getHeight()/3.2 + 80){
                    sprite.setPosition(sprite.getX(), sprite.getY() + 10);
                }
            }
            //down
            if(Gdx.input.getX() >= (int)(Gdx.graphics.getWidth()/16.8) && Gdx.input.getX() <= (int)(Gdx.graphics.getWidth()/16.8) + 80){
                if(Gdx.graphics.getHeight() - Gdx.input.getY() >= Gdx.graphics.getHeight()/48 && Gdx.graphics.getHeight() - Gdx.input.getY() <= Gdx.graphics.getHeight()/48 + 80){
                    sprite.setPosition(sprite.getX(), sprite.getY() - 10);

                }
            }
        }
    }

}

This code simply changes the location of a sprite based on what part of the screen a user is pressing.

The Class which contains the tiled map looks like this

public class StageOneScreen implements Screen {
    TiledMap tiledMap;
    OrthographicCamera camera;
    FitViewport viewPort;
    TiledMapRenderer tiledMapRenderer;
    Stage stage;
    ControllerRenderer controllerRenderer;
    Son son;
    private Music music;

    final float GAME_WORLD_HEIGHT = 100;
    final float GAME_WORLD_WIDTH = 50;

    private TiledMap collisionMap;
    private TiledMapTileLayer collisionLayer;


    public StageOneScreen(){
        float aspectRatio = (float) Gdx.graphics.getHeight() / (float) Gdx.graphics.getWidth();

        camera = new OrthographicCamera(GAME_WORLD_HEIGHT * aspectRatio, GAME_WORLD_HEIGHT);
        camera.position.set(GAME_WORLD_WIDTH/2, GAME_WORLD_HEIGHT/2, 0);
        //viewPort = new FitViewport(800, 400, camera);
        camera.setToOrtho(false, 800, 400);
        camera.update();


        tiledMap = new TmxMapLoader().load("stages/stage1.tmx");
        tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);

        stage = new Stage(new ScreenViewport());
        stage.getViewport().update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
        Gdx.input.setInputProcessor(stage);
    }

    @Override
    public void show() {
       // playMusic();
        controllerRenderer = new ControllerRenderer();
        son = new Son(100, 100, collisionLayer);
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glBlendFunc(GL20.GL_BLEND_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();
        tiledMapRenderer.setView(camera);

        tiledMapRenderer.render();
        controllerRenderer.render(camera);
        son.render();
    }

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

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {
        controllerRenderer.dispose();

    }

    public void playMusic(){
        // load music asset and check if the loop state before playing it
        music =  SoundAsset.loadMusic(SoundAsset.MUSIC_NAME);
        music.setLooping(true);
        if (music.isLooping())
            music.play();
    }
}

On the tiled map I am rendering, I have given certain tiles the property "wall". I also use two layers. The tiles I don't want the "Son" character to be able to move through are on the second layer. How do I stop the character from going through certain tiles?

if you are using the TiledMap Editor : http://www.mapeditor.org/ , you can set your collision properties using some tags from the editor and retreive the value from your code.

When i was using Libgdx for a small 2D game, i had a strategy pattern to draw and move the objects. On the assumption that you already set some properties, just read it and do your logic. Something like "on player move, if nextCase == wall , nextCase = currentCase"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM