I’m experimenting for a simple game here. What I want to do is this: show a floor with some blocks (maze) on it. The player sees the maze from above (e.g. looking down the Y axis) and the camera follows the movements across the x,z plane with a ChaseCamera.
Here’s what I have now:
The floor is shown in blue, the player in red.
I have a few questions:
- How can I get the camera in the right position? It already follows the player, but across the x,y-plane.
- The floor appears to be shaking - can this be caused by the AnalogListener I use?
My code:
[java]package nl.ariejan.plexor;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.nodes.PhysicsCharacterNode;
import com.jme3.bullet.nodes.PhysicsNode;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.control.CameraControl.ControlDirection;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
/**
- test
-
@author Ariejan de Vroom <ariejan@ariejan.nl>
/
public class Main extends SimpleApplication {
protected boolean isRunning = false;
private BulletAppState bulletAppState;
// 7x7 box
private int boxSize = 10;
private PhysicsNode map;
protected PhysicsCharacterNode player;
protected CameraNode playerCam;
public static void main(String[] args) {
// Default settings
AppSettings settings = new AppSettings(true);
settings.setFullscreen(false);
settings.setResolution(1280, 720);
settings.setTitle(“Plexor”);
Main app = new Main();
// Set settings, don’t show settings popup
app.setSettings(settings);
app.setShowSettings(false);
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
float middle = boxSize / 2.0f;
// Create map
Node mapNode = new Node();
Box floor = new Box(Vector3f.ZERO, 10f, 1f, 10f);
Geometry floorGeo = new Geometry(“Floor”, floor);
floorGeo.updateModelBound();
Material floorMat = new Material(assetManager, “Common/MatDefs/Misc/WireColor.j3md”);
floorMat.setColor(“m_Color”, ColorRGBA.Blue);
floorGeo.setMaterial(floorMat);
mapNode.attachChild(floorGeo);
// Border boxes
// for (float z = 0; z < boxSize; z += 1.0f) {
// for (float x = 0; x < boxSize; x += 1.0f) {
// if ((z == 0 || z == boxSize-1) || (x == 0 || x == boxSize-1)) {
// // Create a 1x1x1 Box
// Box b = new Box(new Vector3f(x, 1.0f, z), 0.5f, 0.5f, 0.5f);
// Geometry geo = new Geometry(“Box”, b);
// geo.updateModelBound();
//
// // Material mat = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);
// Material mat = new Material(assetManager, “Common/MatDefs/Misc/SimpleTextured.j3md”);
// // mat.setColor(“m_Color”, ColorRGBA.Blue);
// mat.setTexture(“m_ColorMap”, assetManager.loadTexture(“Interface/Logo/Monkey.png”));
// geo.setMaterial(mat);
// mapNode.attachChild(geo);
// }
// }
// }
// CompoundCollisionShape mapShape =
// CollisionShapeFactory.createBoxCompoundShape(mapNode);
BoxCollisionShape mapShape = new BoxCollisionShape(new Vector3f(10f, 1f, 10f));
map = new PhysicsNode(mapNode, mapShape, 0);
// Add light!
// DirectionalLight light = new DirectionalLight();
// light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
// light.setColor(ColorRGBA.White.clone());
// rootNode.addLight(light);
// Add the player
Box b = new Box(new Vector3f(0, 0, 0), 0.5f, 0.5f, 0.5f);
Geometry geo = new Geometry(“Player”, b);
geo.updateModelBound();
Material mat = new Material(assetManager, “Common/MatDefs/Misc/WireColor.j3md”);
mat.setColor(“m_Color”, ColorRGBA.Red);
geo.setMaterial(mat);
player = new PhysicsCharacterNode(new CapsuleCollisionShape(1.5f, 0.6f, 1), .05f);
player.setLocalTranslation(0, 5, 0);
player.attachChild(geo);
player.setJumpSpeed(20);
player.setFallSpeed(30);
player.setGravity(30);
// Set camera
flyCam.setEnabled(false);
playerCam = new CameraNode(cam);
playerCam.setControlDir(ControlDirection.SpatialToCamera);
playerCam.setLocalTranslation(0, 10, -50);
player.attachChild(playerCam);
rootNode.attachChild(map);
rootNode.attachChild(player);
bulletAppState.getPhysicsSpace().add(map);
bulletAppState.getPhysicsSpace().add(player);
setupKeys();
isRunning = true;
}
private void setupKeys() {
inputManager.addMapping(“Lefts”, new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping(“Rights”, new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping(“Ups”, new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping(“Downs”, new KeyTrigger(KeyInput.KEY_S));
inputManager.addListener(analogListener, new String[]{ “Lefts”, “Rights”, “Ups”, “Downs” });
}
private AnalogListener analogListener = new AnalogListener() {
public void onAnalog(String name, float value, float tpf) {
if (isRunning) {
if (name.equals(“Rights”)) {
Vector3f v = player.getLocalTranslation();
player.setLocalTranslation(v.x - value4speed, v.y, v.z);
}
if (name.equals(“Lefts”)) {
Vector3f v = player.getLocalTranslation();
player.setLocalTranslation(v.x + value4speed, v.y, v.z);
}
if (name.equals(“Ups”)) {
Vector3f v = player.getLocalTranslation();
player.setLocalTranslation(v.x, v.y + value4speed, v.z);
}
if (name.equals(“Downs”)) {
Vector3f v = player.getLocalTranslation();
player.setLocalTranslation(v.x, v.y - value4*speed, v.z);
}
}
}
};
@Override
public void simpleUpdate(float tpf) {
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
[/java]