[Resolved]Implements my own FlyByCamera

Hello,

I have tried to delete some mapping of the FlyByCamera, after have readed this topic : http://hub.jmonkeyengine.org/groups/general-2/forum/topic/modify-flybycamera-without-recreating-it/ , for use the FlyByCamera without have to implement my custom version of it,

I write that on the simpleInitApp()



[java]inputManager.deleteMapping("FLYCAM_ZoomIn");

inputManager.deleteMapping("FLYCAM_ZoomOut");

inputManager.deleteMapping("FLYCAM_RotateDrag");

inputManager.deleteMapping("FLYCAM_Rise");

inputManager.deleteMapping("FLYCAM_Lower");[/java]



but that does not work, I try that :



[java]flyCam.registerWithInput(inputManager);



inputManager.deleteMapping("FLYCAM_ZoomIn");

inputManager.deleteMapping("FLYCAM_ZoomOut");

inputManager.deleteMapping("FLYCAM_RotateDrag");

inputManager.deleteMapping("FLYCAM_Rise");

inputManager.deleteMapping("FLYCAM_Lower");[/java]



but that does not work too, any idea ?



Tank you in advance



_________________________

Sorry for my bad english

Mostly people recommend using the provided cameras as starting point and then writing your own. The behaviour of the camera is something that’s very specific to each game.

1 Like

The fly cam mappings are not initialized until after simpleInit() has finished executing. The fly cam is initialized by its own separate app state now. You can create your own app state to replace that one if you still want to use the fly cam or you can create your own app state that just deletes the mappings.



…in the end you are probably better off just creating your camera.

1 Like

ok I do that,

tank you a lot

Sorry but I don’t know how you implements your own camera.



I have tried that :



My custom camera class :

[java]public class FCam extends FlyByCamera

{

private static String[] mappings = new String[]

{

“FLYCAM_Left”,

“FLYCAM_Right”,

“FLYCAM_Up”,

“FLYCAM_Down”,



“FLYCAM_StrafeLeft”,

“FLYCAM_StrafeRight”,

“FLYCAM_Forward”,

“FLYCAM_Backward”,

};



/**

  • Creates a new FCamera to control the given Camera object.

    *
  • @param cam
  • @since 0.0.1
  • @see FlyByCamera

    */

    public FCam(Camera cam)

    {

    super(cam);

    System.out.println("Création de FCam");

    }

    /**
  • Init inputs.

    *
  • @param inputManager
  • @since 0.0.1
  • @see FlyByCamera

    */

    public void registerWithInput(InputManager inputManager)

    {

    this.inputManager = inputManager;



    // both mouse and button - rotation of cam

    inputManager.addMapping("FLYCAM_Left", new MouseAxisTrigger(MouseInput.AXIS_X, true),

    new KeyTrigger(KeyInput.KEY_LEFT));



    inputManager.addMapping("FLYCAM_Right", new MouseAxisTrigger(MouseInput.AXIS_X, false),

    new KeyTrigger(KeyInput.KEY_RIGHT));



    inputManager.addMapping("FLYCAM_Up", new MouseAxisTrigger(MouseInput.AXIS_Y, false),

    new KeyTrigger(KeyInput.KEY_UP));



    inputManager.addMapping("FLYCAM_Down", new MouseAxisTrigger(MouseInput.AXIS_Y, true),

    new KeyTrigger(KeyInput.KEY_DOWN));



    // keyboard

    inputManager.addMapping("FLYCAM_StrafeLeft", new KeyTrigger(KeyInput.KEY_Q));

    inputManager.addMapping("FLYCAM_StrafeRight", new KeyTrigger(KeyInput.KEY_D));

    inputManager.addMapping("FLYCAM_Forward", new KeyTrigger(KeyInput.KEY_Z));

    inputManager.addMapping("FLYCAM_Backward", new KeyTrigger(KeyInput.KEY_S));



    inputManager.addListener(al, mappings);



    Joystick[] joysticks = inputManager.getJoysticks();

    if (joysticks != null && joysticks.length > 0)

    {

    Joystick joystick = joysticks[0];

    joystick.assignAxis("FLYCAM_StrafeRight", "FLYCAM_StrafeLeft", JoyInput.AXIS_POV_X);

    joystick.assignAxis("FLYCAM_Forward", "FLYCAM_Backward", JoyInput.AXIS_POV_Y);

    joystick.assignAxis("FLYCAM_Right", "FLYCAM_Left", joystick.getXAxisIndex());

    joystick.assignAxis("FLYCAM_Down", "FLYCAM_Up", joystick.getYAxisIndex());

    }



    }



    /**
  • Listen the input, define in <b>registerWithInput</b> method.

    *
  • @since 0.0.1

    */

    AnalogListener al = new AnalogListener()

    {

    public void onAnalog(String name, float value, float tpf)

    {

    if (!enabled)

    return;

    if (name.equals(“FLYCAM_Left”))

    {

    rotateCamera(value, initialUpVec);

    }

    else if (name.equals(“FLYCAM_Right”))

    {

    rotateCamera(-value, initialUpVec);

    }

    else if (name.equals(“FLYCAM_Up”))

    {

    rotateCamera(-value, cam.getLeft());

    }

    else if (name.equals(“FLYCAM_Down”))

    {

    rotateCamera(value, cam.getLeft());

    }

    else if (name.equals(“FLYCAM_Forward”))

    {

    moveCamera(value, false);

    }

    else if (name.equals(“FLYCAM_Backward”))

    {

    moveCamera(-value, false);

    }

    else if (name.equals(“FLYCAM_StrafeLeft”))

    {

    moveCamera(value, true);

    }

    else if (name.equals(“FLYCAM_StrafeRight”))

    {

    moveCamera(-value, true);

    }

    }

    };

    }[/java]



    In the main

    [java]flyCam.setEnabled(false);

    FCam fcam = new FCam(cam);

    fcam.setEnabled(true);

    fcam.registerWithInput(inputManager);

    inputManager.setCursorVisible(false);[/java]



    I am really sorry, but I don’t understand how to do that.

    I am really a noob.



    Tank in avance and sorry for my bad english.

