How to make the AbsoluteMouse on the JMEDesktop?

    my custom cursor is always under the JMEDesktop. I have seen the TestJMEDesktop.java in jmetest, but i don't know how it works.

    here is the code.

   

public class TextAbsoluteMouse extends SimpleGame

{

    private JMEDesktop jmeDesktop;

    private Node desktopNode;

    private AbsoluteMouse cursor;



    public TextAbsoluteMouse()

    {

    }



   public static void main(String []args)

   {

      TextAbsoluteMouse app = new TextAbsoluteMouse();

      app.setDialogBehaviour(BaseGame.ALWAYS_SHOW_PROPS_DIALOG);

      app.start();

   }



   @Override

   protected void simpleInitGame()

   {

      initJmeDesktop();

      createCustomCursor();

   }



   private void initJmeDesktop()

   {

      // TODO Auto-generated method stub

      desktopNode = new Node("desktop");

      desktopNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);

      

      jmeDesktop = new JMEDesktop("jmedesktop",500,400,input);

      

      desktopNode.attachChild(jmeDesktop);

      jmeDesktop.getLocalTranslation().set( display.getWidth() / 2 - 30, display.getHeight() / 2 + 50, 0);

      

      jmeDesktop.getJDesktop().setBackground( new Color( 0, 0, 1, 0.2f ) );



        // create a swing button

        final JButton button = new JButton( "click me" );

        // and put it directly on the desktop

        jmeDesktop.getJDesktop().add( button );

        // desktop has no layout - we layout ourselfes (could assign a layout to desktop here instead)

        button.setLocation( 200, 200 );

        button.setSize( button.getPreferredSize() );

       

        desktopNode.setCullMode(SceneElement.CULL_NEVER);

        desktopNode.setLightCombineMode(LightState.OFF);

        desktopNode.updateRenderState();

        desktopNode.updateGeometricState(0.0f,true);

   }

   

   protected void simpleRender()

   {

      // draw the gui stuff after the scene

       display.getRenderer().draw( desktopNode );

   }

   private void createCustomCursor()

   {

      cursor = new AbsoluteMouse( "cursor", display.getWidth(), display.getHeight() );



      // Get a picture for my mouse.

      TextureState ts = display.getRenderer().createTextureState();

      URL cursorLoc;

      cursorLoc = TextAbsoluteMouse.class.getClassLoader().getResource(

                      "jmetest/data/cursor/cursor1.png" );

      Texture t = TextureManager.loadTexture( cursorLoc, Texture.MM_LINEAR,

                      Texture.FM_LINEAR, Image.GUESS_FORMAT_NO_S3TC, 1, true );

      ts.setTexture( t );

      cursor.setRenderState( ts );

   

      // Make the mouse's background blend with what's already there

      AlphaState as = display.getRenderer().createAlphaState();

      as.setBlendEnabled( true );

      as.setSrcFunction( AlphaState.SB_SRC_ALPHA );

      as.setDstFunction( AlphaState.DB_ONE_MINUS_SRC_ALPHA );

      as.setTestEnabled( true );

      as.setTestFunction( AlphaState.TF_GREATER );

       cursor.setRenderState( as );

   

      // Assign the mouse to an input handler

      cursor.registerWithInputHandler( input );

   

      rootNode.attachChild( cursor );

   

      // important for JMEDesktop: use system coordinates

      cursor.setUsingDelta( false );

      cursor.getXUpdateAction().setSpeed( 1 );

      cursor.getYUpdateAction().setSpeed( 1 );

   

      cursor.setCullMode( SceneElement.CULL_NEVER );

   }

}





      i cannot find the different between the method createCustomCursor() in TestJMEDesktop.java  and in this code.

Try attaching the mouse to the fpsNode. This might do the trick.

Yes, or attach it to your desktopNode. Essentially it has to be painted after the desktop and the rootNode is painted before simpleRender()

thanks.it is ok when i attach it to fpsnode.

imho attaching to the fps node is acceptable for test applications but it is actually a quick & dirty hack.

sfera said:

imho attaching to the fps node is acceptable for test applications but it is actually a quick & dirty hack.

I always feel that extending SimpleGame isn't more than a dirty hack. After all , I want to control what happens :D

yep, you are right there.

still, SimpleGame is excellent for writing quick test and showing engine features.

Nodwick, then use StandardGame instead. :slight_smile:

sfera said:
yep, you are right there.
still, SimpleGame is excellent for writing quick test and showing engine features.

True, but I wanted to point out, that both are dirty hacks, fitting together perfectly :D
darkfrog said:
Nodwick, then use StandardGame instead. :)

I actually use BaseGame.
But I'm a bit puzzled, because I couldn't find StandardGame in the Javadoc, neither in the CVS (but I only looked in the CVS tree /com/jme/app)  :?

StandardGame is in com.jmex.game

never used it…

Ah. I'm using .10, which means that I don't even have that package :wink:

I wrote StandardGame as a system to support both GameStates and multithreading.  I'm using it as the foundation for the game I'm working on currently and it's working amazingly well.  It should not need to be extended, simply instantiated and started.


