0
\$\begingroup\$

I have built a game that uses the Slick framework. The maps are tmx files and were built using TileD. The game iterates through a list of players and maps - once a game with a player and map is completed the next game launches with a new player and map. Right now, the first time the game runs the tiles and map are displayed correctly. If I reuse the same tile files in a map (or reuse the same map) those tile files do not render - we just get a bunch of white tiles where our tiles should have loaded as seen here: white blocks. This is what it should look like: correct rendering. Note the game still works 100% correctly - the tiles just don't load. We also don't see any rendering issues if we rename the tile image files and use those in a map. Does anyone have any insight on why reusing maps/tiles would cause them not to load?

Here are portions of the code. Render code:

 public void render(GameContainer container, Graphics g)  {
        map.getMap().render(320 - (int) ((float)player.getPlayerGridLocation().getX()*16),
                240 - (int) ((float)player.getPlayerGridLocation().getY()*16));
        g.drawAnimation(player.getPlayerAnimation(), (640/2),(480/2));
    }

Launching the games:

for (int playerIndex = 0; playerIndex < players.length; playerIndex++) {
    for (int mapIndex = 0; mapIndex < maps.length; mapIndex++) {
        startMaze(maps[mapIndex], players[playerIndex]);
    }
}

Code in the startMaze function that launches a game:

DungeonMaze dm = new DungeonMaze();
container = new AppGameContainer(dm, 640, 480, false);
container.start();

Code that ends a game:

container.setForceExit(false);
container.exit();

Map code:

