Movement

I was following HelloCollision tutorial. I created my project and implemented it. It is a platform game and in the update loop I set the z-position to 0 so that the player doesn’t fall off. It works well, however I noticed that whenever I push both the left and right keys, the camera starts vibrating violently and the player loses its z-position and falls down. What should I do?

I wouldn’t suggest doing a 2d platform game using the same style as HelloCollision. I would suggest you move the character with the left/right keys and the camera just follows it:



[java]

public void simpleUpdate(float tpf) {

cam.setLocation( new Vector3f(spatial.getWorldTranslation().getX(), spatial.getWorldTranslation().getY(), 10);

cam.lookAt(new Vector3f(spatial.getWorldTranslation()), new Vector3f(0,1,0));

spatial.getLocalTranslation().multLocal(new Vector3f(1,1,0)); //keep him on Z axis

}[/java]

Will try that tonight, thanks :slight_smile: I think the problem was that I tried converting a first-person into a third-person.

Now the character doesn’t collide with the walls I made. Beforehand, the character used to stop, but now I can walk right through vertical walls. Any help?

When I tried reducing the speed, the character stops walking through walls, but the speed has to be very low. The following is the code I am using to move to the right. Variable pos is the position of the player:

[java]player.setPhysicsLocation(new Vector3f(pos.x+0.5f, pos.y, 0));[/java]

you should be multiplying your increment value (0.5f), by the frame independent value, think its called “float value” in the docs. Dunno if it helps tho, but maybe

@wezrule, couldn’t find it. The following is my program. Would appreciate any help because I don’t know what to do :frowning:

[java]package Platform;

import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;

import com.jme3.bullet.collision.shapes.CollisionShape;

import com.jme3.bullet.control.CharacterControl;

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.bullet.util.CollisionShapeFactory;

import com.jme3.input.ChaseCamera;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.light.AmbientLight;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;

public class Main extends SimpleApplication

implements ActionListener {

private Geometry green;

private BulletAppState bulletAppState;

private RigidBodyControl f;

private CharacterControl player;

private boolean bind = false;

private Vector3f walkDirection = new Vector3f();

private boolean left = false, right = false, up = false, down = false;

public static void main(String[] args) {

AppSettings settings=new AppSettings(true);

settings.put(“Width”, 640);

settings.put(“Height”, 480);

settings.put(“Title”, “Platform”);

settings.put(“VSync”, true);

settings.put(“Samples”, 4);

Main app = new Main();

app.setSettings(settings);

app.setShowSettings(false);

app.start();

}

public void simpleInitApp(){

viewPort.setBackgroundColor(new ColorRGBA(0.7f,0.8f,1f,1f));

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

flyCam.setEnabled(false);

setUpKeys();

CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1f, 0f, 1);

player = new CharacterControl(capsuleShape, 0.05f);

player.setJumpSpeed(20);

player.setFallSpeed(30);

player.setGravity(30);

player.setPhysicsLocation(new Vector3f(2, 10, 0));

Box box2 = new Box( new Vector3f(0,0,0), 1,1,1);

green = new Geometry(“Box”, box2);

Material mat2 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat2.setColor(“Color”, ColorRGBA.Green);

green.setMaterial(assetManager.loadMaterial( “Materials/Ground.j3m”));

rootNode.attachChild(green);

bulletAppState.getPhysicsSpace().add(player);

SimpleLevel l = new SimpleLevel();

int block;

block = l.blocknumber;

for (int i = 1; i < block; i++){

l.geom.setMaterial(assetManager.loadMaterial( “Materials/Ground.j3m”));

CollisionShape sceneShape2 = CollisionShapeFactory.createMeshShape(l.geom);

f = new RigidBodyControl(sceneShape2, 0);

l.geom.addControl(f);

System.out.println(l.geom.getLocalTranslation());

rootNode.attachChild(l.geom);

bulletAppState.getPhysicsSpace().add(f);

bulletAppState.getPhysicsSpace().add(player);

}

DirectionalLight light = new DirectionalLight();

light.setDirection( new Vector3f( -1f, -1f, -1f));

light.setColor(ColorRGBA.White.mult(0.5f));

rootNode.addLight( light );

AmbientLight amb = new AmbientLight();

amb.setColor(ColorRGBA.White.mult(1f));

rootNode.addLight(amb);

}

private void setUpKeys() {

inputManager.addMapping(“Lefts”, new KeyTrigger(KeyInput.KEY_A));

inputManager.addMapping(“Rights”, new KeyTrigger(KeyInput.KEY_D));

inputManager.addMapping(“Jumps”, new KeyTrigger(KeyInput.KEY_SPACE));

inputManager.addListener(this, “Lefts”);

inputManager.addListener(this, “Rights”);

inputManager.addListener(this, “Jumps”);

}

public void onAction(String binding, boolean value, float tpf) {

if (binding.equals(“Lefts”)) {

left = value;

} else if (binding.equals(“Rights”)) {

right = value;

} else if (binding.equals(“Jumps”)){

player.jump();

}

}

@Override

public void simpleUpdate(float tpf) {

Vector3f pos = new Vector3f(player.getPhysicsLocation());

ChaseCamera bluechase = new ChaseCamera(cam, green);

bluechase.setDefaultHorizontalRotation(1.565f);

bluechase.setLookAtOffset(new Vector3f(0, 0, 0));

bluechase.setChasingSensitivity(0f);

green.addControl(bluechase);

green.setLocalTranslation(player.getPhysicsLocation());

float v = 0.5f;

if (left) {

player.setPhysicsLocation(new Vector3f(pos.x-v, pos.y, 0));

}

if (right) {

player.setPhysicsLocation(new Vector3f(pos.x+v, pos.y, 0));

}

}

}[/java]