And what happened?

@pspeed said:
The fly cam mappings are not initialized until after simpleInit() has finished executing. The fly cam is initialized by its own separate app state now.


Thats why calling getInputManager().setCursorVisible(false); in simple init() doesnt work.

Because evil flyCam "virus code" runs after init() meaning that no matter what you do ;
a) you either pollute your simpleUpdate() method with code that will only run once (first frame).
meaning your game is a resource hog (+1 command for no reason).
b) or you are forced to have a cursor, because evil flyCam just forced you.

If jme will remain with that design
why not add "postInit()" to solve the bugs flyCam causes ?

Here is the bug issue 527

Override the constructor for your simple app and supply your new flycam instead of the default one.



For example:

[java]

public Main() {

super(

new FCam(),

new StatsAppState(),

new DebugKeysAppState() );

}

[/java]

@zarch said:
Override the constructor for your simple app and supply your new flycam instead of the default one.

For example:
[java]
public Main() {
super(
new FCam(),
new StatsAppState(),
new DebugKeysAppState() );
}
[/java]


No, you'd have to have an app state there... not just a camera.
@tralala said:
Thats why calling getInputManager().setCursorVisible(false); in simple init() doesnt work.

Because evil flyCam "virus code" runs after init() meaning that no matter what you do ;
a) you either pollute your simpleUpdate() method with code that will only run once (first frame).
meaning your game is a resource hog (+1 command for no reason).
b) or you are forced to have a cursor, because evil flyCam just forced you.

If jme will remain with that design
why not add "postInit()" to solve the bugs flyCam causes ?

Here is the bug issue 527


Or... you put logic in an app state like you are supposed to...
you put logic in an app state like you are supposed to…

And then remove the appStat at frame 2, to avoid being a resource hog ?
@tralala said:
Thats why calling getInputManager().setCursorVisible(false); in simple init() doesnt work.

Because evil flyCam "virus code" runs after init() meaning that no matter what you do ;
a) you either pollute your simpleUpdate() method with code that will only run once (first frame).
meaning your game is a resource hog (+1 command for no reason).
b) or you are forced to have a cursor, because evil flyCam just forced you.


And actually, that whole thing is ridiculous since flyCam turns off the cursor by default.

From the bug report, you want your own camera… so why leave FlyCamAppState in at all? Just remove it like it was designed and go about your business.

To the original poster, if you want your own camera then first remove the existing one. Either use the constructor approach as indicated by zarch (but leave out the camera part)…

[java]

public Main() {

super(new StatsAppState(),

new DebugKeysAppState() );

}

[/java]



Or remove the FlyCamAppState in simpleInit():

[java]

public void simpleInitApp(){

stateManager.detach( stateManager.getState(FlyCamAppState.class) ) );

…do your own cam setup…

}

[/java]



Then your custom camera should work fine.



Alternately, if all you want to do is change the mappings you could subclass FlyCamAppState and override its initialize() method:

[java]

public void initialize(AppStateManager stateManager, Application app) {

super.initialize(stateManager, app);

…do your own mappings setup… For example if you just want to change the keys assigned to a given mapping then you can do that here…

}

[/java]



…then include it in the constructor call at top…



…at least in theory.

2 Likes

yeah, this works.



so that means that flyCam.setEnabled(false); should be replaced with

remove flyCam app state.



Here is the code that fixes the bug and works correctly:

[java]

flyCam.setEnabled(false);

if (FIX2)

{

stateManager.detach(stateManager.getState(FlyCamAppState.class));

}

getInputManager().setCursorVisible(false);

[/java]

1 Like
@tralala said:
yeah, this is another way to do this.

so that means that flyCam.setEnabled(false); should be replaced with
remove flyCam app state.

Here is the code that fixes the bug and works correctly:
[java]
flyCam.setEnabled(false);
if (FIX2)
{
stateManager.detach(stateManager.getState(FlyCamAppState.class));
}
getInputManager().setCursorVisible(false);
[/java]


That's why fly cam was moved into an app state in the first place. So many users were having to do 9 steps to disable it... and now you can just leave it out completely. Arguably, the super() constructor approach is easier and can even include your own app states in the list... but the stateManager.detach() approach is also clear.
@pspeed said:
No, you'd have to have an app state there... not just a camera.

Ahh, my bad. I thought FCam was a fly cam app state.

tank a lot,

I have decide to use the pspeed’s method because I like to be able to define a special behavior of my camera

tank again you have really help my,

the community of JME3 is great :wink: