Skip to content

Releases: jmecn/TMXLoader

v0.6.0

28 Apr 10:18
Compare
Choose a tag to compare

https://youtu.be/71XVkOdeYqc

  • The “visual” object is separate from TiledMap, Layers, Tiles and MapObject. You can’t use tile.getVisual(), instead use mapRenderer.getSpriteFactory().newTileSprite(Tile).
  • Add a demo to show how it works.
  • Tons of changes.
    Full Changelog: v0.5.0...v0.6.0

v0.5.0

17 Apr 16:00
Compare
Choose a tag to compare
  • support parallax scroll factor
  • support z-standard compressed data
  • Rewrite a desktop application to show how to use the latest features.

https://youtu.be/0OIIdxaAZjA

Full Changelog: v0.4.0...v0.5.0

v0.4.0

15 Apr 10:10
Compare
Choose a tag to compare

Full Changelog: v0.3.1...v0.4.0

v0.3.1

11 Apr 05:37
Compare
Choose a tag to compare

Full Changelog: v0.3.0...v0.3.1

v0.3.0

09 Apr 07:09
Compare
Choose a tag to compare
  • Support ImageLayer
  • Support GroupLayer
  • Support Tile as Object
  • Support Tinting Color
  • Fixed Object transform in Isometric map
  • Add Test Grid mesh

Full Changelog: v0.2...v0.3.0

TMXLoader v0.2

15 Dec 10:57
Compare
Choose a tag to compare
TMXLoader v0.2 Pre-release
Pre-release

Changelog

  • Use Bucket.GUI instead of Bucket.Transparent, change whole scene from XOZ plane to XOY plane now.
  • Removed RPGCameraState, use only TiledMapAppState now.
  • Fixed issue #1 and #2: Removed BatchNode, use simple Node instead.
  • Fixed issue #3: Now tiles with flip mask can display correctly.
  • Add new feature for animated tiles.

animatedtile

TODO

  • Fixed issue #4
  • Add interface to let control tiles and objects in the scene.

How to use:

package net.jmecn.tmx;

import com.jme3.app.SimpleApplication;
import com.jme3.tmx.TiledMapAppState;
import com.jme3.tmx.TmxLoader;
import com.jme3.tmx.core.TiledMap;

/**
 * Test loading tmx assets with TmxLoader.
 * @author yanmaoyuan
 *
 */
public class TmxLoaderExample extends SimpleApplication {

    @Override
    public void simpleInitApp() {
        // register it
        assetManager.registerLoader(TmxLoader.class, "tmx", "tsx");

        // load tmx with it
        TiledMap map = (TiledMap) assetManager.loadAsset("Models/Examples/Desert/desert.tmx");
        assert map != null;

        // render it with TiledMapAppState
        stateManager.attach(new TiledMapAppState());

        TiledMapAppState tiledMap = stateManager.getState(TiledMapAppState.class);
        tiledMap.setMap(map);
    }

    public static void main(String[] args) {
        TmxLoaderExample app = new TmxLoaderExample();
        app.start();
    }

}

TMXLoader v0.1 alpha

02 Dec 20:35
Compare
Choose a tag to compare
TMXLoader v0.1 alpha Pre-release
Pre-release

Introduction

TMXLoader is used for loading .tmx assets created by Tiled Map Editor. It's a plugin for jMonkeyEngine 3.1.

default

How to use

  • First of all, register it to assetManager.
  • Then load a tmx asset with assetManager, you will get a TileMap object.
  • Render it or do anything you want to it.

Example:

package net.jmecn.tmx;

import com.jme3.app.SimpleApplication;
import com.jme3.math.Vector3f;
import com.jme3.tmx.RPGCamAppState;
import com.jme3.tmx.TiledMapAppState;
import com.jme3.tmx.TmxLoader;
import com.jme3.tmx.core.TiledMap;

/**
 * An example to let you know how to use TMXLoader
 * 
 * @author yanmaoyuan
 *
 */
public class TiledMapExample extends SimpleApplication {

    @Override
    public void simpleInitApp() {
        // register it to assetManager.
        assetManager.registerLoader(TmxLoader.class, "tmx", "tsx");

        // load an asset with it.
        TiledMap map = (TiledMap) assetManager.loadAsset("Models/Examples/Orthogonal/01.tmx");

        // render it
        TiledMapAppState tiledAppState = new TiledMapAppState(map);
        stateManager.attach(tiledAppState);

        // setup an parallel cam for it
        int viewColumns = 24;
        RPGCamAppState rpcamAppState = new RPGCamAppState(viewColumns);
        rpcamAppState.setTileWidth(map.getTileWidth());
        stateManager.attach(rpcamAppState);

        // may be you want to look at the center of this map?
        Vector3f loc = tiledAppState.getLocation(map.getWidth()/2, map.getHeight()/2);
        cam.setLocation(loc);
    }