public class Map {
    private Point MapSize;
    private int MapBoxWidth;
    static MapBox[][] MapGrid;
    BoxType[][] Grid;
    private TiledMap map;
    private String name = "";

public void setMap(String mapName) throws SlickException {
    map = null; 
    try {
         map = new TiledMap("res/" + mapName, true);
         name = mapName;
         initMap();
     } catch (Exception e) {
         e.printStackTrace();
     }
}

public String getMapName() {
    return name;
}

private void initMap() {
     MapSize = new Point(map.getWidth(),map.getHeight());
    //System.out.print(MapSize.getX());
    //System.out.print(MapSize.getY());

    MapBoxWidth = map.getTileHeight();
    MapGrid = new MapBox[(int) MapSize.getX()][(int) MapSize.getY()];
    Grid = new BoxType[(int) MapSize.getX()][(int) MapSize.getY()];

    // Get the index #s of each layer of the TMX map file.
    // * we could probably write this as a loop to get every layer in the map
    int collisionIndex = map.getLayerIndex("collision");
    int keyIndex = map.getLayerIndex("key");
    int doorIndex = map.getLayerIndex("door");
    int endIndex = map.getLayerIndex("end");

    for(int i = 0; i < (int)MapSize.getX(); i++) {
        for(int j = 0; j < (int)MapSize.getY(); j++) {
            BoxType curType = BoxType.Open;

            int tileID = map.getTileId(i,j,collisionIndex);
            String property = map.getTileProperty(tileID, "collide", "false");
            if(property.equals("true")) {
                curType = BoxType.Blocked;
            }

            tileID = map.getTileId(i,j,keyIndex);
            property = map.getTileProperty(tileID, "keyed", "false");
            if(property.equals("true")) {
                curType = BoxType.Key;
                /*System.out.print(i);
                System.out.print("-");
                System.out.print(j);
                System.out.print("Key\n");*/
            }

            tileID = map.getTileId(i,j,doorIndex);
            property = map.getTileProperty(tileID, "doored", "false");
            if(property.equals("true")) {
                curType = BoxType.Door;
                /*System.out.print(i);
                System.out.print("-");
                System.out.print(j);
                System.out.print("Door\n"); */
            }

            tileID = map.getTileId(i,j,endIndex);
            property = map.getTileProperty(tileID, "ended", "false");
            if(property.equals("true")) {
                curType = BoxType.Exit;
                /*System.out.print(i);
                System.out.print("-");
                System.out.print(j);
                System.out.print("Exit\n");*/
            }

            Grid[i][j] = curType;
        }
    }

    for(int i = 0; i < (int)MapSize.getX(); i++) {
        for(int j = 0; j < (int)MapSize.getY(); j++) {  
            BoxType North = BoxType.Open;  
            BoxType South = BoxType.Open;  
            BoxType East = BoxType.Open;  
            BoxType West = BoxType.Open;

            if(i == 0) {West = BoxType.Blocked;}
            else {West = Grid[i-1][j];}

            if(i == (int)MapSize.getX() - 1) {East = BoxType.Blocked;}
            else {East = Grid[i+1][j]; }

            if(j == 0) {North = BoxType.Blocked;}
            else {North = Grid[i][j-1];}

            if(j == (int)MapSize.getY() - 1) {South = BoxType.Blocked;}
            else {South = Grid[i][j+1];}

            boolean consumable = false;
            if (Grid[i][j] == BoxType.Key){ consumable = true;} 

            boolean end = false;
            if (Grid[i][j] == BoxType.Exit){ end = true;} 

            MapGrid[i][j] = new MapBox(North, South, East, West, consumable, end);                
        }
    }
}

// Constructor for Map, load map from resources folder
public Map() throws SlickException {
    //map = new TiledMap("res/map02.tmx");
}

// Return the entire TMX map as a TiledMap
public TiledMap getMap() {
    return map;
}

// Return the contents of a specific MapBox space
public MapBox getMapBox(Point box) {
    return MapGrid[(int) box.getX()][(int) box.getY()];
}

// Returns the size of the overall map as X,Y coordinate
public Point getMapSize() {
    return MapSize;
}

public void pickup(Point playerLocation) { //thought key was still exsiting to south
    //MapBox Location = MapGrid[(int) playerLocation.getX()][(int) playerLocation.getY()];
    MapGrid[(int) playerLocation.getX()][(int) playerLocation.getY()].consume();

    if(playerLocation.getX() > 0) {
        MapBox WestBox = MapGrid[(int) playerLocation.getX()-1][(int) playerLocation.getY()];
        MapGrid[(int) playerLocation.getX()-1][(int) playerLocation.getY()] = new MapBox(WestBox.North, WestBox.South, BoxType.Open, WestBox.West, WestBox.hasKey(), WestBox.isEnd());
    }
    if(playerLocation.getX() < MapSize.x) {
        MapBox EastBox = MapGrid[(int) playerLocation.getX()+1][(int) playerLocation.getY()];
        MapGrid[(int) playerLocation.getX()+1][(int) playerLocation.getY()] = new MapBox(EastBox.North, EastBox.South, EastBox.East, BoxType.Open, EastBox.hasKey(), EastBox.isEnd());
    }
    if(playerLocation.getY() > 0) {
        MapBox SouthBox = MapGrid[(int) playerLocation.getX()][(int) playerLocation.getY()+1];
        MapGrid[(int) playerLocation.getX()][(int) playerLocation.getY()-1] = new MapBox(BoxType.Open, SouthBox.South, SouthBox.East, SouthBox.West, SouthBox.hasKey(), SouthBox.isEnd());
    }
    if(playerLocation.getY() < MapSize.y) {
        MapBox NorthBox = MapGrid[(int) playerLocation.getX()][(int) playerLocation.getY()-1];
        MapGrid[(int) playerLocation.getX()][(int) playerLocation.getY()+1] = new MapBox(NorthBox.North, BoxType.Open, NorthBox.East, NorthBox.West, NorthBox.hasKey(), NorthBox.isEnd());
    }


    int tilesIndex = map.getLayerIndex("tiles");

    int keyIndex = map.getLayerIndex("key");
    int tileID = map.getTileId((int) playerLocation.getX(),(int) playerLocation.getY(),tilesIndex);
    map.setTileId((int) playerLocation.getX(), (int) playerLocation.getY(), keyIndex, tileID);
}

public boolean unlockDoor(Point playerLocation) {
    MapBox Location = MapGrid[(int) playerLocation.getX()][(int) playerLocation.getY()];
    Point DoorLocation = new Point();

    //check for each direction for a door
    if(Location.North == BoxType.Door) {
        DoorLocation.x = (int) playerLocation.getX();
        DoorLocation.y = (int) playerLocation.getY()-1;
    }
    else if(Location.South == BoxType.Door) {
        DoorLocation.x = (int) playerLocation.getX();
        DoorLocation.y = (int) playerLocation.getY()+1;
    }
    else if(Location.East == BoxType.Door) {
        DoorLocation.x = (int) playerLocation.getX()+1;
        DoorLocation.y = (int) playerLocation.getY();            
    }
    else if (Location.West == BoxType.Door) {
        DoorLocation.x = (int) playerLocation.getX()-1;
        DoorLocation.y = (int) playerLocation.getY();
    }
    else { //no door, return false
        //System.out.print("unlock failed\n");
        return false; 
    }

    //MapBox Door = MapGrid[DoorLocation.x][DoorLocation.y];

    //MapGrid[(int) playerLocation.getX()][(int) playerLocation.getY()].consume();

    if(DoorLocation.getX() > 0) {
        MapBox WestBox = MapGrid[(int) DoorLocation.getX()-1][(int) DoorLocation.getY()];
        MapGrid[(int) DoorLocation.getX()-1][(int) DoorLocation.getY()] = new MapBox(WestBox.North, WestBox.South, BoxType.Open, WestBox.West, WestBox.hasKey(), WestBox.isEnd());
    }
    if(DoorLocation.getX() < MapSize.x) {
        MapBox EastBox = MapGrid[(int) DoorLocation.getX()+1][(int) DoorLocation.getY()];
        MapGrid[(int) DoorLocation.getX()+1][(int) DoorLocation.getY()] = new MapBox(EastBox.North, EastBox.South, EastBox.East, BoxType.Open, EastBox.hasKey(), EastBox.isEnd());
    }
    if(DoorLocation.getY() < MapSize.y) {
        MapBox SouthBox = MapGrid[(int) DoorLocation.getX()][(int) DoorLocation.getY()+1];
        MapGrid[(int) DoorLocation.getX()][(int) DoorLocation.getY()+1] = new MapBox(BoxType.Open, SouthBox.South, SouthBox.East, SouthBox.West, SouthBox.hasKey(), SouthBox.isEnd());    
    }
    if(DoorLocation.getY() > 0) {
        MapBox NorthBox = MapGrid[(int) DoorLocation.getX()][(int) DoorLocation.getY()-1];
        MapGrid[(int) DoorLocation.getX()][(int) DoorLocation.getY()-1] = new MapBox(NorthBox.North, BoxType.Open, NorthBox.East, NorthBox.West, NorthBox.hasKey(), NorthBox.isEnd());
    }

    //System.out.print("unlocked\n");

    int tilesIndex = map.getLayerIndex("tiles");

    int doorIndex = map.getLayerIndex("door");
    int tileID = map.getTileId((int) DoorLocation.getX(),(int) DoorLocation.getY(),tilesIndex);
    map.setTileId((int) DoorLocation.getX(), (int) DoorLocation.getY(), doorIndex, tileID);
    return true;
}

// Return the size of the MapBox
public int getMapBoxWidth() {
    return MapBoxWidth;
}

}