StandardGame game = new StandardGame("My Game");
game.start();



Then you can simply create your GameStates, activate them, and add them to the GameStateManager and you're good to go.

There are also quite a few changes to the GameState system in CVS now if you're willing to update.
darkfrog said:
I wrote StandardGame as a system to support both GameStates and multithreading.  I'm using it as the foundation for the game I'm working on currently and it's working amazingly well.  It should not need to be extended, simply instantiated and started.

StandardGame game = new StandardGame("My Game");
game.start();


Then you can simply create your GameStates, activate them, and add them to the GameStateManager and you're good to go.
There are also quite a few changes to the GameState system in CVS now if you're willing to update.

This sounds really cool, and I'd be willing to update, but I have 2 issues with that:
* Jikes seems to hate it, but that might be solved by setting an option
* The current CVS version seems to hate my MouseMotionListener and not calling its mouseDragged(), making my nice moveable user interface unmoveable, which kinda sucks.

1.) Stop using jikes.  :stuck_out_tongue:



2.) If there's a problem with the most recent version of CVS with mouse dragging it won't get fixed unless someone is willing to help debug the problem. :wink:

I recently applied a patch from Galun that dealt with mouse event dispatching. Please check if your problem is solved by commenting out these two code blocks in JMEDesktop:


            // FIX ME: this is a workaround as we cannot access eventEnabled in JMEDesktop.dispatchEvent
            while ( comp != null && comp.getMouseListeners().length == 0 ) {
                comp = comp.getParent();
            }


       


            // FIX ME: this is a workaround as we cannot access eventEnabled in JMEDesktop.dispatchEvent
            while ( comp != null && comp.getMouseMotionListeners().length == 0 ) {
                comp = comp.getParent();
            }

darkfrog said:
It should not need to be extended, simply instantiated and started.

Well, you assumed wrong. I wanted to extend it, and thus created a subclass which unfortunately cannot read certain member variables because they're neither protected, nor do they have a getter. I had to change my local CVS copy of StandardGame.

Oh and you've got some bugs in your DebugGameState. First, in the update method you check for update and if it equals true then you return from the method. Doing it this way, once the pause is activated, the check for the key being pressed is never executed again. Place the toggle_pause command check at the start of the method to fix this. Another bug is how you handle the exit command, which is the escape key. If detected, you halt the entire application by calling System.exit. Doing this will skip all the shutdown related methods in StandardGame. Namely quit and cleanup. I guess you did this as a quick hack, since you don't seem to have a reference to the StandardGame in your GameStates.
Gaheris said:

Well, you assumed wrong. I wanted to extend it, and thus created a subclass which unfortunately cannot read certain member variables because they're neither protected, nor do they have a getter. I had to change my local CVS copy of StandardGame.


Why would you want to extend it?  What is it that you are trying to do with it that can't be done by simply instantiating it?

Gaheris said:

Oh and you've got some bugs in your DebugGameState. First, in the update method you check for update and if it equals true then you return from the method. Doing it this way, once the pause is activated, the check for the key being pressed is never executed again. Place the toggle_pause command check at the start of the method to fix this.


Oops, I'll try to make sure I get that fixed.  I never use pause myself, so I never actually tested that. :P

Gaheris said:
Another bug is how you handle the exit command, which is the escape key. If detected, you halt the entire application by calling System.exit. Doing this will skip all the shutdown related methods in StandardGame. Namely quit and cleanup. I guess you did this as a quick hack, since you don't seem to have a reference to the StandardGame in your GameStates.


Explain a better way for me to do this and I'll happily change it.  I don't add any explicit calls to StandardGame since it's possible that people using the GameStates might not be using StandardGame (I know, it's shocking).
darkfrog said:

Why would you want to extend it?  What is it that you are trying to do with it that can't be done by simply instantiating it?


I'm sure that for anyone actually developing a game there might not be any reason to extend the class, although I wouldn't say never. However that's not what I'm developing right now. I subclassed StandardGame to be able to add some debugger/oberserver/manager code in a non-API-breaking/changing and transparent (to the client) way. It's an example on how to use/implement it, as well as an easy way add some value for anyone using StandardGame.

darkfrog said:

Explain a better way for me to do this and I'll happily change it.  I don't add any explicit calls to StandardGame since it's possible that people using the GameStates might not be using StandardGame (I know, it's shocking).


I thought about that as I considered doing such a change to my local CVS copy, but I didn't really like any solutions that came to my mind. One would have to implement some sort of an event-handling or messaging code to the game states to which the StandardGame (or any other object implementing some special interface) can attach itself to.
Gaheris said:

I thought about that as I considered doing such a change to my local CVS copy, but I didn't really like any solutions that came to my mind. One would have to implement some sort of an event-handling or messaging code to the game states to which the StandardGame (or any other object implementing some special interface) can attach itself to.

Yes, using a SyntheticButton should work smoothly.
irrisor said:

I recently applied a patch from Galun that dealt with mouse event dispatching. Please check if your problem is solved by commenting out these two code blocks in JMEDesktop (...)

That makes the dragging work again, thanks :)