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.