Search code examples
javaandroidandenginetmx

AndEngine change TMX Tiled Map Dynamically


I have read all the possible duplicates of this question and none gives me a full solution (the solution is in divided into the answers) so I decided to try and clear the things up. BTW StackOverflow told me:

Not the answer you're looking for? Browse other questions tagged android andengine tmx or ask your own question.

and

It's OK to Ask and Answer Your Own Questions
So [...] if you'd like to document it in public so others (including yourself) can find it later

Now this being clear, I would like to change a TMX map dynamically. For example the map has a chest object. The player walks on it and receives gold. Then I would like to remove the chest from the map so the player cannot collect the chest more than once. How do I do this?


Solution

  • Removing the chest from the map so it can no longer be collected is possible, but not by editing the TMX Map. To accomplish this, whenever the player walks over a chest (check by adding a property to the chest like chest=true and then checking it), besides rewarding the player, you must do something, and that is saving using Shared Preferences which chests have been used using a String Set (eg. with the key "chests") and containing the coordinates, separated by ":". To save the coordinates:

    String saveMe = tileRow + ":" + tileColumn;
    removeChest(tileRow, tileColumn);
    

    To load the coordinates:

    String loaded = loadString();
    String[] coords = loades.split(":");
    tileRow = Integer.parseInt(coords[0]);
    tileColumn = Integer.parseInt(coords[1]);
    removeChest(tileRow, tileColumn);
    

    Now you can save / load used chests. This is whenever the player walks over a tile which has (chest=true) property:

    boolean found = false;
    for (int i = 0; i < chestsUsedTileRowsArray.length; i++) {
        if (chestFoundTileRow == chestsUsedTileRowsArray[i] && chestFoundTileColumn == chestsUsedTileColumnsArray[i]) {
            found = true;
            break;
        }
    }
    if (!found) {
        rewardPlayer();
        saveChestUsed(tileRow, tileColumn);
    }
    

    Finally, there is removeChest() which requires a little trick: drawing a sprite which has the texture of the ground on the chest:

    void removeChest(int tileRow, int tileColumn) {
        final TMXTile tileToReplace = tmxMap.getTMXLayers().get(0).getTMXTile(tileColumn, tileRow);
        final int w = tileToReplace.getTileWidth();
        final int h = tileToReplace.getTileHeight();
        Sprite sprite = new Sprite(w * (tileColumn + 0.5), h * (tileRow + 0.5), textureRegionOfGround, this.getVertexBufferObjectManager());
        scene.addChild(sprite);
    }