I am working on a small project using Java and Swing. I'm making a very, very small and simple RPG that is in the style of Earthbound for mainly it's combat style. Alongside this project, I'm working on a framework to make it easier to create games of a similar genre and feel (i.e. screen, game loop, state manager, audio manager, etc). The issue I'm running into is that the "image to game object" converter class I made is overwriting the list with the final game object that is created. I am converting from a PNG to a GameObject (class created within the framework).
I diagnosed this by printing out the position and type of all the elements in the list to receive the same X, Y, and types for each element. I checked to make sure the HashMap I passed through was setup correctly and that each tile type was added correctly. Below is the relevant section of code to the top along with it's output:
private void init() {
tileMap.put(new Color(0,255,0), new Tile(16,16, TileType.GRASS));
tileMap.put(new Color(250,255,0), new Tile(16,16, TileType.SAND));
tileMap.put(new Color(135,135,135), new Tile(16,16, TileType.ROCK));
tileMap.put(new Color(255,0,233), new Tile(16,16, TileType.DIRT_PATH_SIDE));
for(Color t : tileMap.keySet()) {
System.out.println(((Tile) tileMap.get(t)).getTileType());
}
....
}
----- OUTPUT -----
GRASS
ROCK
DIRT_PATH_SIDE
SAND
The image loads correctly and the HashMap's values are added correctly so I decided to see where in the framework the issue was. I checked the position when it was being set and it was fine (ie (0,0), (0,16), (0,32)...) until I looped through the finished list where the game objects in the list are all the same.
I know that static variables cause an issue but the only "static" variable I am using is the enums to denote what the tile type is. I used an integer just to see what would happened and yielded the same result. I took the final list, made it a variable the class could read as opposed to just the function, and tried to see if that would work but still was just the final game object created after reading.
I've checked over SO and other websites but nothing is working. I fear that I looked at this problem the wrong way as I was trying to implement a solution I used in Unity/C# here but probably had a disconnect somewhere along the way.
Here is the full function from earlier:
private void init() {
tileMap.put(new Color(0,255,0), new Tile(16,16, TileType.GRASS));
tileMap.put(new Color(250,255,0), new Tile(16,16, TileType.SAND));
tileMap.put(new Color(135,135,135), new Tile(16,16, TileType.ROCK));
tileMap.put(new Color(255,0,233), new Tile(16,16, TileType.DIRT_PATH_SIDE));
for(Color t : tileMap.keySet()) {
System.out.println(((Tile) tileMap.get(t)).getTileType());
}
try {
im.loadImage();
} catch (IOException e) {
e.printStackTrace();
}
im.readImage(tileMap);
objects = im.getMap(); // objects is a list within the class that contains all Tile game objects.
}
And the converter class's relevant code:
public void readImage(HashMap<Color, GameObject> tileDict) {
for(int x=0; x<img.getWidth(); x++) {
for(int y=0; y<img.getHeight(); y++) {
GameObject g = determineObject(tileDict, x, y);
if(g != null) {
map.add(g);
}
}
}
}
private GameObject determineObject(HashMap<Color, GameObject> tileDict,
int x, int y) {
GameObject g = null;
for(Color c : tileDict.keySet()) {
if(c.getRGB() == img.getRGB(x, y)) {
g = tileDict.get(c);
g.setXPos(x*g.getWidth());
g.setYPos(y*g.getHeight());
}
}
return g;
}
--- EDIT: 8/10/2017 ---
I am sorry for not clarifying what the structure looks like. GameObject is an abstract class within the framework I've made that is extended by Tile in the game. As well, TileType is an enum type that I created within the game and not the framework. The framework is in a separate jar/project so it is unaware of what extends GameObject and what TileType is.
--- EDIT 2: 8/10/2017 ---
I tried implementing a solution using the Serializable
class but that didn't work. I followed the example from this question. The copy() function I created in the abstract GameObject
looks like this:
public final GameObject copy() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos).writeObject(this);
return (GameObject) new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())).readObject();
} catch (Exception e) {
throw new AssertionError();
}
}
I have also tried this as an abstract method and wrote the function in Tile
but there is no current result. I'll keep mucking around here to see if anything comes up.
Resources