Convert BasicGameState to SimpleGame

I have a simple animation that extends BasicGameState.



How can I merge it into my existing game that extends SimpleGame? 



Any easy way to do that?



merge the code in the following (extends BasicGameState)

http://www.oniva.com/upload/1356/StarfieldDemoGameState.java



copy the code above to a Game that (extends SimpleGame)

http://www.oniva.com/upload/1356/TestColladaLoading.java

In your simpleInitGame() Method you can create the instances of StarfieldDemoGameState and attach them to the GameStateManager.



I think this should already be enough because SimpleGame is already set up to render Gamestates.



Then in simpleRender() you need to render the GameStates.

but if i do that way I will get null pointer exception



GameStateManager.getInstance().attachChild(gameState);




package jmetest.renderer.loader;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme.app.AbstractGame;
import com.jme.app.SimpleGame;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.game.state.BasicGameState;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameState;
import com.jmex.game.state.GameStateManager;
import com.jmex.model.converters.MaxToJme;


public class TestMaxJmeWrite extends SimpleGame {
    private static final Logger logger = Logger.getLogger(TestMaxJmeWrite.class
            .getName());
   
    public static void main(String[] args) {

        TestMaxJmeWrite app = new TestMaxJmeWrite();
        if (args.length > 0) {
            app.setModelToLoad(args[0]);
        }
        app.setDialogBehaviour(AbstractGame.FIRSTRUN_OR_NOCONFIGFILE_SHOW_PROPS_DIALOG);
        app.start();

       

    }

    private URL modelToLoad = null;

    private void setModelToLoad(String string) {
        try {
            modelToLoad = (new File(string)).toURI().toURL();
        } catch (MalformedURLException e) {
        }
    }

    protected void simpleInitGame() {
        if (modelToLoad == null) {
            modelToLoad = TestMaxJmeWrite.class.getClassLoader().getResource(
                    "jmetest/data/model/Character.3DS");
        }
        try {
            MaxToJme C1 = new MaxToJme();
            ByteArrayOutputStream BO = new ByteArrayOutputStream();
            C1.convert(new BufferedInputStream(modelToLoad.openStream()), BO);
            Node r1 = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            //Node r = new Node("parent stuff");
            //r.attachChild(C1.get(new BufferedInputStream(modelToLoad.openStream()), BO));
            //r.setLocalScale(.1f);
            r1.setLocalScale(.1f);
            if (r1.getChild(0).getControllers().size() != 0)
                r1.getChild(0).getController(0).setSpeed(20);
           
            Quaternion temp = new Quaternion();
            temp.fromAngleAxis(FastMath.PI / 2, new Vector3f(-1, 0, 0));
            rootNode.setLocalRotation(temp);
            r1.setLocalTranslation(new Vector3f(10,0,0));
            //rootNode.attachChild(r);
            rootNode.attachChild(r1);
           
           
           
           
            float velocityX = 10.0f;
            float velocityY = 10.0f;
           
            // Layered fields create multiple star sizes.
            BasicGameState[] gameStates = new BasicGameState[] {
                new StarfieldDemoGameState("Starfield 1", 15, 20, 3.0f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 2", 30, 20, 2.5f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 3", 60, 20, 2.0f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 4", 120, 20, 1.5f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 5", 240, 20, 1.0f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 6", 480, 20, 0.5f, velocityX, velocityY),
                new DebugGameState()};
         
            for (GameState gameState : gameStates) {
               GameStateManager.getInstance().attachChild(gameState);
               gameState.setActive(true);
            }
           
         
           
        } catch (IOException e) {
            logger.log(Level.SEVERE, "Failed to load Max file", e);
        }
    }
}






package jmetest.renderer.loader;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;

import com.jme.renderer.Renderer;
import com.jme.scene.BatchMesh;
import com.jme.scene.Spatial;
import com.jme.scene.batch.PointBatch;
import com.jme.scene.state.LightState;
import com.jme.system.DisplaySystem;
import com.jme.util.geom.BufferUtils;
import com.jmex.editors.swing.settings.GameSettingsPanel;
import com.jmex.game.StandardGame;
import com.jmex.game.state.BasicGameState;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameState;
import com.jmex.game.state.GameStateManager;

/**
 * The StarfieldGameState displays a set of points in a scene using QUEUE_ORTHO mode to simulate a parallax scrolling star
 * field.
 *
 * @author Matthew Woodard
 */
public class StarfieldDemoGameState extends BasicGameState {
   /** The number of stars to render */
   private int mNumStars;

