New to JME!

renegadeandy said:

ok so if i had an enemy node. And had attached a healthbar child node to this, i would use setlocaltranslation on the healthbar to move it to the top of the enemy node - and then use set  local translation on the enemy node to change its position in the world as that node is a child of the root one>


thats the way to do it, yep.

Ok so currently my application has the following layout :



AbstractGame -> BaseGame -> BaseSimpleGame -> SimpleGame -> base(my main)



base has the following:



main

simpleinit

simpleupdate



I added simple update in there.



I access the camera by just doing cam.whatever etc etc etc - and plan on managing input and using this simpleupdate method to spawn of all other needed methods on each game loop such as check enemy positions, fire, listen for key input - make new defence etc etc etc.



Is this a good setup or is there a better place for this code.

have a look at standart game and the tutorial for it - i like it much more :slight_smile:

Ok, can you link me to it please, i dont see if on the wiki!



Also, am trying to follow a terrain guide and am having an odd problem, the guide is:



http://www.jmonkeyengine.com/wiki/doku.php?id=loading_the_terrain



and the bit is where it defines tb = new TerrainBlock(yada yada yada) my machine says that the arguments are wrong, and suggests something like :



         tb = new TerrainBlock("My Terrain",heightMap.getSize(), terrainScale, heightMap.getHeightMap(), new Vector3f(0,0,0), alphaBits, null,tpf);



However on running my code it gets a null pointer:






import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import jmetest.TutorialGuide.HelloModelLoading;

import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.renderer.Camera;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.intersection.PickData;
import com.jme.intersection.PickResults;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Ray;
import com.jme.math.Vector3f;

import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;

public class base extends SimpleGame{
   
   ArrayList nodes = new ArrayList();
    private static final Logger logger = Logger
     .getLogger(HelloModelLoading.class.getName());
    TerrainBlock tb;

   /**
    * @param args
    */
   public static void main(String[] args) {
   
         base app = new base();
           app.setConfigShowMode(ConfigShowMode.NeverShow);
          
           // Turn the logger off so we can see the XML later on
           app.start();
   }

   @Override
   
   
   
   protected void simpleInitGame() {
      // TODO Auto-generated method stub

      //setup terrain
      
      /*
        Node node = Loader.loadModel("jmetest/data/model/sydney.md2");
      node.setLocalScale(.1f);
      node.setModelBound(new BoundingSphere());
      node.updateModelBound();
      node.setLocalTranslation(100, 50, 10);
      nodes.add(node);
      */
      
      
   
      buildTerrain();
      rootNode.attachChild(tb);
      

      
       Box b=new Box("My box yo",new Vector3f(0,0,0),new Vector3f(1,1,1));

       rootNode.attachChild(b);
         // b.setLocalTranslation(new Vector3f(10,100,1000));
   }

   /**
     * Can be defined in derived classes for custom updating. Called every frame
     * in update.
     */
   
   
    protected void simpleUpdate() {
        //do nothing
       Ray ray = new Ray(cam.getLocation(), cam.getDirection());
       PickResults results = new TrianglePickResults();
       results.setCheckDistance(true);
       
       rootNode.findPick(ray,results);
       //check if we hit something
       if(results.getNumber() > 0) {
          PickData closest = results.getPickData(0);
          System.out.println("The closest hit: " + closest.getTargetMesh().getName());
       }
       
    }
   
    private void buildTerrain() {
          // Generate a random terrain data
          MidPointHeightMap heightMap = new MidPointHeightMap(64, 0.5f);
          Vector3f terrainScale = new Vector3f(20, 0.5f, 20);
         tb = new TerrainBlock("My Terrain",heightMap.getSize(), terrainScale, heightMap.getHeightMap(), new Vector3f(0,0,0), alphaBits, null,tpf);
          tb.setModelBound(new BoundingBox());
          tb.updateModelBound();
       }
}



Any ideas :S I am using 2.0 if that makes any difference, and couldnt find any info on this :S

http://www.jmonkeyengine.com/wiki/doku.php?id=standardgame_gamestates_and_multithreading_a_new_way_of_thinking

http://www.jmonkeyengine.com/wiki/doku.php?id=simplegame_to_standardgame