    public static void main(String[] args) {
        TiledMapExample app = new TiledMapExample();
        app.start();
    }

}

The MapRenderer

If you don't want to make an renderer your self, I have created some MapRenderers for easy use.

  • com.jme3.tmx.render.MapRenderer;
  • com.jme3.tmx.render.HexagonalRenderer;
  • com.jme3.tmx.render.IsometricRenderer;
  • com.jme3.tmx.render.OrthogonalRenderer;
  • com.jme3.tmx.render.StaggeredRenderer;

As there are 3 kind of layers in a TiledMap:

  • TileLayer
  • ObjectGroup
  • ImageLayer

The MapRenderers provides 3 methods to make spatials for each layer.

public Spatial render(TileLayer layer);
public Spatial render(ObjectLayer layer);
public Spatial render(ImageLayer layer);

Here it an example I wrote earlier.

public void render(TiledMap map) {
    this.map = map;

    switch (map.getOrientation()) {
    case ORTHOGONAL:
        mapRender = new OrthogonalRenderer(map);
        break;
    case ISOMETRIC:
        mapRender = new IsometricRenderer(map);
        break;
    case HEXAGONAL:
        mapRender = new HexagonalRenderer(map);
        break;
    case STAGGERED:
        mapRender = new StaggeredRenderer(map);
        break;
    }

    mapRender.updateVisual();

    // background color
    if (map.getBackgroundColor() != null) {
        viewPort.setBackgroundColor(map.getBackgroundColor());
    } else {
        viewPort.setBackgroundColor(ColorRGBA.Black);
    }

    Node node = new Node("Tiled Map");
    int len = map.getLayerCount();

    int layerCnt = 0;

    for (int i = 0; i < len; i++) {
        Layer layer = map.getLayer(i);

        // skip invisible layer
        if (!layer.isVisible()) {
            continue;
        }

        Spatial visual = null;
        if (layer instanceof TileLayer) {
            visual = mapRender.render((TileLayer) layer);
        }

        if (layer instanceof ObjectLayer) {
            visual = mapRender.render((ObjectLayer) layer);
        }

        if (layer instanceof ImageLayer) {
            visual = mapRender.render((ImageLayer) layer);
        }

        if (visual != null) {
            node.attachChild(visual);

            // this is a little magic to make let top layer block off the
            // bottom layer
            visual.setLocalTranslation(0, layerCnt++, 0);
        }
    }

    // make the whole map thinner
    if (layerCnt > 0) {
        node.setLocalScale(1, 1f / layerCnt, 1);
    }
    rootNode.attachChild(node);
}

The com.jme3.tmx.TiledMapAppState will help you to do all the mess.

The camera

I don't really draw 2d image in a 3d game engine, instead I create spatials and apply Material to tiles and objects. They are large quad align to XOZ plane.

default

In Tiled Qt they use XOY axis, X positive to right and Y positive to down

  O------- X
  |
  |
  |
  Y

Once in jme3 I choose XOY plane, which means I have to modify the Y for every tile and every object. Now I choose XOZ plane, it's much easier to do the math. The Point(x,y) in Tiled now converted to Vector3f(x, 0, y).

  O------- X
  |
  |
  |
  Z

Which means you need to set a parallel and make it look at XOZ plane just like this.

/**
 * Set view columns. It changes the number of tiles you can see in a row.
 * 
 * @param columns
 */
public void setViewColumn(float columns) {

    this.viewColumns = columns;

    if (cam == null) {
        return;
    }

    cam.setParallelProjection(true);
    cam.lookAtDirection(new Vector3f(0, -1, 0), new Vector3f(0, 0, -1));

    float frustumSize = viewColumns * tileWidth * 0.5f;
    float aspect = (float) cam.getHeight() / cam.getWidth();
    cam.setFrustum(-1000, 1000, -frustumSize, frustumSize, aspect
            * frustumSize, -aspect * frustumSize);
}

If you don't want to do it yourself, I create com.jme3.tmx.RPGCamAppState for my debug use. It may help you.
Using RPGCamAppState will disable the FlyCamAppState.

TODO

  • add interface to control player and monster
  • add support for animated tiles
  • handle layer offsets
  • handle fliped tile
  • fix a lot of bugs:
    • NPE when call render() before TiledMapAppState initialized.
    • object in hexangonal and isometric map located on wrong position.
    • .......