do 0.5f * tpf

  1. The speed is way too slow.
  2. If I increase it, the same thing happens, the character walks through walls.

k well from quickly glancing through your code, your capsuleCollisionShape doesn’t have a height? and do bulletAppState.getPhysicsSpace().enableDebug(true); so you can see your collisionshapes

hmm… There is no collision shape visible on the screen :confused: Note that the player doesn’t fall through ground.

Ok on further inspection i find even more things: You don’t attach the CharacterControl (player) to a spatial, and also you call bulletAppState.getPhysicsSpace().add(player); for every block added, it’s only need once. You need to look through your code more carefully, there’s a lot of things which can attribute to the given behaviour.

player isn’t a spatial. I don’t use spatials in this one, only Geometries (box), Also, I only callulletAppState.getPhysicsSpace().add(player); once…

Will continue working on it tomorrow. If you find the problem, please tell me.

ok you don’t need to attatch the characterControl to a spatial, but:


memonick said:
I don't use spatials in this one, only Geometries (box),


A geometry is a spatial

memonick said:
Also, I only callulletAppState.getPhysicsSpace().add(player); once...


oh rly?

for (int i = 1; i < block; i++){
l.geom.setMaterial(assetManager.loadMaterial( "Materials/Ground.j3m"));
CollisionShape sceneShape2 = CollisionShapeFactory.createMeshShape(l.geom);
f = new RigidBodyControl(sceneShape2, 0);
l.geom.addControl(f);
System.out.println(l.geom.getLocalTranslation());
rootNode.attachChild(l.geom);
bulletAppState.getPhysicsSpace().add(f);
bulletAppState.getPhysicsSpace().add(player);
}

@wezrule, sorry, I didn’t realize I was showing you an old piece of code. I updated it. Sorry.

What do I need to change from the below code? I really don’t understand what you mean about not attaching spatials to character controls. The geometries (except green) are the boxes I want to add as ground.

[java]

package Platform;

import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;

import com.jme3.bullet.collision.shapes.CollisionShape;

import com.jme3.bullet.control.CharacterControl;

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.bullet.util.CollisionShapeFactory;

import com.jme3.input.ChaseCamera;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.light.AmbientLight;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;

public class Main extends SimpleApplication