Hmm looks confusing i think i understand it at a high level:



You have gamestates - main menu, level1, level2, level3, pause, loading



you add each to a gamestatemanager and switch between them by selecting the gamestate and doing setActive(true).



So, my new main class is :






import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;

import jmetest.TutorialGuide.HelloModelLoading;

import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.renderer.Camera;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.util.GameTaskQueueManager;
import com.jme.intersection.PickData;
import com.jme.intersection.PickResults;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Ray;
import com.jme.math.Vector3f;

import com.jmex.game.StandardGame;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameStateManager;
import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;

public class base {
   
   ArrayList nodes = new ArrayList();
    private static final Logger logger = Logger
     .getLogger(HelloModelLoading.class.getName());
    TerrainBlock tb;

   /**
    * @param args
    */
   public static void main(String[] args) {
   
      //   base app = new base();
        //   app.setConfigShowMode(ConfigShowMode.NeverShow);
          
        //   app.start();
          
          
          
           StandardGame game = new StandardGame("TestGame");   // Create our game
           game.start();   // Start the game thread
          
           DebugGameState gameState = new DebugGameState();   // Create our game state
           GameStateManager.getInstance().attachChild(gameState);   // Attach it to the GameStateManager
           gameState.setActive(true);   // Activate it
          
           final Box box = new Box("TestBox", new Vector3f(), 1.0f, 1.0f, 1.0f);   // Create a Box (we have to make it final so we can use it in an anonymous implementation of Callable)
           box.setRandomColors();   // Set random colors on it
           GameTaskQueueManager.getManager().update(new Callable<Object>() {
            public Object call() throws Exception {
               box.lock();
               return null;
            }
           });
           box.updateRenderState();   // Update the render state so the colors appear (the game is already running, so this must always be done)
           gameState.getRootNode().attachChild(box);   // Attach the box to rootNode in DebugGameState
           gameState.getRootNode().updateRenderState();
          
          
   }

   public void buildTerrain() {
          // Generate a random terrain data
          MidPointHeightMap heightMap = new MidPointHeightMap(64, 0.5f);
          Vector3f terrainScale = new Vector3f(20, 0.5f, 20);
       //  tb = new TerrainBlock("My Terrain",heightMap.getSize(), terrainScale, heightMap.getHeightMap(), new Vector3f(0,0,0), alphaBits, null,tpf);
   
          tb.setModelBound(new BoundingBox());
          tb.updateModelBound();
       }
}



However it gets a null pointer at line :

DebugGameState gameState = new DebugGameState();

some things have to be processed inside the OpenGL Thread. use the GameTaskQueueManager for that. A list of which calls have to be inside the OpenGL thread is somewhere around the wiki. when you use StandardGame and get NullPointerExceptions out of nowhere, you can almost always be certain that its based on it not being executed in the OpenGL thread.

ahh right ok…



Exept that code snippet is pasted directly out of the example code in the multithreading new way of thinking wiki entry showing how to use the gamestates etc

XD … well then I'll have to pass  :wink:



EDIT:[me=dhdd]summons the frog[/me]

this is the console output :



