Hey,
I want to implement an elementary physics that manage collision between movable object and player and also between everything and the map.
To achieve that, I must use env3d.Env
based application because it’s a requirement for this exercise.
But for no, the problem is that sometime when I move my character it just disappears under the room.
So actually, I have 3 classes, one for the movable object (letter) another for the player character and another for the room. Finally, I have my 3denv class that run everything
So, here is the character class :
public class Tux implements ActionListener {
private Jeu context;
private CharacterControl tux;
private Spatial tuxModel;
private boolean left = false, right = false, up = false, down = false, lastLeft = false, lastRight = false, lastUp = false, lastDown = false;
private Vector3f walkDirection = new Vector3f();
private Vector3f tempDirVector = new Vector3f();
private Vector3f tempRotateVector = new Vector3f();
public Tux(Jeu context) {
this.context = context;
setUpKeys();
Spatial tuxModel = assetManager.loadModel("models/tux/tux.obj");
Material mat_tux = new Material(
assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat_tux.setTexture("ColorMap",assetManager.loadTexture("models/tux/tux.png"));
tuxModel.setMaterial(mat_tux);
tuxModel.setLocalScale(1.5f);
tuxModel.setLocalTranslation(0, 10, 0);
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(tuxModel.getLocalScale().getX(), tuxModel.getLocalScale().length(), 1);
tux = new CharacterControl(capsuleShape, 5);
tux.setJumpSpeed(10);
tux.setFallSpeed(10);
tuxModel.addControl(tux);
context.getRootNode().attachChild(tuxModel);
context.getBulletAppState().getPhysicsSpace().add(tux);
tux.setGravity(10);
}
private void setUpKeys() {
context.getInputManager().addMapping("Left", new KeyTrigger(KeyInput.KEY_Q));
//Lot of key register
context.getInputManager().addListener(this, "Jump");
}
@Override
public void onAction(String binding, boolean isPressed, float tpf) {
//Juste move the position of my tux
}
//some other methode for movements
}
Here is the room
public class Room {
private Spatial floor;
private Spatial wallNorth;
private Spatial wallEast;
private Spatial wallSouth;
private Spatial wallWest;
private int depth = 200;
private int height = 200;
private int width = 200;
public Room(Jeu context, int width, int depth, int height,String textureBottom, String textureNorth, String textureEast, String textureSouth,String textureWest) {
//Defined room size
this.width = width;
this.depth = depth;
this.height = height;
//Floor init
Box boxFloor = new Box(Vector3f.ZERO,width, 10, depth);
floor = new Geometry("Floor", boxFloor);
floor.setLocalTranslation(0, -boxFloor.yExtent, 0);
floor.setMaterial(generateMaterial(textureBottom));
CollisionShape sceneShapeFloor = CollisionShapeFactory.createMeshShape(floor);
floor.addControl(new RigidBodyControl(sceneShapeFloor, 0));
context.getRootNode().attachChild(floor);
context.getBulletAppState().getPhysicsSpace().add(floor);
//definition des murs
Box boxNS = new Box(width, height, 10);
Box boxEW = new Box(1, height, width);
wallNorth = new Geometry("WallNorth", boxNS);
wallNorth.setLocalTranslation(0, height, -depth);
wallNorth.setMaterial(generateMaterial(textureNorth));
CollisionShape sceneShapeNorth = CollisionShapeFactory.createMeshShape(wallNorth);
wallNorth.addControl(new RigidBodyControl(sceneShapeNorth, 0));
context.getRootNode().attachChild(wallNorth);
context.getBulletAppState().getPhysicsSpace().add(wallNorth);
//Same with littel variation for other walls
}
private Material generateMaterial(String texture) {
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap",assetManager.loadTexture(texture));
return material;
}
}
My movable cube object
public class Letter {
private char letter;
private Spatial cube;
public Letter(Jeu context, char l, float x, float z){
this.letter = l;
cube = assetManager.loadModel("models/cube/cube.obj");
Material mat_cube = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
if(l>='a'&& l<='z')
mat_cube.setTexture("ColorMap",assetManager.loadTexture("/models/letter/"+l+".png"));
else
mat_cube.setTexture("ColorMap",assetManager.loadTexture("/models/cube/cube.png"));
cube.setMaterial(mat_cube);
cube.setLocalTranslation(x,40,z);
RigidBodyControl cubeBody = new RigidBodyControl( 0.02f);
cube.setLocalScale(2f,2f,2f);
cube.addControl(cubeBody);
context.getRootNode().attachChild(cube);
context.getBulletAppState().getPhysicsSpace().add(cubeBody);
}
and now the env3D class
public abstract class Jeu extends Env{
private BulletAppState bulletAppState;
private Room room;
private Profil profil;
private Tux tux;
protected float speed = 1f;
protected boolean paused = false;
public Jeu() {
this.rootNode.detachAllChildren();
//init physics
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//Cam settings
setCameraXYZ(50, 30, 150);
setCameraPitch(-45);
setResolution(1920, 1080,32);
setDisplayStr(ge[0].getIDstring());
}
//Juste generate some cubes with they constructor
private void loadWord(){
String word = dico.getMotDepuisListeNiveau(4);
int x = 10;
for(char c : normalize(word.toLowerCase()).toCharArray()){
lettres.add(new Letter(this,c,x,50));
x=x+10;
}
}
public void joue(Partie partie) {
// Init physics
bulletAppState.startPhysics();
//load room
room = new Room(this,200,200,200,"/textures/stone_granite.png","/textures/stonebrick.png","/textures/stonebrick.png","/textures/stonebrick.png","/textures/stonebrick.png");
//Load character
tux = new Tux(this);
//To load cubes
loadWord();
// Game loop
Boolean finished;
finished = false;
while (!finished) {
super.update();
if (speed != 0 || !paused) {
float tpf = timer.getTimePerFrame() * speed;
// update states
stateManager.update(tpf);
//Where call update environement
tux.simpleUpdate();
//Node updates
bulletAppState.update(tpf);
rootNode.updateLogicalState(tpf);
guiNode.updateLogicalState(tpf);
rootNode.updateGeometricState();
guiNode.updateGeometricState();
// render states
stateManager.render(renderManager);
renderManager.render(tpf, context.isRenderable());
stateManager.postRender();
}
if (getKey() == 1) {
finished = true;
}
//cal next frame
advanceOneFrame();
}
}
}
So If you have any idea from where my error could come, that will be very helpful.