   /** The depth of the field - the number of steps between the 'front' and 'back' parallax layers */
   private int mDepth;

   /** The size of the stars */
   private float mStarSize;

   /** The velocity of the field in the X direction - individual stars are proportional to their depth */
   private float mVelocityX = 0.0f;

   /** The velocity of the field in the Y direction - individual stars are proportional to their depth */
   private float mVelocityY = 0.0f;

   /** The star field controller adjusts the position of the stars over time */
   protected StarfieldController mStarfieldController;

   /** The mesh onto which the stars are drawn */
   protected BatchMesh mBackgroundMesh;

   /**
    * The StarfieldController moves the stars in the mesh.
    *
    * @author Matthew Woodard
    */
   public class StarfieldController {
      /** The width of the field */
      private int mWidth;

      /** The height of the field */
      private int mHeight;

      /** The star positions */
      private FloatBuffer mStarPositionBuffer;

      /** The star colors (dim in back, bright in front) */
      private FloatBuffer mStarColorBuffer;

      /** The indexes to render (all points) */
      private IntBuffer mStarIndexBuffer;

      /** The points to render */
      private PointBatch mPointBatch;

      /** The star depth positions used to determine color and scaled movement */
      private float mPositionZ[];

      /**
       * Initializes all of the buffers required to render the stars.
       *
       * @param width
       *           the width of the field
       * @param height
       *           the height of the field
       */
      public StarfieldController(int width, int height) {
         mWidth = width;
         mHeight = height;

         mPositionZ = new float[mNumStars];
         for (int i = 0; i < mNumStars; i++) {
            mPositionZ[i] = (int) (Math.random() * mDepth) + 1;
         }

         Arrays.sort(mPositionZ);

         mStarIndexBuffer = BufferUtils.createIntBuffer(mNumStars);
         mStarColorBuffer = BufferUtils.createFloatBuffer(4 * mNumStars);
         mStarPositionBuffer = BufferUtils.createFloatBuffer(3 * mNumStars);
         for (int star = 0; star < mNumStars; star++) {
            float z = mPositionZ[star] / (float) mDepth;

            mStarPositionBuffer.put((float) (Math.random() * width)).put((float) (Math.random() * height)).put(z);
            mStarColorBuffer.put(z).put(z).put(z).put(1);
            mStarIndexBuffer.put(star);
         }
         mStarPositionBuffer.flip();
         mStarColorBuffer.flip();
         mStarIndexBuffer.flip();

         mPointBatch = new PointBatch();
         mPointBatch.setVertexBuffer(mStarPositionBuffer);
         mPointBatch.setColorBuffer(mStarColorBuffer);
         mPointBatch.setIndexBuffer(mStarIndexBuffer);
         mPointBatch.setPointSize(mStarSize);
      }

      /**
       * Invoked in order to move the star field. All movement is on the X,Y plane to simulate a classic parallax star field. Z
       * movement could be simulated by adjusting the Z position, which would adjust the intensity and relative motion of each
       * star over time.
       *
       * @param tpf
       *           the time per frame, used to maintain smooth movement regardless of frame rate
       */
      public void update(float tpf) {
         for (int i = 0; i < mNumStars; i++) {
            int index = i * 3;

            float x = mStarPositionBuffer.get(index);
            float y = mStarPositionBuffer.get(index + 1);
            float z = mPositionZ[i];

            x += (mVelocityX * tpf * 10.0f) * (z / mDepth);
            y += (mVelocityY * tpf * 10.0f) * (z / mDepth);

            if (x >= mWidth) {
               x = 0;
            } else if (x < 0) {
               x = mWidth - 1;
            }
            if (y >= mHeight) {
               y = 0;
            } else if (y < 0) {
               y = mHeight - 1;
            }

            mStarPositionBuffer.put(index, x);
            mStarPositionBuffer.put(index + 1, y);
         }
      }
   }

   /**
    * Constructs a new state that renders a simulated parallax star field on a mesh.
    *
    * @param n
    *           the name of the state
    * @param numStars
    *           the number of stars to render
    * @param depth
    *           the parallax field depth
    * @param starSize
    *           the size of the stars
    */
   public StarfieldDemoGameState(String n, int numStars, int depth, float starSize, float velocityX, float velocityY) {
      super(n);

      mDepth = depth;
      mStarSize = starSize;
      mNumStars = numStars;
      mVelocityX = velocityX;
      mVelocityY = velocityY;

      initGameState();
   }

   /**
    * Updates the star field, moving the stars in a parallax manner.
    *
    * @see com.jmex.game.state.BasicGameState#update(float)
    */
   @Override
   public void update(float tpf) {
      super.update(tpf);

      mStarfieldController.update(tpf);
   }