25-Aug-2008 15:02:24 com.jme.input.joystick.DummyJoystickInput <init>
INFO: Joystick support is disabled
25-Aug-2008 15:02:24 com.jme.system.lwjgl.LWJGLDisplaySystem <init>
INFO: LWJGL Display System created.
25-Aug-2008 15:02:27 com.jme.renderer.lwjgl.LWJGLRenderer <init>
INFO: LWJGLRenderer created. W:  640H: 480
25-Aug-2008 15:02:28 com.jme.renderer.AbstractCamera <init>
INFO: Camera created.
25-Aug-2008 15:02:28 com.jmex.audio.openal.OpenALSystem setupSourcePool
INFO: max source channels: 64
25-Aug-2008 15:02:29 com.jmex.game.state.GameStateManager create
INFO: Created GameStateManager
25-Aug-2008 15:02:29 com.jme.util.lwjgl.LWJGLTimer <init>
INFO: Timer resolution: 1000 ticks per second
25-Aug-2008 15:02:29 com.jme.scene.Node <init>
INFO: Node created.
25-Aug-2008 15:02:29 com.jme.scene.Node <init>
INFO: Node created.
25-Aug-2008 15:02:29 com.jme.scene.Node attachChild
INFO: Child (Text) attached to this node (TextNode)
25-Aug-2008 15:02:29 com.jme.scene.Node <init>
INFO: Node created.
25-Aug-2008 15:02:29 com.jme.scene.Node <init>
INFO: Node created.
25-Aug-2008 15:02:29 com.jmex.game.state.StatisticsGameState setupGraph
SEVERE: Statistics cannot be displayed if Debug.stats is false, enable gathering of statistics first: System.setProperty("jme.stats", "set");
25-Aug-2008 15:02:29 com.jme.scene.Node <init>
INFO: Node created.
Exception in thread "main" java.lang.NullPointerException
   at com.jme.renderer.lwjgl.LWJGLTextureRenderer.<init>(LWJGLTextureRenderer.java:103)
   at com.jme.system.lwjgl.LWJGLDisplaySystem.createTextureRenderer(LWJGLDisplaySystem.java:321)
   at com.jme.util.stat.graph.AbstractStatGrapher.<init>(AbstractStatGrapher.java:69)
   at com.jme.util.stat.graph.LineGrapher.<init>(LineGrapher.java:90)
   at com.jme.util.stat.graph.GraphFactory.makeLineGraph(GraphFactory.java:69)
   at com.jmex.game.state.StatisticsGameState.setupStatGraphs(StatisticsGameState.java:149)
   at com.jmex.game.state.StatisticsGameState.setupGraph(StatisticsGameState.java:113)
   at com.jmex.game.state.StatisticsGameState.<init>(StatisticsGameState.java:98)
   at com.jmex.game.state.DebugGameState.init(DebugGameState.java:88)
   at com.jmex.game.state.DebugGameState.<init>(DebugGameState.java:81)
   at com.jmex.game.state.DebugGameState.<init>(DebugGameState.java:76)
   at base.main(base.java:55)

renegadeandy said:

25-Aug-2008 15:02:29 com.jmex.game.state.StatisticsGameState setupGraph
SEVERE: Statistics cannot be displayed if Debug.stats is false, enable gathering of statistics first: System.setProperty("jme.stats", "set");


the solution is in the output. put:

System.setProperty("jme.stats", "set");


before standardGame.start()

good point - ok i added that and now looked carefully at the next set of errors, and i dont think this time the solution is in the output!:



25-Aug-2008 15:28:33 com.jme.input.joystick.DummyJoystickInput <init>
INFO: Joystick support is disabled
25-Aug-2008 15:28:33 com.jme.system.lwjgl.LWJGLDisplaySystem <init>
INFO: LWJGL Display System created.
25-Aug-2008 15:28:33 com.jme.renderer.lwjgl.LWJGLRenderer <init>
INFO: LWJGLRenderer created. W:  640H: 480
25-Aug-2008 15:28:34 com.jme.renderer.AbstractCamera <init>
INFO: Camera created.
25-Aug-2008 15:28:34 com.jmex.audio.openal.OpenALSystem setupSourcePool
INFO: max source channels: 64
25-Aug-2008 15:28:34 com.jmex.game.state.GameStateManager create
INFO: Created GameStateManager
25-Aug-2008 15:28:34 com.jme.util.lwjgl.LWJGLTimer <init>
INFO: Timer resolution: 1000 ticks per second
25-Aug-2008 15:28:34 com.jme.scene.Node <init>
INFO: Node created.
25-Aug-2008 15:28:34 com.jme.scene.Node <init>
INFO: Node created.
25-Aug-2008 15:28:34 com.jme.scene.Node attachChild
INFO: Child (Text) attached to this node (TextNode)
25-Aug-2008 15:28:34 com.jme.scene.Node <init>
INFO: Node created.
25-Aug-2008 15:28:34 com.jme.scene.Node <init>
INFO: Node created.
25-Aug-2008 15:28:34 com.jme.scene.Node <init>
INFO: Node created.
Exception in thread "main" java.lang.NullPointerException
   at com.jme.renderer.lwjgl.LWJGLTextureRenderer.<init>(LWJGLTextureRenderer.java:103)
   at com.jme.system.lwjgl.LWJGLDisplaySystem.createTextureRenderer(LWJGLDisplaySystem.java:321)
   at com.jme.util.stat.graph.AbstractStatGrapher.<init>(AbstractStatGrapher.java:69)
   at com.jme.util.stat.graph.LineGrapher.<init>(LineGrapher.java:90)
   at com.jme.util.stat.graph.GraphFactory.makeLineGraph(GraphFactory.java:69)
   at com.jmex.game.state.StatisticsGameState.setupStatGraphs(StatisticsGameState.java:149)
   at com.jmex.game.state.StatisticsGameState.setupGraph(StatisticsGameState.java:113)
   at com.jmex.game.state.StatisticsGameState.<init>(StatisticsGameState.java:98)
   at com.jmex.game.state.DebugGameState.init(DebugGameState.java:88)
   at com.jmex.game.state.DebugGameState.<init>(DebugGameState.java:81)
   at com.jmex.game.state.DebugGameState.<init>(DebugGameState.java:76)
   at base.main(base.java:55)



