Noob Worries

Hi Guys (new to the forum and new to Java)

I’ve started a new journey into Java but coming from a C/C++, PHP, Perl, JavaScript background working with various frameworks in the past I can’t say that Java scares me much. That being said frameworks usually complicate things and there is a steep learning curve, that being said I realise of course that frameworks make tasks simpler in the end once you’ve gotten to grips with the tools and how to use them.

I’ve recently bought a couple of books (Learning Libgdx Game Development by Oehlke, Andreas and jMonkeyEngine 3.0 Beginner’s Guide by Ruth Kusterer) both of them use the same publisher (PackT Publishing). I started out with the Learning Libgdx which is a 2D engine and although excited I noticed some errors in the book which I emailed the author about. After reading several more pages I ended up with several more emails to the author regarding stupid mistakes in the book. Anyway to cut a long story short I was trying to understand the book instead of trying to understand java/Libgdx. I’ve since returned the book and opened the jMonkeyEngine 3.0 Beginner’s Guide: hence why I’m here.

Working through this book is starting to give me the same problems as before. I’ve worked to the letter within the pages and constantly hit problems. I know it’s not me as sometimes the SDK suggests fixes that solve the issue even though the book makes no mention of them. Does anyone have access to this book that would be willing to help?

For instance page 54 is asking me to create a new class file called UserInput.java and I am to refactor the main() method to use:

[java]UserInput app = new UserInput();[/java]

I’m getting an error on the app object as it is already being used:

"error: variable app is already defined in method main(String[]) UserInput app = new UserInput();"

if I remove the:

[java]Main app = new Main();[/java]

…so that I may use the app variable then app.start() no longer exists.

error: cannot find symbol app.setSettings(settings); symbol: method setSettings(AppSettings) location: variable app of type UserInput error: cannot find symbol app.start(); symbol:method start() location: variable app of type UserInput

It seems that I’m getting bogged down in the problems in the book instead of progressing. :explode:

Has anyone tried following this book?

Many thanks
James

Looking at the book, it tells you to refactor the first line to use the UserInput class, which means you should no longer have the “Main app = new Main()” because you refactored it to “UserInput app = new UserInput()”.

Also, if you are experienced in coding you certainly see that you create the application object here, obviously you don’t do that twice and especially not with another application class called “Main”.

1 Like

Thanks Normen

I hope that mentioning my past experience hasn’t tainted your opinion. I merely intended to give anyone reading my first post that I have past experience with other languages and that I am taking java and the jMonkeyEngine on together with <span style=“text-decoration:underline;”>some</span> confidence. This is all foreign land to me.

I appreciate your answer but I’m still a little confused by what the book is telling me to do. Obviously (I use the word loosely :facepalm:) I would do the following to allow both objects to work together:

[java]public static void main(String args) {

    AppSettings settings = new AppSettings(true);        
    Main appStart = new Main();
    UserInput app = new UserInput();
    
    settings.setTitle("My Tower Defense Demo");
    settings.setSettingsDialogImage("Interface/towerdefensesplash.png");
    settings.setResolution(1024,768);
    settings.setUseInput(true);
    settings.setSamples(16);
    settings.setVSync(true);
    
    appStart.setSettings(settings);
    appStart.start();
}[/java]

Is this right?

I’m wording why the book didn’t just ask me to write:

[java]UserInput uInput = new UserInput();[/java]

Then there wouldn’t have been a need for the confusion.

I don’t mean to sound difficult but my experience with java so far is very exciting but the latest two books have me wondering if what I’m writing is correct. For example page 44 shows the line for changing the Input Handling settings:

[java]settings.useInput(false);[/java]

But when I tried that I received an error:

error: cannot find symbol settings.UseInput(true); symbol: method UseInput(boolean) location: variable settings of type AppSettings

It was only after looking at similar statements that I thought to try

[java]settings.setUseInput(false);[/java]

Can you see my point?

The book tells you to create a new copy of the basic game java class, where the code in main() looks like this:
[java] public static void main(String[] args) {
Main app = new Main();
app.start();
}
[/java]

and then tells you to refactor the first line to “UserInput app = new UserInput();” which would make
[java] public static void main(String[] args) {
UserInput app = new UserInput();
app.start();
}
[/java]

About the useInput on AppSettings, thats true, only the getter is called useInput(), that would be worthy of a report. However in cases like these (typos, copy-paste issues etc.) you can see a list of all existing methods of an object by pressing Ctrl-Space after the variable name, e.g. “appSettings.[Ctrl-Space]”.

