Skip to content

Commit

Permalink
[M]Seperate tiled image into an new class
Browse files Browse the repository at this point in the history
  • Loading branch information
闫茂源 committed Apr 11, 2024
1 parent f91277b commit 003d464
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 145 deletions.
141 changes: 65 additions & 76 deletions src/main/java/com/jme3/tmx/TmxLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
import com.jme3.tmx.animation.Frame;
import com.jme3.tmx.core.*;
import com.jme3.tmx.enums.*;
import com.jme3.tmx.math2d.Point;
import com.jme3.tmx.render.shape.TileMesh;
import com.jme3.tmx.util.ColorUtil;
import com.jme3.tmx.util.TileCutter;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.w3c.dom.Document;
Expand Down Expand Up @@ -73,6 +75,7 @@ public class TmxLoader implements AssetLoader {
public static final String CLASS = "class";
public static final String COLOR = "color";
public static final String TILESET = "tileset";
public static final String GID = "gid";
public static final String TILE = "tile";
public static final String SOURCE = "source";
public static final String IMAGE = "image";
Expand All @@ -84,6 +87,7 @@ public class TmxLoader implements AssetLoader {
public static final String OBJECTGROUP = "objectgroup";
public static final String OBJECT = "object";
public static final String PROPERTIES = "properties";
public static final String _TEXT = "#text";
public static final String PROPERTY = "property";
public static final String POINT = "point";
public static final String POLYLINE = "polyline";
Expand Down Expand Up @@ -406,7 +410,7 @@ private void readMap(Document doc) throws IOException {
break;
}
default: {
if (TILESET.equals(childName) || PROPERTIES.equals(childName) || "#text".equals(childName)) {
if (TILESET.equals(childName) || PROPERTIES.equals(childName) || _TEXT.equals(childName)) {
// Ignore, already processed
} else {
logger.warn("Unsupported map element: {}", childName);
Expand Down Expand Up @@ -478,6 +482,7 @@ private Tileset readTileset(Node node) {
}

boolean hasTilesetImage = false;
TiledImage image = null;
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
Expand All @@ -489,16 +494,16 @@ private Tileset readTileset(Node node) {
continue;
}

AnImage image = readImage(child);
if (image.texture != null) {
image = readImage(child);
if (image.getTexture() != null) {
// Not a shared image, but an entire set in one image
// file. There should be only one image element in this
// case.
hasTilesetImage = true;

set.setImageSource(image.source);
set.setTexture(image.texture);
set.setMaterial(image.createMaterial());
set.setImageSource(image.getSource());
set.setTexture(image.getTexture());
set.setMaterial(image.getMaterial());
}
} else if ("grid".equals(nodeName)) {
/*
Expand Down Expand Up @@ -554,10 +559,17 @@ private Tileset readTileset(Node node) {
}

if (hasTilesetImage) {
// add tileoffset to the material

TileCutter cutter = new TileCutter(image.getWidth(), image.getHeight(), tileWidth, tileHeight, tileMargin, tileSpacing);

Tile tile = cutter.getNextTile();
while (tile != null) {
set.addNewTile(tile);
tile = cutter.getNextTile();
}

Material mat = set.getMaterial();
Vector2f tileOffset = new Vector2f(set.getTileOffsetX(), set.getTileOffsetY());
mat.setVector2("TileOffset", tileOffset);
mat.setBoolean("UseTilesetImage", true);
}
}

Expand Down Expand Up @@ -593,14 +605,8 @@ private void createVisual(Tileset tileset) {
sharedMat = tileset.getMaterial();
}

int offsetX = 0;
int offsetY = 0;

// if the tileset tilesize is larger than the map tilesize, adjust the offset
int diffY = tileset.getTileHeight() - map.getTileHeight();
if (diffY > 0) {
offsetY = - diffY;
}
Point offset = new Point(tileset.getTileOffsetX(), tileset.getTileOffsetY());
Point origin = new Point(0, map.getTileHeight());

List<Tile> tiles = tileset.getTiles();
int len = tiles.size();
Expand All @@ -614,11 +620,6 @@ private void createVisual(Tileset tileset) {
* material.
*/
boolean useSharedImage = tile.getTexture() == null;
if (!useSharedImage && tile.getMaterial() == null) {
// this shouldn't happen, just in case someone uses Tiles created by code.
logger.warn("The tile mush has a material if it don't use sharedImage: {}", name);
continue;
}

int x = tile.getX();
int y = tile.getY();
Expand All @@ -635,7 +636,7 @@ private void createVisual(Tileset tileset) {
imageHeight = tile.getTexture().getImage().getHeight();
}

TileMesh mesh = new TileMesh(x, y, width, height, imageWidth, imageHeight, offsetY);
TileMesh mesh = new TileMesh(x, y, width, height, imageWidth, imageHeight, offset, origin);

Geometry geometry = new Geometry(name, mesh);
geometry.setQueueBucket(Bucket.Gui);
Expand Down Expand Up @@ -792,9 +793,9 @@ private void readTile(Tileset set, Node t) {
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (IMAGE.equals(child.getNodeName())) {
AnImage image = readImage(child);
tile.setTexture(image.texture);
tile.setMaterial(image.createMaterial());
TiledImage image = readImage(child);
tile.setTexture(image.getTexture());
tile.setMaterial(image.getMaterial());
} else if ("animation".equalsIgnoreCase(child.getNodeName())) {
Animation animation = new Animation(null);
NodeList frames = child.getChildNodes();
Expand Down Expand Up @@ -822,17 +823,19 @@ private void readTile(Tileset set, Node t) {
* @return
* @throws IOException
*/
private AnImage readImage(Node t) {

AnImage image = new AnImage();

private TiledImage readImage(Node t) {
String source = getAttributeValue(t, SOURCE);
String trans = getAttributeValue(t, "trans");
String format = getAttributeValue(t, "format");// useless for jme3
int width = getAttribute(t, WIDTH, 0);
int height = getAttribute(t, HEIGHT, 0);

Texture2D texture = null;
// load a image from file or decode from the CDATA.
if (source != null) {
String assetPath = toJmeAssetPath(key.getFolder() + source);
image.source = assetPath;
image.texture = loadTexture2D(assetPath);
source = assetPath;
texture = loadTexture2D(assetPath);
} else {
NodeList nl = t.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Expand All @@ -843,21 +846,34 @@ private AnImage readImage(Node t) {
String sdata = cdata.getNodeValue();
byte[] imageData = Base64.getDecoder().decode(sdata.trim());

image.texture = loadTexture2D(imageData);
texture = loadTexture2D(imageData);
}
break;
}
}
}

image.trans = getAttributeValue(t, "trans");
// useless for jme3
image.format = getAttributeValue(t, "format");
image.width = getAttribute(t, WIDTH, 0);
image.height = getAttribute(t, HEIGHT, 0);
if (texture != null && (width == 0 || height == 0)) {
logger.warn("Image size is not specified, using the texture size.");
width = texture.getImage().getWidth();
height = texture.getImage().getHeight();
}

return image;
TiledImage image = new TiledImage(source, trans, format, width, height);
image.setTexture(texture);

// create material
Material mat = new Material(assetManager, "com/jme3/tmx/resources/Tiled.j3md");
mat.setTexture("ColorMap", texture);
if (trans != null) {
ColorRGBA transparentColor = ColorUtil.toColorRGBA(trans);
mat.setColor("TransColor", transparentColor);
}
Vector2f imageSize = new Vector2f(width, height);
mat.setVector2("ImageSize", imageSize);
image.setMaterial(mat);

return image;
}

/**
Expand Down Expand Up @@ -1149,11 +1165,11 @@ private Layer readImageLayer(Node node) {
String nodeName = child.getNodeName();
if (nodeName.equalsIgnoreCase(IMAGE)) {

AnImage image = readImage(child);
if (image.texture != null) {
layer.setSource(image.source);
layer.setTexture(image.texture);
layer.setMaterial(image.createMaterial());
TiledImage image = readImage(child);
if (image.getTexture() != null) {
layer.setSource(image.getSource());
layer.setTexture(image.getTexture());
layer.setMaterial(image.getMaterial());

hasImage = true;
break;
Expand Down Expand Up @@ -1297,14 +1313,14 @@ private MapObject readObjectNode(Node node) {
}
case IMAGE: {
obj.setShape(ObjectType.IMAGE);
AnImage image = readImage(child);
obj.setImageSource(image.source);
obj.setTexture(image.texture);
obj.setMaterial(image.createMaterial());
TiledImage image = readImage(child);
obj.setImageSource(image.getSource());
obj.setTexture(image.getTexture());
obj.setMaterial(image.getMaterial());
break;
}
default: {
if ("#text".equals(nodeName)) {
if (PROPERTIES.equals(nodeName) || _TEXT.equals(nodeName)) {
// ignore
} else {
logger.warn("unknown object type:{}", nodeName);
Expand Down Expand Up @@ -1646,31 +1662,4 @@ private String toJmeAssetPath(final String src) {
}
}

/**
* When read a &lt;image&gt; element there 5 attribute there. This class is
* just a data struct to return the whole image node;
*
* @author yanmaoyuan
*/
private class AnImage {
String source;
String trans;
// useless for jme3
String format;
int width;
int height;

Texture2D texture = null;

private Material createMaterial() {
Material mat = new Material(assetManager, "com/jme3/tmx/resources/Tiled.j3md");
mat.setTexture("ColorMap", texture);
if (trans != null) {
ColorRGBA transparentColor = ColorUtil.toColorRGBA(trans);
mat.setColor("TransColor", transparentColor);
}
return mat;
}
}

}
65 changes: 65 additions & 0 deletions src/main/java/com/jme3/tmx/core/TiledImage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.jme3.tmx.core;

import com.jme3.material.Material;
import com.jme3.texture.Texture2D;

/**
* When read a &lt;image&gt; element there 5 attribute there. This class is just a data struct to return the whole image node.
*
* @author yanmaoyuan
*/
public class TiledImage {
private final String source;
private final String trans;
// useless for jme3
private final String format;
private final int width;
private final int height;

private Texture2D texture;
private Material material;

public TiledImage(String source, String trans, String format, int width, int height) {
this.source = source;
this.trans = trans;
this.format = format;
this.width = width;
this.height = height;
}

public String getSource() {
return source;
}

public String getTrans() {
return trans;
}

public String getFormat() {
return format;
}

public int getWidth() {
return width;
}

public int getHeight() {
return height;
}

public Texture2D getTexture() {
return texture;
}

public void setTexture(Texture2D texture) {
this.texture = texture;
}

public Material getMaterial() {
return material;
}

public void setMaterial(Material material) {
this.material = material;
}
}
9 changes: 0 additions & 9 deletions src/main/java/com/jme3/tmx/core/Tileset.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import com.jme3.tmx.enums.ObjectAlignment;
import com.jme3.tmx.enums.Orientation;
import com.jme3.tmx.enums.TileRenderSize;
import com.jme3.tmx.util.TileCutter;

/**
* If there are multiple &lt;tileset&gt; elements, they are in ascending order of
Expand Down Expand Up @@ -269,14 +268,6 @@ public Texture getTexture() {
*/
public void setTexture(Texture texture) {
this.texture = texture;

TileCutter cutter = new TileCutter(texture, tileWidth, tileHeight, tileMargin, tileSpacing);

Tile tile = cutter.getNextTile();
while (tile != null) {
addNewTile(tile);
tile = cutter.getNextTile();
}
}

public Material getMaterial() {
Expand Down
11 changes: 5 additions & 6 deletions src/main/java/com/jme3/tmx/render/ObjectRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.jme3.tmx.core.*;
import com.jme3.tmx.enums.FillMode;
import com.jme3.tmx.enums.Orientation;
import com.jme3.tmx.math2d.Point;
import com.jme3.tmx.render.shape.*;
import com.jme3.tmx.util.ObjectMesh;
import org.slf4j.Logger;
Expand Down Expand Up @@ -226,19 +227,17 @@ private void tile(MapObject obj) {

float th = tile.getHeight();
float tw = tile.getWidth();
float offsetX = tile.getTileset().getTileOffsetX();
float offsetY = tile.getTileset().getTileOffsetY();

// When the object has a gid set, then it is represented by
// the image of the tile with that global ID. The image
// alignment currently depends on the map orientation.

// In orthogonal, it's aligned to the bottom-left
float[] vertices = new float[]{
offsetX, 0, offsetY,
offsetX+tw, 0, offsetY,
offsetX+tw, 0, offsetY-th,
offsetX, 0, offsetY-th};
0, 0, -th,
tw, 0, -th,
tw, 0, 0,
0, 0, 0};

// In isometric, it's aligned to the bottom-center.
if (map.getOrientation() == Orientation.ISOMETRIC) {
Expand Down
Loading

0 comments on commit 003d464

Please sign in to comment.