implements ActionListener {

private Geometry green;

private BulletAppState bulletAppState;

private RigidBodyControl f;

private CharacterControl player;

private boolean bind = false;

private Vector3f walkDirection = new Vector3f();

private boolean left = false, right = false, up = false, down = false;

public static void main(String[] args) {

AppSettings settings=new AppSettings(true);

settings.put(“Width”, 640);

settings.put(“Height”, 480);

settings.put(“Title”, “Platform”);

settings.put(“VSync”, true);

settings.put(“Samples”, 4);

Main app = new Main();

app.setSettings(settings);

app.setShowSettings(false);

app.start();

}

public void simpleInitApp(){

viewPort.setBackgroundColor(new ColorRGBA(0.7f,0.8f,1f,1f));

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

flyCam.setEnabled(false);

setUpKeys();

CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1f, 1f, 1);

player = new CharacterControl(capsuleShape, 0.05f);

player.setJumpSpeed(20);

player.setFallSpeed(30);

player.setGravity(30);

player.setPhysicsLocation(new Vector3f(2, 10, 0));

Box box2 = new Box( new Vector3f(0,0,0), 1f,1f,1f);

green = new Geometry(“Box”, box2);

Material mat2 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat2.setColor(“Color”, ColorRGBA.Green);

green.setMaterial(assetManager.loadMaterial( “Materials/Ground.j3m”));

rootNode.attachChild(green);

bulletAppState.getPhysicsSpace().add(player);

bulletAppState.getPhysicsSpace().enableDebug(assetManager);

SimpleLevel l = new SimpleLevel();

int block;

block = l.blocknumber;

for (int i = 1; i < block; i++){

l.geom.setMaterial(assetManager.loadMaterial( “Materials/Ground.j3m”));

CollisionShape sceneShape2 = CollisionShapeFactory.createMeshShape(l.geom);

f = new RigidBodyControl(sceneShape2, 0);

l.geom.addControl(f);

System.out.println(l.geom.getLocalTranslation());

rootNode.attachChild(l.geom);

bulletAppState.getPhysicsSpace().add(f);

}

DirectionalLight light = new DirectionalLight();

light.setDirection(new Vector3f( -1f, -1f, -1f));

light.setColor(ColorRGBA.White.mult(0.5f));

rootNode.addLight( light );

AmbientLight amb = new AmbientLight();

amb.setColor(ColorRGBA.White.mult(1f));

rootNode.addLight(amb);

}

private void setUpKeys() {

inputManager.addMapping(“Lefts”, new KeyTrigger(KeyInput.KEY_A));

inputManager.addMapping(“Rights”, new KeyTrigger(KeyInput.KEY_D));

inputManager.addMapping(“Jumps”, new KeyTrigger(KeyInput.KEY_SPACE));

inputManager.addListener(this, “Lefts”);

inputManager.addListener(this, “Rights”);

inputManager.addListener(this, “Jumps”);

}

public void onAction(String binding, boolean value, float tpf) {

if (binding.equals(“Lefts”)) {

left = value;

} else if (binding.equals(“Rights”)) {

right = value;

} else if (binding.equals(“Jumps”)){

player.jump();

}

}

@Override

public void simpleUpdate(float tpf) {

Vector3f pos = new Vector3f(player.getPhysicsLocation());

ChaseCamera bluechase = new ChaseCamera(cam, green);

bluechase.setDefaultHorizontalRotation(1.565f);

bluechase.setLookAtOffset(new Vector3f(0, 0, 0));

bluechase.setChasingSensitivity(0f);

green.addControl(bluechase);

green.setLocalTranslation(player.getPhysicsLocation());

float v = 0.5f;

if (left) {

player.setPhysicsLocation(new Vector3f(pos.x-v, pos.y, 0));

}

if (right) {

player.setPhysicsLocation(new Vector3f(pos.x+v, pos.y, 0));

}

}

}[/java]



EDIT: Increased the capsuleshape’s values. Now the player doesn’t pass through geometries, but the camera vibrates a lot when colliding.

Anyone please?

Dude!!! You didn’t even wait two hours for an answer!! Bump more aggressively like this and I close your thread.

Sorry, but I’m kinda desperate. It’s like seeing all my work getting undone :frowning: I’ll stop bumping, don’t worry.

I made this in the first few days of coming to JME, and knowing nothing about making games. Its just a simple “2d” scene with a character (with a big collision shape, i might add), and it’s probably got a lot of stuff you don’t want like a control for an enemy, but ill let you figure that out. It doesn’t make use of a chase cam, just the standard cam which i suggested to you early on that you should use. See if you get the same “shaking” you got previously. Also you’ll need the test-data.jar file in your class path:

Main.java

[java]package mygame;

import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.Node;

import com.jme3.light.AmbientLight;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.control.RigidBodyControl;

import com.jme3.bullet.control.CharacterControl;

import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;

import com.jme3.math.FastMath;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.input.KeyInput;

import com.jme3.scene.shape.Box;