Basically I don’t really see your point, no, unless its “you can always find something else to blame but yourself if you look hard enough”. What would be your point in one sentence?

Ouch!

Like I say, I’m trying to be difficult nor am I trying to blame anyone.

Thanks for showing the code fix. I’ve updated it as I mentioned in my first post

Here’s the code with the suggested use:

[java] public static void main(String args) {

    AppSettings settings = new AppSettings(true);        
    UserInput app = new UserInput();
    
    settings.setTitle("My Tower Defense Demo");
    settings.setSettingsDialogImage("Interface/towerdefensesplash.png");
    settings.setResolution(1024,768);
    settings.setUseInput(true);
    settings.setSamples(16);
    settings.setVSync(true);
    
    app.setSettings(settings);
    app.start();
}[/java]

And here’s the errors:

error: cannot find symbol app.setSettings(settings); symbol: method setSettings(AppSettings) location: variable app of type UserInput

error: cannot find symbol app.start();
symbol: method start()
location: variable app of type UserInput

Can you help?
Thanks
James

…so you didn’t want to make a point it seems?

Okay, lets go step by step though the book chapter, OK?

1) Make another copy of the BasicGame projects Main.java template and name the class UserInput.java. Remember also to refactor the first line of the main() method to the following: UserInput app = new UserInput();

So if you have an empty Main.java from a BasicGame project it looks like this:

[java]package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

/**

  • test

  • @author normenhansen
    */
    public class Main extends SimpleApplication {

    public static void main(String args) {
    Main app = new Main();
    app.start();
    }

    @Override
    public void simpleInitApp() {
    Box b = new Box(1, 1, 1);
    Geometry geom = new Geometry(“Box”, b);

     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setColor("Color", ColorRGBA.Blue);
     geom.setMaterial(mat);
    
     rootNode.attachChild(geom);
    

    }

    @Override
    public void simpleUpdate(float tpf) {
    //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
    //TODO: add render code
    }
    }
    [/java]

… and you’re told to copy it to the name of UserInput.java.

if you do that with Ctrl-C and Ctrl-V and then enter the new name to the refactoring panel that pops up you automatically get this:

[java]package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

/**

  • test

  • @author normenhansen
    */
    public class UserInput extends SimpleApplication {

    public static void main(String args) {
    UserInput app = new UserInput();
    app.start();
    }

    @Override
    public void simpleInitApp() {
    Box b = new Box(1, 1, 1);
    Geometry geom = new Geometry(“Box”, b);

     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setColor("Color", ColorRGBA.Blue);
     geom.setMaterial(mat);
    
     rootNode.attachChild(geom);
    

    }

    @Override
    public void simpleUpdate(float tpf) {
    //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
    //TODO: add render code
    }
    }
    [/java]

… if you copy the file in another way you will have to follow the last step which is

Remember also to refactor the first line of the main() method to the following: UserInput app = new UserInput();

so if your fist line of main() still reads “Main main = new Main();” then you would refactor that to “UserInput userInput = new UserInput()”. But in most cases this will already be done by the SDK.

^— Note that you created the application class here that isn’t found in your example, so this step is probably your problem.

So for the next steps:

2. Define class constants that represent the Space bar and left-click of the mouse. Import the necessary classes from the com.jme3.input.* and com.jme3.input.controls.* packages. private final static Trigger TRIGGER_COLOR = new KeyTrigger(KeyInput.KEY_SPACE); private final static Trigger TRIGGER_COLOR = new MouseButtonTrigger(MouseInput.BUTTON_LEFT;)
  1. Define two string class constants. We use the Strings to identify the two actions later: rotating the cube and toggling its color.
    private static final String MAPPING_COLOR = “Toggle Color”;
    private static final String MAPPING_ROTATE = “Rotate”;

In none of the steps using setUseInput is mentioned and with your error you obviously did not do what was said, which is copying a clean Main.java file to UserInput.java and launching that.

1 Like

Thanks Normen

Sorry for the delay, I seem to have ended up creating a further class file named UserInput.java within my original package rather than a completely new package named UserInput which is were I went wrong. :S

Thanks for writing the baby steps for me :slight_smile:

I thought it may be easier to download the book source files which I’ve done. I’ve opened the Chapter 3 section and copied the code into my UserInput.java class file.

[java]package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.input.controls.Trigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