\$\endgroup\$
5
  • \$\begingroup\$ Hmm that is strange... So if you load the map for the first time it displays the tiles? Does this work for all of the maps? I.e use map2 as the initial starting map? Or is it only if you try to change the map at runtime? \$\endgroup\$
    – Savlon
    Jan 24, 2013 at 3:05
  • \$\begingroup\$ The first time we load any map the tiles are displayed (if the tiles have not been used previously in another map). So if map02 was loaded first it displays correctly and if map02 (or any other map) is loaded again in the same game session using the same tile files we get the white blocks issue. However, if we load map03 using the same tile files as map02 (but renamed) it loads correctly. \$\endgroup\$ Jan 24, 2013 at 16:54
  • \$\begingroup\$ Ok, well let me get home from work and ill try to replicate your problem and see if we can fix this issue \$\endgroup\$
    – Savlon
    Jan 24, 2013 at 21:11
  • 1
    \$\begingroup\$ Ok so I have been fiddling around with slick tiled maps and I cant seem to replicate your problem. Everything works fine for me, I have no problem changing tiled maps at runtime and I am using the exact same tile set for both maps. If you want I can paste my example code for you to check out? If not then I'm guessing you will have to start debugging your code because I dont think I will be able to help you. Well I could but that would be doing your dirty work lol... Can you please post your render method for me to see? thanks \$\endgroup\$
    – Savlon
    Jan 25, 2013 at 6:20
  • \$\begingroup\$ Thanks for looking into this Savlon - really appreciate it! I've added the render code above in my main post. If you don't mind, please post your example code so I can do some comparisons between the two. \$\endgroup\$ Jan 25, 2013 at 14:41

2 Answers 2

1
\$\begingroup\$

Ok so lets get to it!

Paste the code where you call your first map to initialise. Do you use the setMap() method to initialise your first map? or do you have map = new TiledMap("blah");??

If you can't figure out the problem with my example code then you might have to paste your code on pastebin and let me thoroughly read and test it.

Here is my example of loading a TiledMap and changing maps at runtime using key's 1 & 2. Here is also a link to my youtube channel where i have posted a short video for you to see this in action :) TiledMap: Change at runtime test

package test;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.TiledMap;

public class Game extends BasicGame {

public TiledMap map;

public Game() {
    super("TileMap Test");
}

public void setMap(String mapName) throws SlickException {
    map = null;
    map = new TiledMap("res/" + mapName + ".tmx");
}

@Override
public void init(GameContainer gc) throws SlickException {
    setMap("tilemaptest");
}

@Override
public void update(GameContainer gc, int delta) throws SlickException {
    Input input = gc.getInput();

    if (input.isKeyPressed(Input.KEY_1)) {
        setMap("tilemaptest");
    }

    if (input.isKeyPressed(Input.KEY_2)) {
        setMap("tilemaptest2");
    }
}

@Override
public void render(GameContainer gc, Graphics g) throws SlickException {
    map.render(0, 0);
}

public static void main(String[] args) throws SlickException {
    AppGameContainer app = new AppGameContainer(new Game());
    app.setDisplayMode(640, 480, false);
    app.setTargetFrameRate(60);
    app.start();
}

}

Let me know how you go :)

\$\endgroup\$
0
\$\begingroup\$

Ended up figuring out what the issue was after running Savlon's example above. The issue was with how I was restarting the game. I was starting and stopping the AppGameContainer i n a separate file which was causing some sort of issue with the rendering in subsequent runs. After rewriting the code, I changed it so that in the update function of my BasicGame class when a game completes the GameContainer reinitializes (reinit()). That ended up solving the weird rendering issue.

Thanks for your help Savlon - you example ended up pointing me in the right direction!

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .