Objects changing type randomly

Hello.



My fairly popular (not really?) tile-engine is giving me trouble as I’ve been manipulating it to be better. I have made an improvement that comes with a cost.



The engine will load RAW heightmaps for whatever tile-coordinate you’re standing on IF and ONLY IF there is a map with the appropriate name (i.e. x,y.raw). If not, the loader detects the problem and places the “default map” in it’s place. This has always worked without problem. The improvement I made was to the way the tile-loader detects height on a heightmap.  Before, I was searching through an ArrayList of the children of the TerrainNode and then deciding which one I was on. Now I figure it based on the names of the nodes, so it’s much faster and the character will never fall through the earth (like it was before).



However, with this improvement, if I walk off of the “defined” world into a “defaulted” world (where there is no set map, only a default map) I get an exception–a ClassCastException. It’s saying that a TerrainBlock object can’t be cast to a Tile object (Tile is a class defined by my tile-loader, available here).



Every Tile object has a TerrainBlock attached to it (since Tile extends Node, it can hold objects), so I think that’s where it’s getting confused. The REALLY complicated thing is this: I printed out every object attached to the Node which is designed to hold all of the Tiles, and they are ALL Tile objects. THEN, when I print out (immediately afterwards) the object by calling it by it’s name, it shows up as a TerrainBlock object.



Does anybody have any clue as to why this is happening?

Whats your code for printing the info?

I print all objects attached to the TerrainNode like this:

System.out.println(terrainNode.getChildren());



I print the specific object like this:

System.out.println(terrainNode.getChild(x + "," + y);





    public Spatial getChild(String name) {
        if (name == null) return null;
        for (int x = 0, cSize = getQuantity(); x < cSize; x++) {
            Spatial child = children.get(x);
            if (name.equals(child.getName())) {
                return child;
            } else if(child instanceof Node) {
                Spatial out = ((Node)child).getChild(name);
                if(out != null) {
                    return out;
                }
            }
        }
        return null;
    }



Might be


                Spatial out = ((Node)child).getChild(name);
                if(out != null) {
                    return out;
                }



And using getChild(String) to get the child by name isn't much faster than looping through the list from getChildren()... Might be something else that's slowing it down.

The order of the children changes during the moving, so the character will sporatically fall through the earth otherwise.



Why is it only when moving into undefined terrain? I also don't see why the code you showed above would cause it to return the incorrect type when called by name…

Trussell said:

I also don't see why the code you showed above would cause it to return the incorrect type when called by name..

That would be because you are assuming that the error is not in your own code but somewhere else. There is never an "incorrect type" returned anywhere. You just get what you asked for with getChild() (which admittedly needs a line of javadoc stating that it will descend into child nodes) - only it isn't what you expect. That's most likely because you made a mistake when creating your default Tile or adding the TerrainBlock.

Take a closer look at this line in getChild():

Spatial out = ((Node)child).getChild(name);


The Node.getChild(String name) method recursively descends into any node which isn't named name and will return the first child with the given name it finds. Take a look at your scenegraph, there are some great tools for that out there on the User Code board. You should be able to identify your problem with one look at the scene graph tree.