import com.jme3.bullet.collision.PhysicsCollisionEvent;

import com.jme3.bullet.collision.PhysicsCollisionListener;

import com.jme3.util.SkyFactory;

/**

  • test

    *
  • @author normenhansen

    /

    public class Main extends SimpleApplication implements ActionListener, PhysicsCollisionListener {

    public BulletAppState bulletAppState;

    private Node model;

    private CharacterControl characterControl;

    private boolean left = false, right = false;

    private float increaseAmount = 1f;

    private Vector3f newLoc;

    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }

    @Override

    public void simpleInitApp() {

    bulletAppState = new BulletAppState();

    stateManager.attach(bulletAppState);

    createWorld();

    createCharacter();

    createEnemy();

    setUpLights();

    setupCamera();

    setupKeys();

    bulletAppState.getPhysicsSpace().enableDebug(assetManager);

    bulletAppState.getPhysicsSpace().addCollisionListener(this);

    rootNode.attachChild(SkyFactory.createSky(

    assetManager, "Textures/Sky/Bright/BrightSky.dds", false));

    }

    @Override

    public void collision(PhysicsCollisionEvent event) {

    if (event.getNodeA() != null) {

    RigidBodyControl r = event.getNodeA().getControl(RigidBodyControl.class);

    if (r != null) {

    r.setPhysicsLocation(r.getPhysicsLocation().mult(new Vector3f(1, 1, 0)));

    }

    }

    if (event.getNodeB() != null) {

    RigidBodyControl r = event.getNodeB().getControl(RigidBodyControl.class);

    if (r != null) {

    r.setPhysicsLocation(r.getPhysicsLocation().mult(new Vector3f(1, 1, 0)));

    }

    }

    }

    @Override

    public void simpleUpdate(float tpf) {

    //move the character in response to the keys pressed

    newLoc = characterControl.getPhysicsLocation();

    if (left) {

    newLoc.addLocal(-increaseAmount * tpf, 0, 0);

    }

    if (right) {

    newLoc.addLocal(increaseAmount * tpf, 0, 0);

    }

    newLoc.multLocal(new Vector3f(1, 1, 0));

    characterControl.setPhysicsLocation(newLoc);

    //move camera to this location

    cam.setLocation(new Vector3f(characterControl.getPhysicsLocation().getX(), characterControl.getPhysicsLocation().getY(), 10));

    cam.lookAt(new Vector3f(characterControl.getPhysicsLocation()), new Vector3f(0, 1, 0));

    }

    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }

    public void createWorld() {

    Spatial s = assetManager.loadModel("Scenes/MainLevel.obj");

    Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    m.setColor("Color", ColorRGBA.Red);

    s.setMaterial(m);

    s.rotate(0, FastMath.DEG_TO_RAD * -90, 0);

    s.addControl(new RigidBodyControl(0));

    rootNode.attachChild(s);

    bulletAppState.getPhysicsSpace().add(s);

    }

    public void createCharacter() {

    CapsuleCollisionShape shape = new CapsuleCollisionShape(0.5f, 0.5f);

    characterControl = new CharacterControl(shape, 1);

    characterControl.setGravity(1f);

    model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");

    model.setName("Character");

    model.setLocalScale(0.01f);

    model.addControl(characterControl);

    characterControl.setPhysicsLocation(new Vector3f(-1, 2, 0));

    rootNode.attachChild(model);

    bulletAppState.getPhysicsSpace().add(characterControl);

    }

    public void createEnemy() {

    Box b = new Box(Vector3f.ZERO, 0.1f, 0.1f, 0.1f);

    Spatial boxEnemy = new Geometry("Enemy", b);

    boxEnemy.setName("Enemy");

    boxEnemy.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"));

    boxEnemy.setLocalTranslation(0.15f, 1, 0);

    boxEnemy.addControl(new RigidBodyControl(1));

    boxEnemy.addControl(new SideToSideControl(this));

    rootNode.attachChild(boxEnemy);

    bulletAppState.getPhysicsSpace().add(boxEnemy);

    }

    public void setUpLights() {

    AmbientLight ambient = new AmbientLight();

    ambient.setColor(ColorRGBA.White);

    rootNode.addLight(ambient);

    }

    private void setupCamera() {

    flyCam.setEnabled(false);

    //make the camera initially pointed at the character

    cam.setLocation(new Vector3f(characterControl.getPhysicsLocation().getX(), characterControl.getPhysicsLocation().getY(), 10));

    cam.lookAt(new Vector3f(characterControl.getPhysicsLocation()), new Vector3f(0, 1, 0));

    }

    private void setupKeys() {

    inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_LEFT));

    inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_RIGHT));

    inputManager.addListener(this, "left", "right");

    }

    @Override

    public void onAction(String name, boolean keypressed, float tpf) {

    if (name.equals("left")) {

    if (keypressed) {

    left = true;

    } else {

    left = false;

    }

    } else if (name.equals("right")) {

    if (keypressed) {

    right = true;

    } else {

    right = false;

    }

    }

    }

    }

    [/java]

    SideToSideControl.java

    [java]package mygame;

    import com.jme3.math.Vector3f;

    import com.jme3.scene.control.Control;

    import com.jme3.renderer.RenderManager;

    import com.jme3.renderer.ViewPort;

    import com.jme3.scene.Spatial;

    import java.io.IOException;

    import com.jme3.export.JmeExporter;

    import com.jme3.export.JmeImporter;

    import com.jme3.export.OutputCapsule;

    import com.jme3.export.InputCapsule;

    import com.jme3.bullet.control.PhysicsControl;

    import com.jme3.bullet.control.RigidBodyControl;

    import com.jme3.app.SimpleApplication;

    import com.jme3.bullet.PhysicsSpace;

    import com.jme3.bullet.collision.PhysicsCollisionEvent;

    import com.jme3.bullet.collision.PhysicsCollisionListener;

    public class SideToSideControl implements Control, PhysicsCollisionListener {

    protected Spatial spatial;

    protected boolean enabled = true;

    private Vector3f translation;

    private SimpleApplication myApp;

    public SideToSideControl(SimpleApplication app) {

    myApp = app;

    ((Main)myApp).bulletAppState.getPhysicsSpace().addCollisionListener(this);

    }

    @Override

    public void update(float tpf) {

    if (enabled && spatial != null) {

    // …

    // Write custom code to control the spatial here!

    moveSpatial(tpf);

    }

    }

    @Override

    public void collision(PhysicsCollisionEvent event) {

    //get coordinates to stay within

    if(event.getNodeA().getName().equals("Character") && event.getNodeB().getName().equals("Enemy")){

    System.out.println("hit");

    }

    // else if(event.getNodeB().getName().equals("Character")){

    else if(event.getNodeB().getName().equals("Character") && event.getNodeA().getName().equals("Enemy")){

    System.out.println("hit");

    }

    }

    public void moveSpatial(float tpf){

    spatial.getControl(RigidBodyControl.class).setPhysicsLocation(spatial.getControl(RigidBodyControl.class).getPhysicsLocation().subtract(new Vector3f(tpf
    0.5f,0,0)));

    }

    @Override

    public void render(RenderManager rm, ViewPort vp) {

    // optional, e.g. to display a debug shape

    }

    @Override

    public Control cloneForSpatial(Spatial spatial) {

    SideToSideControl control = new SideToSideControl(myApp);

    // …

    spatial.addControl(control);

    return control;

    }

    @Override

    public void setEnabled(boolean enabled) {

    this.enabled = enabled;

    // …

    }

    @Override

    public boolean isEnabled() {

    return enabled;

    }

    @Override

    public void write(JmeExporter ex) throws IOException {

    //super.write(ex);

    OutputCapsule oc = ex.getCapsule(this);

    oc.write(enabled, "enabled", true);

    oc.write(spatial, "spatial", null);

    // write custom variables …

    }

    @Override

    public void read(JmeImporter im) throws IOException {

    // super.read(im);

    InputCapsule ic = im.getCapsule(this);

    enabled = ic.readBoolean("enabled", true);

    spatial = (Spatial) ic.readSavable("spatial", null);

    // read custom variables …

    }

    @Override

    public void setSpatial(Spatial spatial) {

    // super.read(im);

    this.spatial = spatial;

    translation = spatial.getLocalTranslation();

    }

    }

    [/java]



    Edit: ok sorry you also need the scene file.

    http://www.mediafire.com/?a8u38grb778ekl3 - MainLevel.obj

    http://www.mediafire.com/?gb4a99xp0u1j5ss - MainLevel.mtl