Hello,
i was wondering if there was any support for AZERTY (and eventually QWERTZ) keyboard with jME?
(beside rebinding every key everytime 'by hand' in jme' sources or in our main)
:?
Thanx in advance
Nothing that I know of, but this is an interesting thing to look at since I had a co-worker using french keyboards who used to get quite frustrated with the keybindings.
Using Locale.getDefault() you can find the OS' set country and automatically re-bind from there. I'll have a look at integrating this into the jME2 sources as this is a great usability thing, but it would only be for the built in control handlers such as FirstPersonHandler. Are you using jME2 or 3?
P.S: nice name
Yeah WSAD binding is hell for AZERTY keyboards!!!
I think Kirill is planning to add a "save/load key mapping to a config file" feature to JME3, so you could easily load the correct binding for your keyboard.
If you're using KeyboardLookHandler with jME2, then you can use this function to detect and change the assignment of keys
private void adjustPerLocale(){
KeyBindingManager keyBindingManager = KeyBindingManager.getKeyBindingManager();
Locale locale = Locale.getDefault();
if(locale.equals(Locale.FRANCE) || locale.equals(Locale.FRENCH)){
keyBindingManager.set("forward", KeyInput.KEY_Z);
keyBindingManager.set("backward", KeyInput.KEY_S);
keyBindingManager.set("strafeLeft", KeyInput.KEY_Q);
keyBindingManager.set("strafeRight", KeyInput.KEY_D);
keyBindingManager.set( "elevateUp", KeyInput.KEY_A);
keyBindingManager.set( "elevateDown", KeyInput.KEY_W);
}
else if(locale.equals(Locale.GERMANY) || locale.equals(Locale.GERMAN)){
keyBindingManager.set("forward", KeyInput.KEY_Z);
keyBindingManager.set("backward", KeyInput.KEY_S);
keyBindingManager.set("strafeLeft", KeyInput.KEY_A);
keyBindingManager.set("strafeRight", KeyInput.KEY_D);
keyBindingManager.set( "elevateUp", KeyInput.KEY_Q);
keyBindingManager.set( "elevateDown", KeyInput.KEY_Y);
}
}
Thanx sbook,
that was what i was doing in jme2.
But i hoped jme3 might change the keyboard handling or that u could still do that in the jmonleyplatform^^
Honestly, i starting to get sick already of that localization/keyboard setting (i'll try eclispe with sources, might be better than the jmonkeyplatform)^^
Ill keep u informed
I created a new java project with jme3 sources, it works fine and i can change keymapping like in jme2.
Too bad i can't use the jmonkeyplatform
fckregistration said:
I created a new java project with jme3 sources, it works fine and i can change keymapping like in jme2.
Too bad i can't use the jmonkeyplatform :/
I dont understand? Whats your problem with jMP? How is setting the keybindings for a jme3 game different in eclipse than in jMP?
normen said:
fckregistration said:
I created a new java project with jme3 sources, it works fine and i can change keymapping like in jme2.
Too bad i can't use the jmonkeyplatform :/
I dont understand? Whats your problem with jMP? How is setting the keybindings for a jme3 game different in eclipse than in jMP?
Because i downloaded the win32 exe installer for jmp.
It offers with some demo codes that i wanted to run+edit.
But since the sources/classes (for input handlers) in the package jm3 are in an jar, u can't modify them.
That's no big deal because i don't really need another IDE for java^^
(i will not/never use netbean IDE)
fckregistration said:
Because i downloaded the win32 exe installer for jmp.
It offers with some demo codes that i wanted to run+edit.
But since the sources/classes (for input handlers) in the package jm3 are in an jar, u can't modify them.
That's no big deal because i don't really need another IDE for java^^
(i will not/never use netbean IDE)
Lol. For eclipse fanboys there will be asset-only projects in jMP at some point, so you can code in your beloved IDE and use jMP for handling assets etc.
normen said:
fckregistration said:
Because i downloaded the win32 exe installer for jmp.
It offers with some demo codes that i wanted to run+edit.
But since the sources/classes (for input handlers) in the package jm3 are in an jar, u can't modify them.
That's no big deal because i don't really need another IDE for java^^
(i will not/never use netbean IDE)
Lol. For eclipse fanboys there will be asset-only projects in jMP at some point, so you can code in your beloved IDE and use jMP for handling assets etc.
i ain't an eclipse fanboys (if u could ask my friends, u'd know that i said many bad things about eclipse^^)...
it is just i have already an IDE and i don't want another one (even if it is only for handling some part i can't in my regular IDE).
fckregistration said:
i ain't an eclipse fanboys (if u could ask my friends, u'd know that i said many bad things about eclipse^^)...
it is just i have already an IDE and i don't want another one (even if it is only for handling some part i can't in my regular IDE).
Hm, ok. I rather use an IDE that is made for the environment I am working in. For javacard software I use an Eclipse IDE that is adapted for that purpose, for coding on MacOSX I use XCode, for Java software I use NetBeans and for PHP software I use another (older) install of NetBeans. Writing all config files etc. by hand just to stick to a certain IDE just does not make much sense to me :)
Cheers,
Normen
normen said:
fckregistration said:
i ain't an eclipse fanboys (if u could ask my friends, u'd know that i said many bad things about eclipse^^)...
it is just i have already an IDE and i don't want another one (even if it is only for handling some part i can't in my regular IDE).
Hm, ok. I rather use an IDE that is made for the environment I am working in. For javacard software I use an Eclipse IDE that is adapted for that purpose, for coding on MacOSX I use XCode, for Java software I use NetBeans and for PHP software I use another (older) install of NetBeans. Writing all config files etc. by hand just to stick to a certain IDE just does not make much sense to me :)
Cheers,
Normen
Well, i think it is less messy and easier to have a single IDE for everything.
Thanx for the answers
fckregistration said:
Well, i think it is less messy and easier to have a single IDE for everything.
Thanx for the answers
As a self-proclaimed Eclipse fanboy (its unhealthy, Normen hates me for it, etc), NetBeans' PHP support makes Eclipse feel like a joke :)
fckregistration said:
Thanx sbook,
that was what i was doing in jme2.
Perhaps its time that this made it into the constructor up there in the codebase.. I'll set up a contribution
I had the same problem for classes extending com.jme3.app.SimpleApplication, it can be solved easily by:
-
implementing an azerty FlyByCamera based on the qwerty implementation from jme3
-
adding a couple of lines at the begin of simpleInitApp() method (to detach the FlyCamAppState and register the azerty FlyByCamera)
-
mygame.AZERTYFlyByCamera:
[java]
/*
- Copyright © 2009-2010 jMonkeyEngine
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- Neither the name of âjMonkeyEngineâ nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- âAS ISâ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package mygame;
import com.jme3.collision.MotionAllowedListener;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
/**
-
A first person view camera controller.
-
After creation, you must register the camera controller with the
-
dispatcher using #registerWithDispatcher().
-
Controls:
-
- Move the mouse to rotate the camera
-
- Mouse wheel for zooming in or out
-
- WASD keys for moving forward/backward and strafing
-
- QZ keys raise or lower the camera
*/
public class AZERTYFlyByCamera implements AnalogListener, ActionListener {
private Camera cam;
private Vector3f initialUpVec;
private float rotationSpeed = 1f;
private float moveSpeed = 3f;
private MotionAllowedListener motionAllowed = null;
private boolean enabled = true;
private boolean dragToRotate = false;
private boolean canRotate = false;
private InputManager inputManager;/**
- Creates a new FlyByCamera to control the given Camera object.
-
@param cam
*/
public AZERTYFlyByCamera(Camera cam){
this.cam = cam;
initialUpVec = cam.getUp().clone();
}
public void setMotionAllowedListener(MotionAllowedListener listener){
this.motionAllowed = listener;
}/**
- Sets the move speed. The speed is given in world units per second.
-
@param moveSpeed
*/
public void setMoveSpeed(float moveSpeed){
this.moveSpeed = moveSpeed;
}
/**
- Sets the rotation speed.
-
@param rotationSpeed
*/
public void setRotationSpeed(float rotationSpeed){
this.rotationSpeed = rotationSpeed;
}
/**
-
@param enable If false, the camera will ignore input.
*/
public void setEnabled(boolean enable){
enabled = enable;
}
/**
- @return If enabled
-
@see FlyByCamera#setEnabled(boolean)
*/
public boolean isEnabled(){
return enabled;
}
/**
- @return If drag to rotate feature is enabled.
-
@see FlyByCamera#setDragToRotate(boolean)
*/
public boolean isDragToRotate() {
return dragToRotate;
}
/**
- @param dragToRotate When true, the user must hold the mouse button
- and drag over the screen to rotate the camera, and the cursor is
- visible until dragged. Otherwise, the cursor is invisible at all times
- and holding the mouse button is not needed to rotate the camera.
- This feature is disabled by default.
*/
public void setDragToRotate(boolean dragToRotate) {
this.dragToRotate = dragToRotate;
inputManager.setCursorVisible(dragToRotate);
}
/**
- Registers the FlyByCamera to recieve input events from the provided
- Dispatcher.
-
@param dispacher
*/
public void registerWithInput(InputManager inputManager){
this.inputManager = inputManager;
- QZ keys raise or lower the camera
// inputManager.registerJoystickAxisBinding(âFLYCAM_Leftâ, 2, JoyInput.AXIS_X, true);
// inputManager.registerJoystickAxisBinding(âFLYCAM_Rightâ, 2, JoyInput.AXIS_X, false);
// inputManager.registerJoystickAxisBinding(âFLYCAM_Upâ, 2, JoyInput.AXIS_Y, true);
// inputManager.registerJoystickAxisBinding(âFLYCAM_Downâ, 2, JoyInput.AXIS_Y, false);
//
// inputManager.registerJoystickAxisBinding(âFLYCAM_StrafeLeftâ, 2, JoyInput.POV_X, true);
// inputManager.registerJoystickAxisBinding(âFLYCAM_StrafeRightâ, 2, JoyInput.POV_X, false);
// inputManager.registerJoystickAxisBinding(âFLYCAM_Forwardâ, 2, JoyInput.POV_Y, true);
// inputManager.registerJoystickAxisBinding(âFLYCAM_Backwardâ, 2, JoyInput.POV_Y, false);
String[] mappings = new String[]{
"FLYCAM_Left",
"FLYCAM_Right",
"FLYCAM_Up",
"FLYCAM_Down",
"FLYCAM_StrafeLeft",
"FLYCAM_StrafeRight",
"FLYCAM_Forward",
"FLYCAM_Backward",
"FLYCAM_ZoomIn",
"FLYCAM_ZoomOut",
"FLYCAM_RotateDrag",
"FLYCAM_Rise",
"FLYCAM_Lower"
};
// both mouse and button - rotation of cam
inputManager.addMapping("FLYCAM_Left", new MouseAxisTrigger(0, true),
new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("FLYCAM_Right", new MouseAxisTrigger(0, false),
new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("FLYCAM_Up", new MouseAxisTrigger(1, false),
new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("FLYCAM_Down", new MouseAxisTrigger(1, true),
new KeyTrigger(KeyInput.KEY_DOWN));
// mouse only - zoom in/out with wheel, and rotate drag
inputManager.addMapping("FLYCAM_ZoomIn", new MouseAxisTrigger(2, false));
inputManager.addMapping("FLYCAM_ZoomOut", new MouseAxisTrigger(2, true));
inputManager.addMapping("FLYCAM_RotateDrag", new MouseButtonTrigger(0));
// keyboard only ZQSD for movement and WZ for rise/lower height
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.addMapping("FLYCAM_Rise", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("FLYCAM_Lower", new KeyTrigger(KeyInput.KEY_W));
inputManager.addListener(this, mappings);
inputManager.setCursorVisible(dragToRotate);
}
private void rotateCamera(float value, Vector3f axis){
if (dragToRotate){
if (canRotate){
// value = -value;
}else{
return;
}
}
Matrix3f mat = new Matrix3f();
mat.fromAngleNormalAxis(rotationSpeed * value, axis);
Vector3f up = cam.getUp();
Vector3f left = cam.getLeft();
Vector3f dir = cam.getDirection();
mat.mult(up, up);
mat.mult(left, left);
mat.mult(dir, dir);
Quaternion q = new Quaternion();
q.fromAxes(left, up, dir);
//q.normalize();
q.normalizeLocal();
cam.setAxes(q);
}
private void zoomCamera(float value){
// derive fovY value
float h = cam.getFrustumTop();
float w = cam.getFrustumRight();
float aspect = w / h;
float near = cam.getFrustumNear();
float fovY = FastMath.atan(h / near)
/ (FastMath.DEG_TO_RAD * .5f);
fovY += value * 0.1f;
h = FastMath.tan( fovY * FastMath.DEG_TO_RAD * .5f) * near;
w = h * aspect;
cam.setFrustumTop(h);
cam.setFrustumBottom(-h);
cam.setFrustumLeft(-w);
cam.setFrustumRight(w);
}
private void riseCamera(float value){
Vector3f vel = new Vector3f(0, value * moveSpeed, 0);
Vector3f pos = cam.getLocation().clone();
if (motionAllowed != null)
motionAllowed.checkMotionAllowed(pos, vel);
else
pos.addLocal(vel);
cam.setLocation(pos);
}
private void moveCamera(float value, boolean sideways){
Vector3f vel = new Vector3f();
Vector3f pos = cam.getLocation().clone();
if (sideways){
cam.getLeft(vel);
}else{
cam.getDirection(vel);
}
vel.multLocal(value * moveSpeed);
if (motionAllowed != null)
motionAllowed.checkMotionAllowed(pos, vel);
else
pos.addLocal(vel);
cam.setLocation(pos);
}
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);
}else if (name.equals("FLYCAM_Rise")){
riseCamera(value);
}else if (name.equals("FLYCAM_Lower")){
riseCamera(-value);
}else if (name.equals("FLYCAM_ZoomIn")){
zoomCamera(value);
}else if (name.equals("FLYCAM_ZoomOut")){
zoomCamera(-value);
}
}
public void onAction(String name, boolean value, float tpf) {
if (!enabled)
return;
if (name.equals("FLYCAM_RotateDrag") && dragToRotate){
canRotate = value;
inputManager.setCursorVisible(!value);
}
}
}
[/java]
- mygame.Main:
[java]
/*
- Copyright © 2009-2010 jMonkeyEngine
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- Neither the name of âjMonkeyEngineâ nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- âAS ISâ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package mygame;
import com.jme3.app.FlyCamAppState;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
/**
-
test
-
@author normenhansen
*/
public class Main extends SimpleApplication {public static void main(String[] args) {
Main app = new Main();
app.start();}
@Override
public void simpleInitApp() {//Here are the couple of lines!
stateManager.detach( stateManager.getState( FlyCamAppState.class ) );
new AZERTYFlyByCamera(cam).registerWithInput(inputManager);
//Box b = new Box(1, 1, 1); Geometry geom = new Geometry("Box", b); Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); mat.setColor("Color", ColorRGBA.Blue); geom.setMaterial(mat); rootNode.attachChild(geom);
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
[/java]
Lol i wasnât sure till now but it seems i was the one posting the problem^.^
And i changed my mind⊠separate IDEâs is a good idea^.^