Thanks so much for your continued support!

i dont know whats wrong there, i tested it myself and get the same exception. maybe someone else can help? its already been a long day here in Austria and i'm tired  :expressionless:



so long,

Andy

ur code works fine on my sytsem even without that System.setProperty("jme.stats", "set"); fix

so you have got a problem with your setups or its about jme2 because i m using jme1 and the tutorial is also written for jme 1


Hmm dam thats odd.



Anybody here that uses jme2 able to help me debug this?

i do use jme 2.0 … and Slevin seems to be right:



try that:



           Future<ClipState> future = GameTaskQueueManager.getManager().update(new Callable<ClipState>() {
            public Object call() throws Exception {
           DebugGameState gameState = new DebugGameState();   // Create our game state
           GameStateManager.getInstance().attachChild(gameState);   // Attach it to the GameStateManager
           gameState.setActive(true);   // Activate it
                return null;
            }
           });
                future.get();



EDIT: The forum has a few Topics on how the GameTaskQueueManager and Future<Object> works.

Ok, - i have changed the main a little, so now it runs and shows me the f4 for graph, which draws the graph fine.



code =






import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;

import jmetest.TutorialGuide.HelloModelLoading;

import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.renderer.Camera;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.ClipState;
import com.jme.util.GameTaskQueueManager;
import com.jme.intersection.PickData;
import com.jme.intersection.PickResults;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Ray;
import com.jme.math.Vector3f;

import com.jmex.game.StandardGame;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameState;
import com.jmex.game.state.GameStateManager;
import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;

public class base {
   
   //ArrayList nodes = new ArrayList();
   /// private static final Logger logger = Logger
    // .getLogger(HelloModelLoading.class.getName());
   /// TerrainBlock tb;

   /**
    * @param args
    */
   public static void main(String[] args) {
   
         System.setProperty("jme.stats", "set");
           StandardGame game = new StandardGame("TestGame");   // Create our game
           game.start();   // Start the game thread
          
          
           Future<ClipState> future = GameTaskQueueManager.getManager().update(new Callable<ClipState>() {
            public ClipState call() throws Exception {
           DebugGameState gameState = new DebugGameState();   // Create our game state
           GameStateManager.getInstance().attachChild(gameState);   // Attach it to the GameStateManager
           gameState.setActive(true);   // Activate it
                return null;
            }
           });
                try {
               future.get();
               
               
                   
                
               
            } catch (InterruptedException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            } catch (ExecutionException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
          
          
          
   }
}



So how do i now access and append objects to the DebugGameState object - and then say, switch to another game state ?

There's also quite a bit in the wiki about this as well.

ive read the wiki article, but i dont see how to actually append things to the rootnode of the gamestate DebugGameState because it seems out of scope :S

OH,! I think its just dawned on me.



So in the init method of my game - I add in all the possible game states, and in the main game loop, simply choose which game state to be shown. So I make 3 different game states, in their own classes, which in themselves are pretty much their own little bits of code



1)pause menu

2)main menu

3)level 1



And in the main GameStateManager bit, i put them all in, main menu first, if they click on play in main menu, that gamestate switches to the level1 gamestate object?!