/**

  • This sample demonstrates how to detect and respond to user input.

  • Left-clicking rotates the cube (“analog”).

  • Pressing spacebar or C toggles the cube’s color (“discrete”).

  • It also shows how to free up existing input mappings.
    */
    public class UserInput extends SimpleApplication {

    private Geometry geom;
    private final static Trigger TRIGGER_COLOR = new KeyTrigger(KeyInput.KEY_SPACE);
    private final static Trigger TRIGGER_COLOR2 = new KeyTrigger(KeyInput.KEY_C);
    private final static Trigger TRIGGER_ROTATE = new MouseButtonTrigger(MouseInput.BUTTON_LEFT);
    private final static String MAPPING_COLOR = “Toggle Color”;
    private final static String MAPPING_ROTATE = “Rotate”;

    @Override
    /** initialize the scene here /
    public void simpleInitApp() {
    /
    * unregister one default input mapping, so you can refine Key_C /
    inputManager.deleteMapping(INPUT_MAPPING_CAMERA_POS); // free up Key_C
    /
    * register input mappings to input manager */
    inputManager.addMapping(MAPPING_COLOR, TRIGGER_COLOR, TRIGGER_COLOR2);
    inputManager.addMapping(MAPPING_ROTATE, TRIGGER_ROTATE);
    inputManager.addListener(actionListener, new String{MAPPING_COLOR});
    inputManager.addListener(analogListener, new String{MAPPING_ROTATE});

     /** Create a blue cube */
     Box mesh = new Box(1, 1, 1);
     geom = new Geometry("Box", mesh);
     Material mat = new Material(assetManager,
             "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setColor("Color", ColorRGBA.Blue);
     geom.setMaterial(mat);
     rootNode.attachChild(geom);
    

    }

    private ActionListener actionListener = new ActionListener() {
    public void onAction(String name, boolean isPressed, float tpf) {
    System.out.println("Mapping detected (discrete): "+name );
    if (name.equals(MAPPING_COLOR) && !isPressed) {
    geom.getMaterial().setColor(“Color”, ColorRGBA.randomColor());
    } // else if …
    }
    };

    private AnalogListener analogListener = new AnalogListener() {

     public void onAnalog(String name, float intensity, float tpf) {
         System.out.println("Mapping detected (analog): "+name );
         if (name.equals(MAPPING_ROTATE)) {
             geom.rotate(0, intensity * 10f, 0);
         } // else if ...
     }
    

    };

    /** Start the jMonkeyEngine application */
    public static void main(String args) {
    UserInput app = new UserInput();
    app.start();

    }
    }[/java]

I can’t find anything regarding why I receive the following errors (google search/forum search doesn’t pin-point the problem). Is there something I’ve missed.

Note: this will build fine it is only after launching that it exits with a dialogue error message and this is shown in the console:

Dialogue message

Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main] NullPointerException

Console

WARNING: Cannot find mapping to be removed, skipping: SIMPLEAPP_CameraPos Jan 11, 2014 11:13:46 AM com.jme3.app.Application handleError SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main] java.lang.NullPointerException at com.jme3.input.InputManager$Mapping.access$200(InputManager.java:110) at com.jme3.input.InputManager.deleteMapping(InputManager.java:607) at mygame.UserInput.simpleInitApp(UserInput.java:35) at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226) at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130) at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207) at java.lang.Thread.run(Thread.java:722)

Did I miss something?

Look at the error output. It tells you in which line of your class the problem is. In this case you can just remove it (see warning in output).

Thanks again.

The book tells me that KEY_C is already mapped to diagnostic output which is dumps in the console. To remove the default mapping action of a key I need to keep the code

[java]inputManager.deleteMapping(INPUT_MAPPING_CAMERA_POS); // free up Key_C[/java]

But it doesn’t tell me that I should get this error so why does it occur?

@Dal1980 said: Thanks again.

The book tells me that KEY_C is already mapped to diagnostic output which is dumps in the console. To remove the default mapping action of a key I need to keep the code

[java]inputManager.deleteMapping(INPUT_MAPPING_CAMERA_POS); // free up Key_C[/java]

But it doesn’t tell me that I should get this error so why does it occur?

And the output tells you that mapping doesn’t exist, as I said you can just remove that call. This occurs because the engine changed after the book was written.

I think that it is well worth of a notice that, as Normen said, the engine has changed since the release of the book - that’s very cool! The engine is regularly updated and improved.

It looks like that you are experiencing problems on both frontiers: the Java language and the JME logic. I think that you should learn the core concepts of Java like main classes, exceptions and stuff prior to jumping into 3D game development with it. And maybe use some simpler tool for starters, like Processing. Also, the tutorials on this website are pretty cool too, you could check them out. I think they’re updated according to the engine changes.

Good luck!