libGDX:如何处理Tiled对象层中sprite的冲突?

Ric*_*ard 1 java android collision-detection libgdx

我正在使用libGDXTiled制作一个RPG.我已经有很多工作了:标题屏幕,测试屏幕,我的地图已加载.我可以阅读我放在地图上和某些瓷砖上的属性.我也可以在地图上移动一切,但我现在要弄清楚的是:

如何从对象层渲染地图对象并处理碰撞?

我想在我的碰撞层使用Tiled的Object层.IE:在我不希望角色能够通过的某些瓷砖/区域周围放置形状.

这是我到目前为止:

package rawct.awakening;

import java.lang.reflect.Method;
import java.util.Iterator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.maps.MapObject;
import com.badlogic.gdx.maps.MapObjects;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMapTileSet;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;

public class GameMap extends TiledMap {
    private String TAG = "GameMap";
    private TmxMapLoader loader = new TmxMapLoader();
    private OrthogonalTiledMapRenderer mRender;

    private TiledMap gamemap;
    private TiledMapTileLayer mapTiles;

    private ObjectMap<TiledMapTile, Boolean> Blocked;
    private ObjectMap<TiledMapTile, Boolean> Event;

    private MapObjects mObjects = new MapObjects();
    private MapObject mObj;

    public void draw(OrthographicCamera cam){
        mRender.setView(cam);
        mRender.render();
    // Should render my map object?
        mRender.renderObject(mObj);
    }

    public GameMap(String Map){
        Blocked = new ObjectMap<TiledMapTile, Boolean>();
        Event = new ObjectMap<TiledMapTile, Boolean>();

        gamemap = loader.load("maps/"+Map+".tmx");
        mRender = new OrthogonalTiledMapRenderer(gamemap);
        loadMap(gamemap);
    }

    private Cell getCellAt(float x, float y){
        return mapTiles.getCell((int)x, (int)y);
    }

    private TiledMapTile getTileAt(float x, float y){
        Cell cell = getCellAt(x, y);
        return cell != null ? cell.getTile() : null;
    }

    public boolean isTileBlocked(float x, float y){
        try {
            return Blocked.get(getTileAt(x, y));
        } catch (Exception e) {
            Gdx.app.log(TAG, e.toString());
            return false;
        }
    }

    private void loadMap(TiledMap map) {
        String sI = null;
        Blocked.clear();
        Event.clear();

        try{
            mapTiles = (TiledMapTileLayer)map.getLayers().get(0);
            mObjects = map.getLayers().get("Testing").getObjects();
        } catch (Exception e) {
            Gdx.app.log(TAG, e.toString());
        }


        Gdx.app.log(TAG, "Objects:"+mObjects.getCount());

        for(Iterator<MapObject> mObjs = mObjects.iterator(); mObjs.hasNext();){
        // I have set just about everything possible(I only have one object at the moment so mObj only gets set once.
            mObj = mObjs.next();
            Gdx.app.log(TAG, "Obj:"+mObj.getName());
            mObj.setColor(Color.GREEN);
            mObj.setOpacity(1f);
            mObj.setVisible(true);

//          try {
//              Method Test = getClass().getDeclaredMethod((String) mObj.getProperties().get("Func"));
//              Test.invoke(this);
//          } catch (Exception e) {
//              Gdx.app.log(TAG, e.toString());
//          }
        }

        Array<String> sTilesets = new Array<String>();
        TiledMapTile tile;

        try {
            for(Iterator<TiledMapTileSet> tilesets = map.getTileSets().iterator(); tilesets.hasNext();){
                    sI = tilesets.next().getName();
                    sTilesets.add(sI);
            }

            int tCount = sTilesets.size;
            for(int i = 0; i < tCount; i++){
                for(Iterator<TiledMapTile> tiles = map.getTileSets().getTileSet(sTilesets.get(i)).iterator(); tiles.hasNext();){
                tile = tiles.next();

                if(tile.getProperties().containsKey("blocked")){
                    //Gdx.app.log(TAG, "Tile:" + tile.getId() + " blocked!");
                }

                if(tile.getProperties().containsKey("name")){
                    //Gdx.app.log(TAG, "Name:" + tile.getProperties().get("name"));
                }

                boolean blocked = Boolean.parseBoolean(tile.getProperties().get("blocked", "false", String.class));
                boolean event = Boolean.parseBoolean(tile.getProperties().get("event", "false", String.class));

                Blocked.put(tile, blocked);
                Event.put(tile, event);
            }
        }
            Gdx.app.log(TAG, "Map Loaded!");
        } catch (Exception e) {
            Gdx.app.log(TAG, "Error:" + e.toString());
        }
    }

    public TiledMap getMap(){
        return gamemap;
    }
}
Run Code Online (Sandbox Code Playgroud)

dae*_*ina 6

最近我在GameDev上回答了类似的问题,一段时间以来一直受到同样问题的困扰.一个彻底的谷歌搜索最终让我得到关于这个主题的教程.我的意思是彻底的.它似乎是整个互联网上解决这个问题的唯一方法.奇怪的.

无论如何.我给出的答案和基于它的教程都使用Box2d来处理碰撞检测.我衷心建议走这样一条路,如果你不是太遥远让您的游戏:Box2D的处理相当多的你,如果你使用它,但它确实意味着重新思考了很多现有的代码.一切与运动有关,基本上.如果你选择这样做,那么好的旧LibGDX wiki可以让你开始(这是与相关文章的直接链接).

如果你不想去那个兔子洞,那么上面的链接仍然建议一个解决方案.在我认为你出错的地方是试图MapObject直接画出s.试试这个:

MapObjects objects = map.getLayers().get("Obstacles").getObjects();

for(MapObject object : objects) {
    if (object instanceof RectangleMapObject) {
        Rectangle rect = ((RectangleMapObject) object).getRectangle();
        // do something with rect...
    }
    else if (object instanceof PolygonMapObject) {
        Polygon polygon = ((PolygonMapObject) object).getPolygon();
        // do something with polygon...
    }
    else if (object instanceof PolylineMapObject) {
        Polyline chain = ((PolylineMapObject) object).getPolyline();
        // do something with chain...
    }
    else if (object instanceof CircleMapObject) {
        Circle circle = ((CircleMapObject) object).getCircle();
        // do something with circle...
    }
}
Run Code Online (Sandbox Code Playgroud)

从那里你处理生成的形状(Rectangle或你有什么)而不是MapObjects.它们具有用于碰撞检测的方法,例如overlaps(),contains()等等.如果你只处理一种形状,那么它可以让你在非Box2d游戏中变得更轻松.例如,仅使用if语句PolygonMapObject,然后删除其他三个语句.