Loading assets

Hey there,
I started 3 days ago with jmonkeyengine and already read the first 6 beginner tutorials in the documentation. And I attempted to make a simple scene.
I tried to make something tile-based with (at the moment) 3 different kind of tiles, a normal one, a hill and a mountain. I made my code so that it randomly decides if a tile will be a normal, hill or mountain. Examples:


Now first off some information about how I load these:
models are still somewhat crappy (I quickly made them in blender just to have some representation)
I basically loaded these assets in game with a for loop and calling some methods within to decide what kind of tile it should be.

Now… I really have no idea if this is the way to do these kind of things (to be honest I don’t think so) because in my for loop I call
[java]Spatial normalTile = assetManager.loadModel(“Models/Tile/Tile.j3o”);
rootNode.attachChild(normalTile); [/java]
(for example I also have the hillTile and mountainTile)
Then again it’s probably normal for me to make these kind of mistakes since I really have no past experience with jme 3.

Now for my other question, is there a way to control these assets after I placed them, to like update them or replace them with other tiles?
If yes could you tell me how? (I mean just give me a javadoc reference or something :D)

Btw: I do have Java experience from my university studies and modding minecraft in the past…

Thank you for reading.

PS: sorry for spelling mistakes, English isn’t my native language

Well, you could detach them and attach other models. :stuck_out_tongue:
(Another way would be something like animation - There are plenty of topic about that in the forum, but once you got yourself a method, that works, this is very handy :slight_smile:)

For the moment, I would suggest, you create your own class Tile, that extends from Node and attach the models to them - You then attach objects from the class Tile to your scene. This way, you can create methods for each tile object, e.g. “replaceModelWith(String modelPath)”, “addSomeCrazyEffect”, “setTextureVisible(boolean isVisible)”.

Quick 'n dirty, something like this: (Untested)
[java]import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

public class Tile extends Node{

public Tile(String modelPath){
    modelSpatial = addModelToTIle(modelPath);
}
protected Spatial modelSpatial;

public Spatial addModelToTIle(String modelPath){
    //Or however you can access your assetManager
    Spatial modelSpatial = Main.INSTANCE.getAssetManager().loadModel(modelPath);
    attachChild(modelSpatial);
    return modelSpatial;
}

public void removeMainModel(){
    detachChild(modelSpatial);
}

public void setWireFrameView(boolean isWireframe){
    //Set getAdditionalRenderState().setWireframe(isWireframe) to the material
}

public void addFireEffect(){
    YourFireParticleEmitterClas fire = new YourFireParticleEmitterClass();
    attachChild(fire);
}

public void someOtherMethodToModifyYourObject(){
    
}

}[/java]

I hope, that helps. :slight_smile:

Yeah sounds fair enough, thank you for the fast reply I`ll look into it right now

Hey I do know what you mean with your code, I just don’t know how to load these models with other classes
I can’t make references to my main class to place the models.
[java]Spatial modelSpatial = Main.INSTANCE.getAssetManager().loadModel(modelPath); [/java]
What exactly do you mean with Main.INSTANCE? I tried to look it up but couldn’t find any info about it.

Do I have to pass my assetmanager from my main class or something?

Ty for the help before and sorry for bothering

He must be storing his SimpleApplication in an instance variable. It’s quite a common pattern. (We use AppContext.getJME3() but it’s the same idea).

Yeah, somehow you have to access the assetManager in there, in my case I just linked to the SimpleApplication-instance and called it from there.
As the comment in the line above says:
[java]//Or however you can access your assetManager
Spatial modelSpatial = Main.INSTANCE.getAssetManager().loadModel(modelPath);[/java]

You can use something like this in your SimpleApplication-extended class. those instances are called “singletons”:
[java]public class YourClassName extends SimpleApplication{

public YourClassName(){
    INSTANCE = this;
    //...
}
public static INSTANCE;

//...

}[/java]

Ack, no!

Don’t create singletons like that, it’s a really bad idea. You are exporting the type before its fully initialized and can lead to horrible and near-impossible-to-track-down race condition bugs. You are also not preventing people creating multiple, and just the most recent is stored in the variable which again can lead to horrible bugs to track down.

Create singletons using:

[java]
private YourClassName() { // Private constructor prevents anyone accidentally creating a non-singleton version of the class.
}

private static final YourClassName instance = new YourClassName();

public static YourClassName getInstance() { return instance; }
[/java]

Personally I prefer using a getter, but using the instance variable is fine so long as its initialized correctly.

3 Likes

Alright guys thanks for the help, I solved my little problem.
Basically I just extended a wrong class (I made a similar testclass with a very little different name and got them both messed up … xP)