External Publication
Visit Post

jME 3.10.0-alpha4

jMonkeyEngine Hub May 7, 2026
Source

https://drive.google.com/drive/folders/1mnwaMuswKaG4m853MOhAhKX7jg30mcsW?usp=sharing

This is a main, where every frame I update get x y z of player and show tiles if needed. When I need new tiles, I will assign the correct image to the tile.

The images I use are 16 grey scale, so have only one channel.

package com.worldgame;

import Terrain.TileManager;
import Terrain.TileMeshBuilder;
import Terrain.location.Position3D;
import Terrain.utils.Tile;
import Terrain.utils.TileID;
import com.config.AppSettingsConfig;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.system.AppSettings;
import com.jme3.texture.Texture;

import java.util.HashMap;
import java.util.Set;

public class WorldGame extends SimpleApplication {
private TileManager terrainDataManager;
private final HashMap<TileID, Geometry> renderedTiles = new HashMap<>();
private final HashMap<String, Texture> textureCache = new HashMap<>();
public static void main(String
 args) {
WorldGame app = new WorldGame();
AppSettings settings = AppSettingsConfig.getInstance().getSettings();
app.setSettings(settings);
app.start();
}

@Override
public void simpleInitApp() {assetManager.registerLocator(
        "C:\\software\\eclipse_workspace\\WorldGame\\src\\main\\resources\\heightData",
        com.jme3.asset.plugins.FileLocator.class
);

    cam.setLocation(new Vector3f(0, 1f, 0f));
    Vector3f playerPos = cam.getLocation();
    cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
    cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.00001f, 1000f);
    float[] earthCenter = new float[]{0f, 0f, 0f};
    viewPort.setBackgroundColor(ColorRGBA.White); // Purple/indigo nyan color
    terrainDataManager = new TileManager(
            new Position3D(playerPos.x, playerPos.y, playerPos.z),
            new Position3D(earthCenter[0], earthCenter[1], earthCenter[2])
    );
    Set<Tile> tiles = terrainDataManager.getTilesToRender();
    for (Tile t : tiles) {
            addTile(t);
    }
    flyCam.setMoveSpeed(0.01f);

    System.out.println("=== Scene Tree ===");
    printSceneTree(rootNode, 0);
}

@Override
public void simpleUpdate(float tpf) {
    Vector3f playerPos = cam.getLocation();
    boolean playerChangedTile = terrainDataManager.setPlayerTile(
            new Position3D(playerPos.x, playerPos.y, playerPos.z));
    // First frame: same tile as constructor → setPlayerTile false; still need to attach meshes.
    if (playerChangedTile) {
        Set<Tile> tiles = terrainDataManager.getTilesToRender();

    for (Tile t : tiles) {
        if (!renderedTiles.containsKey(t.getTileId())) {
            addTile(t);
        }
    }

    renderedTiles.entrySet().removeIf(entry -> {
        boolean stillVisible = tiles.stream().anyMatch(t -> t.getTileId() == entry.getKey());
        if (!stillVisible) {
            entry.getValue().removeFromParent();
        }
        return !stillVisible;
    });
    }
}

private void addTile(Tile t) {
    Mesh m = TileMeshBuilder.getInstance().buildMeshFromTile(t.getBuffer());
    Geometry g = new Geometry("tile_" + t.hashCode(), m);

    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    TileID id = t.getTileId();
    Texture tex = getTexture(id);
    mat.setTexture("ColorMap", tex);
    mat.getAdditionalRenderState().setWireframe(false);
    mat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
    g.setMaterial(mat);

    rootNode.attachChild(g);
    renderedTiles.put(t.getTileId(), g);
}

private void printSceneTree(com.jme3.scene.Spatial node, int depth) {
    String indent = "  ".repeat(depth);
    System.out.println(indent + node.getName() + " (" + node.getClass().getSimpleName() + ")");
    if (node instanceof com.jme3.scene.Node n) {
        for (com.jme3.scene.Spatial child : n.getChildren()) {
            printSceneTree(child, depth + 1);
        }
    }
}private Texture getTexture(TileID id) {
    String path = id.face() + "/" + id.row() + "_" + id.col() + ".png";
    return textureCache.computeIfAbsent(path, p -> assetManager.loadTexture(p));
}
}

Discussion in the ATmosphere

Loading comments...