8000 Feature Added: A Universal Tiled Map Loader by BoBIsHere86 · Pull Request #7640 · libgdx/libgdx · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Feature Added: A Universal Tiled Map Loader #7640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.maps.tiled.AtlasTmjMapLoader;
import com.badlogic.gdx.maps.tiled.AtlasTmxMapLoader;
import com.badlogic.gdx.maps.tiled.BaseTiledMapLoader;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.utils.viewport.FitViewport;
Expand Down Expand Up @@ -69,9 +70,9 @@ public class TiledMapPackerTestRender extends ApplicationAdapter {
private final float WORLD_HEIGHT = 8;
private final float PIXELS_PER_METER = 32;
private final float UNIT_SCALE = 1f / PIXELS_PER_METER;
private AtlasTmxMapLoader.AtlasTiledMapLoaderParameters params;
private BaseTiledMapLoader.Parameters params;
private AtlasTmxMapLoader atlasTmxMapLoader;
private AtlasTmjMapLoader.AtlasTiledMapLoaderParameters paramsTmj;
private BaseTiledMapLoader.Parameters paramsTmj;
private AtlasTmjMapLoader atlasTmjMapLoader;
private TiledMap map;
private Viewport viewport;
Expand All @@ -88,7 +89,7 @@ public void create () {
switch (TEST_MAP_TYPE) {
case DEFAULT_TMX_MAP:
atlasTmxMapLoader = new AtlasTmxMapLoader(new InternalFileHandleResolver());
params = new AtlasTmxMapLoader.AtlasTiledMapLoaderParameters();
params = new BaseTiledMapLoader.Parameters();
params.generateMipMaps = false;
params.convertObjectToTileSpace = false;
params.flipY = true;
Expand All @@ -99,7 +100,7 @@ public void create () {
break;
case DEFAULT_TMJ_MAP:
atlasTmjMapLoader = new AtlasTmjMapLoader(new InternalFileHandleResolver());
paramsTmj = new AtlasTmjMapLoader.AtlasTiledMapLoaderParameters();
paramsTmj = new BaseTiledMapLoader.Parameters();
paramsTmj.generateMipMaps = false;
paramsTmj.convertObjectToTileSpace = false;
paramsTmj.flipY = true;
Expand All @@ -110,7 +111,7 @@ public void create () {
break;
case DEFAULT_TMX_IMGLAYER_MAP:
atlasTmxMapLoader = new AtlasTmxMapLoader(new InternalFileHandleResolver());
params = new AtlasTmxMapLoader.AtlasTiledMapLoaderParameters();
params = new BaseTiledMapLoader.Parameters();
params.generateMipMaps = false;
params.convertObjectToTileSpace = false;
params.flipY = true;
Expand All @@ -121,7 +122,7 @@ public void create () {
break;
case DEFAULT_TMX_IMGLAYERS_COLLECTION_TILESET:
atlasTmxMapLoader = new AtlasTmxMapLoader(new InternalFileHandleResolver());
params = new AtlasTmxMapLoader.AtlasTiledMapLoaderParameters();
params = new BaseTiledMapLoader.Parameters();
params.generateMipMaps = false;
params.convertObjectToTileSpace = false;
params.flipY = true;
Expand All @@ -132,7 +133,7 @@ public void create () {
break;
case DEFAULT_TMJ_IMGLAYER_WITH_PROPS_MAP:
atlasTmjMapLoader = new AtlasTmjMapLoader(new InternalFileHandleResolver());
paramsTmj = new AtlasTmjMapLoader.AtlasTiledMapLoaderParameters();
paramsTmj = new BaseTiledMapLoader.Parameters();
paramsTmj.generateMipMaps = false;
paramsTmj.convertObjectToTileSpace = false;
paramsTmj.flipY = true;
Expand Down
1 change: 1 addition & 0 deletions gdx/res/com/badlogic/gdx.gwt.xml
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@
<include name="maps/tiled/BaseTmjMapLoader.java"/>
<include name="maps/tiled/TideMapLoader.java"/>
<include name="maps/tiled/TiledMap.java"/>
<include name="maps/tiled/TiledMapLoader.java"/>
<include name="maps/tiled/TiledMapRenderer.java"/>
<include name="maps/tiled/TiledMapTile.java"/>
<include name="maps/tiled/TiledMapTileLayer.java"/>
Expand Down
15 changes: 5 additions & 10 deletions gdx/src/com/badlogic/gdx/maps/tiled/AtlasTmjMapLoader.java
8000
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,7 @@
*
* @author Justin Shapcott
* @author Manuel Bua */
public class AtlasTmjMapLoader extends BaseTmjMapLoader<AtlasTmjMapLoader.AtlasTiledMapLoaderParameters> {
// TODO: too much duplicate functionality between atlas loaders, any options without making breaking changes?
public static class AtlasTiledMapLoaderParameters extends BaseTmjMapLoader.Parameters {
/** force texture filters? **/
public boolean forceTextureFilters = false;
}
public class AtlasTmjMapLoader extends BaseTmjMapLoader<BaseTiledMapLoader.Parameters> {

protected interface AtlasResolver extends ImageResolver {

Expand Down Expand Up @@ -107,10 +102,10 @@ public AtlasTmjMapLoader (FileHandleResolver resolver) {
}

public TiledMap load (String fileName) {
return load(fileName, new AtlasTiledMapLoaderParameters());
return load(fileName, new Parameters());
}

public TiledMap load (String fileName, AtlasTiledMapLoaderParameters parameter) {
public TiledMap load (String fileName, Parameters parameter) {
FileHandle tmjFile = resolve(fileName);

this.root = json.parse(tmjFile);
Expand All @@ -126,15 +121,15 @@ public TiledMap load (String fileName, AtlasTiledMapLoaderParameters parameter)
}

@Override
public void loadAsync (AssetManager manager, String fileName, FileHandle tmjFile, AtlasTiledMapLoaderParameters parameter) {
public void loadAsync (AssetManager manager, String fileName, FileHandle tmjFile, Parameters parameter) {
FileHandle atlasHandle = getAtlasFileHandle(tmjFile);
this.atlasResolver = new AtlasResolver.AssetManagerAtlasResolver(manager, atlasHandle.path());

this.map = loadTiledMap(tmjFile, parameter, atlasResolver);
}

@Override
public TiledMap loadSync (AssetManager manager, String fileName, FileHandle file, AtlasTiledMapLoaderParameters parameter) {
public TiledMap loadSync (AssetManager manager, String fileName, FileHandle file, Parameters parameter) {
if (parameter != null) {
setTextureFilters(parameter.textureMinFilter, parameter.textureMagFilter);
}
Expand Down
15 changes: 5 additions & 10 deletions gdx/src/com/badlogic/gdx/maps/tiled/AtlasTmxMapLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,7 @@
*
* @author Justin Shapcott
* @author Manuel Bua */
public class AtlasTmxMapLoader extends BaseTmxMapLoader<AtlasTmxMapLoader.AtlasTiledMapLoaderParameters> {

public static class AtlasTiledMapLoaderParameters extends BaseTmxMapLoader.Parameters {
/** force texture filters? **/
public boolean forceTextureFilters = false;
}
public class AtlasTmxMapLoader extends BaseTmxMapLoader<BaseTiledMapLoader.Parameters> {

protected interface AtlasResolver extends ImageResolver {

Expand Down Expand Up @@ -107,10 +102,10 @@ public AtlasTmxMapLoader (FileHandleResolver resolver) {
}

public TiledMap load (String fileName) {
return load(fileName, new AtlasTiledMapLoaderParameters());
return load(fileName, new Parameters());
}

public TiledMap load (String fileName, AtlasTiledMapLoaderParameters parameter) {
public TiledMap load (String fileName, Parameters parameter) {
FileHandle tmxFile = resolve(fileName);

this.root = xml.parse(tmxFile);
Expand All @@ -126,15 +121,15 @@ public TiledMap load (String fileName, AtlasTiledMapLoaderParameters parameter)
}

@Override
public void loadAsync (AssetManager manager, String fileName, FileHandle tmxFile, AtlasTiledMapLoaderParameters parameter) {
public void loadAsync (AssetManager manager, String fileName, FileHandle tmxFile, Parameters parameter) {
FileHandle atlasHandle = getAtlasFileHandle(tmxFile);
this.atlasResolver = new AtlasResolver.AssetManagerAtlasResolver(manager, atlasHandle.path());

this.map = loadTiledMap(tmxFile, parameter, atlasResolver);
}

@Override
public TiledMap loadSync (AssetManager manager, String fileName, FileHandle file, AtlasTiledMapLoaderParameters parameter) {
public TiledMap loadSync (AssetManager manager, String fileName, FileHandle file, Parameters parameter) {
if (parameter != null) {
setTextureFilters(parameter.textureMinFilter, parameter.textureMagFilter);
}
Expand Down
2 changes: 2 additions & 0 deletions gdx/src/com/badlogic/gdx/maps/tiled/BaseTiledMapLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public static class Parameters extends AssetLoaderParameters<TiledMap> {
public boolean flipY = true;
/** Path to Tiled project file. Needed when using class properties. */
public String projectFilePath = null;
/** force texture filters? **/
public boolean forceTextureFilters = false;
}

/** Representation of a single Tiled class property. A property has:
Expand Down
196 changes: 196 additions & 0 deletions gdx/src/com/badlogic/gdx/maps/tiled/TiledMapLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/

package com.badlogic.gdx.maps.tiled;

import com.badlogic.gdx.assets.AssetDescriptor;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.*;

/** A universal map loader that automatically delegates to the appropriate underlying map loader {@link TmxMapLoader},
* {@link AtlasTmxMapLoader}, {@link TmjMapLoader}, or {@link AtlasTmjMapLoader} based solely on the map file's extension and
* content. A primary use case is for projects that need to load a mix of TMX and TMJ maps (with or without atlases) using a
* single loader instance inside an {@link AssetManager}. For TMX and TMJ files, this loader checks for the presence of an
* {@code "atlas"} property. If found, it uses an atlas-based loader; otherwise, it falls back to the standard loader. */
public class TiledMapLoader extends AsynchronousAssetLoader<TiledMap, BaseTiledMapLoader.Parameters> {

private final TmxMapLoader tmxMapLoader;
private final TmjMapLoader tmjMapLoader;

private final AtlasTmxMapLoader atlasTmxMapLoader;
private final XmlReader xmlReader;

private final AtlasTmjMapLoader atlasTmjMapLoader;
private final JsonReader jsonReader;

public TiledMapLoader () {
this(new InternalFileHandleResolver());
}

public TiledMapLoader (FileHandleResolver resolver) {
super(resolver);
tmxMapLoader = new TmxMapLoader(resolver);
tmjMapLoader = new TmjMapLoader(resolver);
atlasTmxMapLoader = new AtlasTmxMapLoader(resolver);
xmlReader = new XmlReader();
atlasTmjMapLoader = new AtlasTmjMapLoader(resolver);
jsonReader = new JsonReader();
}

/** Universal synchronous loader. This method is a thin wrapper that picks the correct underlying loader (TMX vs TMJ, atlas vs
* non‑atlas) and then delegates straight through to its synchronous {@code load(...)} implementation.
* @param fileName path to a .tmx or .tmj file
* @return a loaded {@link TiledMap}
* @throws GdxRuntimeException on unsupported formats or parse errors */
public TiledMap load (String fileName) {
return load(fileName, new BaseTiledMapLoader.Parameters());
}

/** Universal synchronous loader with custom parameters. Resolves the file and Inspects the extension (tmx vs tmj). Check
* whether the ‘atlas’ property exists in the map and delegates to the appropriate loader’s {@code load(...)}.
* @param fileName path to a .tmx or .tmj file
* @param parameter existing Parameters object
* @return a loaded {@link TiledMap}
* @throws GdxRuntimeException on unsupported formats or parse errors */
public TiledMap load (String fileName, BaseTiledMapLoader.Parameters parameter) {

if (parameter == null) parameter = new BaseTiledMapLoader.Parameters();
FileHandle file = resolve(fileName);
String extension = file.extension().toLowerCase();
if (extension.equals("tmx")) {
if (usesAtlas(file)) {
// atlas‑backed TMX
return atlasTmxMapLoader.load(fileName, parameter);
} else {
// plain TMX
return tmxMapLoader.load(fileName, parameter);
}
} else if (extension.equals("tmj")) {
if (usesAtlas(file)) {
// atlas‑backed TMJ
return atlasTmjMapLoader.load(fileName, parameter);
} else {
// plain TMJ
return tmjMapLoader.load(fileName, parameter);
}
} else {
// no other formats supported
throw new GdxRuntimeException("Unsupported map format: '" + extension + "' in file: " + fileName);
}
}

@Override
public Array<AssetDescriptor> getDependencies (String fileName, FileHandle file, BaseTiledMapLoader.Parameters parameter) {

if (parameter == null) parameter = new BaseTiledMapLoader.Parameters();
String extension = file.extension().toLowerCase();
if (extension.equals("tmx")) {
if (usesAtlas(file)) {
return atlasTmxMapLoader.getDependencies(fileName, file, parameter);
} else {
return tmxMapLoader.getDependencies(fileName, file, parameter);
}
} else if (extension.equals("tmj")) {
if (usesAtlas(file)) {
return atlasTmjMapLoader.getDependencies(fileName, file, parameter);
} else {
return tmjMapLoader.getDependencies(fileName, file, parameter);
}
} else {
throw new IllegalArgumentException("Unsupported map format: " + extension);
}
}

@Override
public void loadAsync (AssetManager manager, String fileName, FileHandle file, BaseTiledMapLoader.Parameters parameter) {

if (parameter == null) parameter = new BaseTiledMapLoader.Parameters();
String extension = file.extension().toLowerCase();
if (extension.equals("tmx")) {
if (usesAtlas(file)) {
atlasTmxMapLoader.loadAsync(manager, fileName, file, parameter);
} else {
tmxMapLoader.loadAsync(manager, fileName, file, parameter);
}
} else if (extension.equals("tmj")) {
if (usesAtlas(file)) {
atlasTmjMapLoader.loadAsync(manager, fileName, file, parameter);
} else {
tmjMapLoader.loadAsync(manager, fileName, file, parameter);
}

} else {
throw new IllegalArgumentException("Unsupported map format: " + extension);
}
}

@Override
public TiledMap loadSync (AssetManager manager, String fileName, FileHandle file, BaseTiledMapLoader.Parameters parameter) {
TiledMap map;
if (parameter == null) parameter = new BaseTiledMapLoader.Parameters();

String extension = file.extension().toLowerCase();
if (extension.equals("tmx")) {
if (usesAtlas(file)) {
map = atlasTmxMapLoader.loadSync(manager, fileName, file, parameter);
} else {
map = tmxMapLoader.loadSync(manager, fileName, file, parameter);
}
} else if (extension.equals("tmj")) {
if (usesAtlas(file)) {
map = atlasTmjMapLoader.loadSync(manager, fileName, file, parameter);
} else {
map = tmjMapLoader.loadSync(manager, fileName, file, parameter);
}
} else {
throw new IllegalArgumentException("Unsupported map format: " + extension);
}
return map;
}

private boolean usesAtlas (FileHandle file) {
String extension = file.extension().toLowerCase();
if (extension.equals("tmx")) {
XmlReader.Element root = xmlReader.parse(file);
XmlReader.Element properties = root.getChildByName("properties");
if (properties != null) {
for (XmlReader.Element property : properties.getChildrenByName("property")) {
String name = property.getAttribute("name", "");
if ("atlas".equals(name)) {
return true;
}
}
}
} else if (extension.equals("tmj")) {
JsonValue root = jsonReader.parse(file);
JsonValue properties = root.get("properties");
if (properties != null) {
for (JsonValue property : properties) {
String name = property.getString("name", "");
if ("atlas".equals(name)) {
return true;
}
}
}
}
return false;
}

}
Loading
0