Application that doesn' extend anything

Hi,



Can anyone tell me a way to use JavaMonkeyEngine without extending anything. Here's my problem, I want my interface to extend a certain JADE Agent (Jade is kind of an RMI platform for IA agents), however jmonkeyengine has to extend BaseGame, which limits my flexibility greatly… any workaround?

jME doesn't have to extend BaseGame at all. BaseGame is just there to help organize a main game loop. You can extend anything really, you'll have have to take care of the render loop yourself, initializing the display system, updating, drawing and swapping the display buffers.

Great :slight_smile:



Can you point me to a simple example that runs a scene without extending anything?

hooray  :smiley: it worked, thx for the help  :wink:

I'm trying to learn JME and want to set up as much as possible myself to understand how things work. I've tried to strip it down to a single function. But I must have made a mistake because I only get black window. Can someone spot the mistake. Here is the code:


import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.*;
import com.jme.input.FirstPersonHandler;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.*;
import com.jme.scene.shape.Box;
import com.jme.scene.state.*;
import com.jme.system.*;
import com.jme.util.TextureManager;
import com.jme.util.Timer;

/**
 * A complete example of how to set JME and display a box.
 */
public class JMETest {

   /**
    * Setup and run JMETest
    */
   public static void main(String[] args) {
      DisplaySystem display = null;
      try {
         // init system
         display = DisplaySystem.getDisplaySystem("LWJGL");
         display.setMinDepthBits(8);
         display.setMinStencilBits(0);
         display.setMinAlphaBits(0);
         display.setMinSamples(0);
         display.createWindow(640, 480, 16, 60, false);
         // Create a camera specific to the DisplaySystem that works with the display's width and height
         Camera cam = display.getRenderer().createCamera(display.getWidth(), display.getHeight());

         // Set a black background.
         display.getRenderer().setBackgroundColor(ColorRGBA.black);

         // Set up how our camera sees.
         cam.setFrustumPerspective(45.0f, (float) display.getWidth() / (float) display.getHeight(), 1, 1000);
         cam.update();
         Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
         Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
         Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
         Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
         // Move our camera to a correct place and orientation.
         cam.setFrame(loc, left, up, dir);
         // Signal that we've changed our camera's location/frustum.
         cam.update();
         // Assign the camera to this renderer.
         display.getRenderer().setCamera(cam);

         // Create a basic input controller.
         InputHandler input = new FirstPersonHandler(cam, 50, 1);

         // Get a high resolution timer for FPS updates.
         Timer timer = Timer.getTimer("LWJGL");

         // bind esc key
         KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);

         // init game
         // Create rootNode
         Node rootNode = new Node("rootNode");

         // Create a ZBuffer to display pixels closest to the camera above farther ones.
         ZBufferState buf = display.getRenderer().createZBufferState();
         buf.setEnabled(true);
         buf.setFunction(ZBufferState.CF_LEQUAL);
         rootNode.setRenderState(buf);

         // ---- LIGHTS
         // Attach the light to a lightState and the lightState to rootNode.
         LightState lightState = display.getRenderer().createLightState();
         lightState.setEnabled(false);
         rootNode.setRenderState(lightState);

         // Let derived classes initialize.
         display.setTitle("Manipulation of TextureBuffer");

         Box floor = new Box("Floor", new Vector3f(), 100, 1, 100);
         floor.setModelBound(new BoundingBox());
         floor.updateModelBound();
         floor.getLocalTranslation().y = -20;
         TextureState ts = display.getRenderer().createTextureState();
         //Base texture, not environmental map.
         Texture t0 = TextureManager.loadTexture(Test1.class.getClassLoader().getResource(
                     "jmetest/data/images/Monkey.jpg"), Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
         t0.setWrap(Texture.WM_WRAP_S_WRAP_T);
         ts.setTexture(t0);
         floor.setRenderState(ts);

         floor.getTextureBuffer().put(16 * 2, 0).put(16 * 2 + 1, 5);
         floor.getTextureBuffer().put(17 * 2, 0).put(17 * 2 + 1, 0);
         floor.getTextureBuffer().put(18 * 2, 5).put(18 * 2 + 1, 0);
         floor.getTextureBuffer().put(19 * 2, 5).put(19 * 2 + 1, 5);

         rootNode.attachChild(floor);

         // Update geometric and rendering information for the rootNode
         rootNode.updateGeometricState(0.0f, true);
         rootNode.updateRenderState();

         //main loop
         boolean finished = false;
         while (!finished && !display.isClosing()) {
            //handle input events prior to updating the scene
            InputSystem.update();

            //update game state
            timer.update();
            input.update(timer.getTimePerFrame());

            if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit", false)) {
               finished = true;
            }

            // Reset display's tracking information for number of triangles/vertexes
            display.getRenderer().clearStatistics();
            // Clears the previously rendered information.
            display.getRenderer().clearBuffers();

            //swap buffers
            display.getRenderer().displayBackBuffer();

            Thread.yield();
         }
      } catch (Throwable t) {
         t.printStackTrace();
      }

      // quit
      if (display != null) {
         display.reset();
         display.close();
      }
      
      System.exit(0);
   }
}

why not use extend one of the things in com.jme.app and furthure more maybe break it up.  I have a hard time just staring at a huge thing of code looking for 1 error.  Lastly look at the stuff in com.jme.app and compare and contrast.

I like to have everything that is needed to setup jme in one place. It helps me understand how things work. The code I posted before is taken from AbstractGame, BaseGame, BaseSimpleGame, SimpleGame and TestBox. I tried to merge all of it and remove the reduntant code. I know it is difficult to spot an error when there is so much code. I'll read the wiki and the other docs and come back with a bunch of newbie questions when I'm done.



Btw, could it be possible to add the protected functions and member variables of the com.jme.app classes to the javadoc. The classes are impossible to use without the source.

Have a look at your loop…  it doesn't draw or update a scenegraph…  :slight_smile:

Got it. Needed to add "display.getRenderer().draw(rootNode);" in the loop. Also had to add "rootNode.setRenderState(display.getRenderer().createTextureState());" to get texturing to work.

@tom



Learnt a lot from your example.

Thanks for posting it!



peter

typezero said:

Hi,

Can anyone tell me a way to use JavaMonkeyEngine without extending anything. Here's my problem, I want my interface to extend a certain JADE Agent (Jade is kind of an RMI platform for IA agents), however jmonkeyengine has to extend BaseGame, which limits my flexibility greatly... any workaround?


I have a very similar problem here. I need to know how can i create a box that extends Agent.

inheritance is allways overused…most of the time there are other ways of doing it. why can't your box just be a representation of your agent and be coupled with it in some other way for example? consider if delegetaion or composition works…



from my design pattern book:



"That leads us to our second principle of object-oriented design :

Favor object composition over class inheritance.

...Nevertheless, our experience is that designers overuse inheritance as a reuse technique, and designs are often made more reusable (and simpler) by depending more on object composition. You'll see object composition applied again and again in the design patterns."


some other valuable points:


Consider composition as an alternative to subclassing.
Composition :

  • is implemented simply by forwarding all calls to an object field

  • has no dependence on implementation details of the object field

  • is more flexible, since it is defined dynamically at run-time, not statically at compile-time



Subclassing has the following issues :


  • it violates encapsulation, since the implementations of the superclass and subclass become tightly coupled

  • new methods added to the superclass can break the subclass

  • superclass and subclass need to evolve in parallel

  • designing a class so that it may be safely extended takes extra work -