   /**
    * Initializes the controller and the star mesh.
    */
   protected void initGameState() {
      DisplaySystem displaySystem = DisplaySystem.getDisplaySystem();

      mStarfieldController = new StarfieldController(displaySystem.getWidth(), displaySystem.getHeight());

      mBackgroundMesh = new BatchMesh("Starfield", mStarfieldController.mPointBatch);
      mBackgroundMesh.setCullMode(Spatial.CULL_NEVER);
      mBackgroundMesh.setLightCombineMode(LightState.OFF);
      mBackgroundMesh.setRenderQueueMode(Renderer.QUEUE_ORTHO);
      mBackgroundMesh.updateRenderState();

      getRootNode().attachChildAt(mBackgroundMesh, 0);
   }
  
  
   /**
    * @return the x velocity
    */
   public float getVelocityX() {
      return mVelocityX;
   }

   /**
    * @param velocityX the x velocity to set
    */
   public void setVelocityX(float velocityX) {
      mVelocityX = velocityX;
   }

   /**
    * @return the y velocity
    */
   public float getVelocityY() {
      return mVelocityY;
   }

   /**
    * @param velocityY the y velocity to set
    */
   public void setVelocityY(float velocityY) {
      mVelocityY = velocityY;
   }

   /**
    * Demonstrate layered star fields.
    *
    * @param args no arguments expected
    * @throws InterruptedException thrown by gaem.start()
    */
   public static void main(String[] args) throws InterruptedException {
      // Instantiate StandardGame
      StandardGame game = new StandardGame("A Starfield Demo");

      // Show settings screen
      GameSettingsPanel.prompt(game.getSettings());

      // Start StandardGame, it will block until it has initialized successfully, then return
      game.start();
     
      // The Demo causes the stars to move in the +X and +Y directions
      float velocityX = 10.0f;
      float velocityY = 10.0f;
     
      // Layered fields create multiple star sizes.
      BasicGameState[] gameStates = new BasicGameState[] {
          new StarfieldDemoGameState("Starfield 1", 15, 20, 3.0f, velocityX, velocityY),
          new StarfieldDemoGameState("Starfield 2", 30, 20, 2.5f, velocityX, velocityY),
          new StarfieldDemoGameState("Starfield 3", 60, 20, 2.0f, velocityX, velocityY),
          new StarfieldDemoGameState("Starfield 4", 120, 20, 1.5f, velocityX, velocityY),
          new StarfieldDemoGameState("Starfield 5", 240, 20, 1.0f, velocityX, velocityY),
          new StarfieldDemoGameState("Starfield 6", 480, 20, 0.5f, velocityX, velocityY),
          new DebugGameState()};
   
      for (GameState gameState : gameStates) {
         GameStateManager.getInstance().attachChild(gameState);
         gameState.setActive(true);
      }
   }
}


oops, SimpleGamedoes not render GameStates, i was wrong there.

So, what you do is:

  • create a GameStateManager instance
  • add GameStates
  • update and render the GameStates in simpleUpdate() simpleRender()



import com.jme.app.SimpleGame;
import com.jmex.game.state.BasicGameState;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameState;
import com.jmex.game.state.GameStateManager;


public class StarfieldTest extends SimpleGame {
    @Override
    protected void simpleInitGame() {
        // The Demo causes the stars to move in the +X and +Y directions
        float velocityX = 10.0f;
        float velocityY = 10.0f;
        BasicGameState[] gameStates = new BasicGameState[] {
                new StarfieldDemoGameState("Starfield 1", 15, 20, 3.0f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 2", 30, 20, 2.5f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 3", 60, 20, 2.0f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 4", 120, 20, 1.5f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 5", 240, 20, 1.0f, velocityX, velocityY),
                new StarfieldDemoGameState("Starfield 6", 480, 20, 0.5f, velocityX, velocityY),
                new DebugGameState()};
        GameStateManager.create();
        for (GameState gameState : gameStates) {
            GameStateManager.getInstance().attachChild(gameState);
            gameState.setActive(true);
        }

    }

    public static void main(String[] args) {
        new StarfieldTest().start();
       
    }
    @Override
    protected void simpleRender() {
        super.simpleRender();
        GameStateManager.getInstance().render(Timer.getTimer().getTimePerFrame());
    }
   
    @Override
    protected void simpleUpdate() {
        super.simpleUpdate();
        GameStateManager.getInstance().update(Timer.getTimer().getTimePerFrame());
    }
   
}