I am creating an fps game.I need one clarification.I have one model that I have loaded.Now when the model started walking ,
how should I add collision detection? If the model is hit on a wall, I should be able to determine that the model has been hit.
I have used collision detection tutorials in different ways.Unfortunately none of did work.If I paste the code, can somebody look into that and guide me what mistake I am doing ? Thanks in advance.
[java]
package mygame;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleBulletApplication;
import com.jme3.asset.plugins.HttpZipLocator;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.nodes.PhysicsCharacterNode;
import com.jme3.bullet.nodes.PhysicsNode;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.effect.EmitterSphereShape;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.effect.ParticleMesh.Type;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.MaterialList;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.plugins.ogre.OgreMeshKey;
import com.jme3.scene.shape.Sphere;
import java.io.File;
import com.jme3.app.SimpleBulletApplication;
import com.jme3.collision.CollisionResults;
import com.jme3.math.Ray;
public class TestQ3 extends SimpleBulletApplication implements ActionListener {
private Sphere sphereMesh = new Sphere(32, 32, 10f, false, true);
private Geometry sphere = new Geometry("Sky", sphereMesh);
private Spatial gameLevel;
private PhysicsCharacterNode player;
private Vector3f walkDirection = new Vector3f();
private static boolean useHttp = false;
private boolean left=false,right=false,up=false,down=false;
private Node enemyNode,ottoNode;
private PhysicsCharacterNode ottoPhysicsNode;
private float enemyX = 22.42094f,
enemyY = 11.204865f,
enemyZ = -21.849686f;
//(33.742054, 14.607552, -17.492054
private float ottoX = 33.742054f,
ottoY = 11.607552f,
ottoZ = -17.492054f;
private static final int COUNT_FACTOR = 1;
private static final float COUNT_FACTOR_F = 1f;
//ParticleEmitter debris,fire;
private float time = 0;
private int state = 0;
private ParticleEmitter flame, flash, spark, roundspark, smoketrail, debris,
shockwave;
private AnimChannel channel;
private AnimControl control;
private AnimChannel channel1;
private AnimControl control1;
public static void main(String[] args) {
File file = new File("E:\java resources\Game Tutorial\JME 3 - First Person Shooter-BasicGame\quake3level.zip");
if (!file.exists()) {
useHttp = false;
}
TestQ3 app = new TestQ3();
app.start();
}
public void simpleInitApp() {
flyCam.setMoveSpeed(100);
setupKeys();
this.cam.setFrustumFar(2000);
DirectionalLight dl = new DirectionalLight();
dl.setColor(ColorRGBA.White.clone().multLocal(2));
dl.setDirection(new Vector3f(-1, -1, -1).normalize());
rootNode.addLight(dl);
// load the level from zip or http zip
if (useHttp) {
assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/quake3level.zip", HttpZipLocator.class.getName());
} else {
assetManager.registerLocator("E:\java resources\Game Tutorial\JME 3 - First Person Shooter-BasicGame\quake3level.zip", ZipLocator.class.getName());
}
// create the geometry and attach it
MaterialList matList = (MaterialList) assetManager.loadAsset("Scene.material");
OgreMeshKey key = new OgreMeshKey("main.meshxml", matList);
gameLevel = (Spatial) assetManager.loadAsset(key);
gameLevel.setLocalScale(0.1f);
CompoundCollisionShape levelShape = CollisionShapeFactory.createMeshCompoundShape((Node) gameLevel);
PhysicsNode levelNode = new PhysicsNode(gameLevel, levelShape, 0);
// loading enemy model
Spatial myThingModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml");
PhysicsNode myThingPhysicsNode = new PhysicsNode(myThingModel,
CollisionShapeFactory.createMeshShape((Node)myThingModel),
//new CapsuleCollisionShape(1.5f, 6f, 1),
(float) 0.5);
// myThingPhysicsNode.setLocalTranslation(new Vector3f(2, 15, 0));
myThingPhysicsNode.setLocalTranslation(ottoX, ottoY, ottoZ);
Quaternion quat = new Quaternion();
quat.fromAngleAxis(FastMath.PI+290, new Vector3f(0,1,0));
myThingPhysicsNode.setLocalRotation(quat);
myThingPhysicsNode.setLocalScale(0.45f);
rootNode.attachChild(myThingPhysicsNode);
getPhysicsSpace().add(myThingPhysicsNode);
System.out.println("groups "+myThingPhysicsNode.getCollideWithGroups());
System.out.println("group "+myThingPhysicsNode.getCollisionGroup());
// loading player node
player = new PhysicsCharacterNode(new SphereCollisionShape(5), .01f);
player.setJumpSpeed(20);
player.setFallSpeed(30);
player.setGravity(30);
//
player.setLocalTranslation(new Vector3f(60, 10, -60));
rootNode.attachChild(levelNode);
rootNode.attachChild(player);
// load enemy Object
loadEnemyObject();
// loadAnotherEnemyObject();
createFlame();
attack();
enemyWalk();
// createFlash();
// createSpark();
// createRoundSpark();
// createSmokeTrail();
// createDebris();
// createShockwave();
getPhysicsSpace().add(levelNode);
getPhysicsSpace().add(player);
}
@Override
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
System.out.println("…Location…"+player.getLocalTranslation().toString());
flame.emitAllParticles();
time += tpf / speed;
//
// if (time > 1f && state == 0){
// flame.emitAllParticles();
// // flash.emitAllParticles();
// // spark.emitAllParticles();
// // smoketrail.emitAllParticles();
// // debris.emitAllParticles();
// // shockwave.emitAllParticles();
// state++;
// }
if (time > 1f + .05f / speed && state == 1){
// flame.emitAllParticles();
// // roundspark.emitAllParticles();
// state++;
System.out.println(" here…");
}
ottoZ = ottoZ - (0.1F)/8;
if(ottoNode != null){
ottoNode.setLocalTranslation(ottoX, ottoY, ottoZ);
System.out.println(" world bound…"+ottoNode.getWorldBound());
}
// 2. Aim the ray from cam loc to cam direction.
// // rewind the effect
// if (time > 5 / speed && state == 2){
// state = 0;
// time = 0;
//
// // flash.killAllParticles();
// // spark.killAllParticles();
// // smoketrail.killAllParticles();
// // debris.killAllParticles();
// // flame.killAllParticles();
// // roundspark.killAllParticles();
// // shockwave.killAllParticles();
// }
walkDirection.set(0,0,0);
if(left)
walkDirection.addLocal(camLeft);
if(right)
walkDirection.addLocal(camLeft.negate());
if(up)
walkDirection.addLocal(camDir);
if(down)
walkDirection.addLocal(camDir.negate());
player.setWalkDirection(walkDirection);
cam.setLocation(player.getLocalTranslation());
//rootNode.updateGeometricState();
}
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.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this,"Lefts");
inputManager.addListener(this,"Rights");
inputManager.addListener(this,"Ups");
inputManager.addListener(this,"Downs");
inputManager.addListener(this,"Space");
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Lefts")) {
if(value)
left=true;
else
left=false;
} else if (binding.equals("Rights")) {
if(value)
right=true;
else
right=false;
} else if (binding.equals("Ups")) {
if(value)
up=true;
else
up=false;
} else if (binding.equals("Downs")) {
if(value)
down=true;
else
down=false;
} else if (binding.equals("Space")) {
player.jump();
}
}
private void loadAnotherEnemyObject() {
// ottoNode = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
PhysicsCharacterNode physicsCharacter = new PhysicsCharacterNode(new SphereCollisionShape(0.2f), .1f);
physicsCharacter.setLocalTranslation(new Vector3f(0, 12, 0));
physicsCharacter.setJumpSpeed(10);
physicsCharacter.setFallSpeed(30);
physicsCharacter.setGravity(30);
//physicsCharacter.setMaxSlope(0.02f);
//Material mat = this.getAssetManager().loadMaterial("Models/Oto/Oto.mesh.xml");
Material mat = this.getAssetManager().loadMaterial("Models/Oto/Oto.j3m");
physicsCharacter.attachDebugShape(mat);
rootNode.attachChild(physicsCharacter);
this.getPhysicsSpace().add(physicsCharacter);
// ottoPhysicsNode.setLocalTranslation(ottoX, ottoY, ottoZ);
// Quaternion quat = new Quaternion();
// quat.fromAngleAxis(FastMath.PI+290, new Vector3f(0,1,0));
// ottoPhysicsNode.setLocalRotation(quat);
// ottoPhysicsNode.setLocalScale(0.45f);
//ottoNode.setLocalTranslation(ottoX, ottoY, ottoZ);
//Quaternion quat = new Quaternion();
//quat.fromAngleAxis(FastMath.PI+290, new Vector3f(0,1,0));
//ottoNode.setLocalRotation(quat);
//ottoNode.setLocalScale(0.45f);
// rootNode.attachChild(ottoPhysicsNode);
// this.getPhysicsSpace().add(ottoPhysicsNode);
}
private void loadEnemyObject() {
enemyNode = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
enemyNode.setLocalTranslation(enemyX, enemyY, enemyZ);
Quaternion quat = new Quaternion();
quat.fromAngleAxis(FastMath.PI+90, new Vector3f(0,1,0));
enemyNode.setLocalRotation(quat);
enemyNode.setLocalScale(0.05f);
rootNode.attachChild(enemyNode);
}
private void showEXplosion(){
debris = new ParticleEmitter("Debris", Type.Triangle, 15 * COUNT_FACTOR);
debris.setLocalTranslation(enemyX, enemyY, enemyZ);
debris.setSelectRandomImage(true);
debris.setRandomAngle(true);
debris.setRotateSpeed(FastMath.TWO_PI * 4);
debris.setStartColor(new ColorRGBA(1f, 0.59f, 0.28f, (float) (1.0f / COUNT_FACTOR_F)));
debris.setEndColor(new ColorRGBA(.5f, 0.5f, 0.5f, 0f));
debris.setStartSize(.2f);
debris.setEndSize(.5f);
// debris.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f));
debris.setParticlesPerSec(0);
debris.setGravity(12f);
debris.setLowLife(1.4f);
debris.setHighLife(1.5f);
debris.setStartVel(new Vector3f(0, 15, 0));
debris.setVariation(.60f);
debris.setImagesX(3);
debris.setImagesY(3);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("m_Texture", assetManager.loadTexture("Effects/Explosion/Debris.png"));
debris.setMaterial(mat);
rootNode.attachChild(debris);
}
private void createFlame(){
flame = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR);
flame.setLocalTranslation(enemyX, enemyY, enemyZ);
flame.setSelectRandomImage(true);
flame.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (float) (1f / COUNT_FACTOR_F)));
flame.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f));
flame.setStartSize(1.3f);
flame.setEndSize(2f);
flame.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
flame.setParticlesPerSec(0);
flame.setGravity(-5f);
flame.setLowLife(.4f);
flame.setHighLife(.5f);
flame.setStartVel(new Vector3f(0, 7, 0));
flame.setVariation(1f);
flame.setImagesX(2);
flame.setImagesY(2);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("m_Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
flame.setMaterial(mat);
rootNode.attachChild(flame);
}
private void createFlash(){
flash = new ParticleEmitter("Flash", Type.Triangle, 24 * COUNT_FACTOR);
flash.setLocalTranslation(enemyX, enemyY, enemyZ);
flash.setSelectRandomImage(true);
flash.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1f / COUNT_FACTOR_F)));
flash.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
flash.setStartSize(.1f);
flash.setEndSize(3.0f);
flash.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f));
flash.setParticlesPerSec(0);
flash.setGravity(0);
flash.setLowLife(.2f);
flash.setHighLife(.2f);
flash.setStartVel(new Vector3f(0, 5f, 0));
flash.setVariation(1);
flash.setImagesX(2);
flash.setImagesY(2);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("m_Texture", assetManager.loadTexture("Effects/Explosion/flash.png"));
flash.setMaterial(mat);
rootNode.attachChild(flash);
}
private void createRoundSpark(){
roundspark = new ParticleEmitter("RoundSpark", Type.Triangle, 20 * COUNT_FACTOR);
roundspark.setLocalTranslation(enemyX, enemyY, enemyZ);
roundspark.setStartColor(new ColorRGBA(1f, 0.29f, 0.34f, (float) (1.0 / COUNT_FACTOR_F)));
roundspark.setEndColor(new ColorRGBA(0, 0, 0, (float) (0.5f / COUNT_FACTOR_F)));
roundspark.setStartSize(1.2f);
roundspark.setEndSize(1.8f);
roundspark.setShape(new EmitterSphereShape(Vector3f.ZERO, 2f));
roundspark.setParticlesPerSec(0);
roundspark.setGravity(-.5f);
roundspark.setLowLife(1.8f);
roundspark.setHighLife(2f);
roundspark.setStartVel(new Vector3f(0, 3, 0));
roundspark.setVariation(.5f);
roundspark.setImagesX(1);
roundspark.setImagesY(1);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("m_Texture", assetManager.loadTexture("Effects/Explosion/roundspark.png"));
roundspark.setMaterial(mat);
rootNode.attachChild(roundspark);
}
private void createSpark(){
spark = new ParticleEmitter("Spark", Type.Triangle, 30 * COUNT_FACTOR);
spark.setLocalTranslation(enemyX, enemyY, enemyZ);
spark.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1.0f / COUNT_FACTOR_F)));
spark.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
spark.setStartSize(.5f);
spark.setEndSize(.5f);
// spark.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f));
spark.setFacingVelocity(true);
spark.setParticlesPerSec(0);
spark.setGravity(5);
spark.setLowLife(1.1f);
spark.setHighLife(1.5f);
spark.setStartVel(new Vector3f(0, 20, 0));
spark.setVariation(1);
spark.setImagesX(1);
spark.setImagesY(1);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("m_Texture", assetManager.loadTexture("Effects/Explosion/spark.png"));
spark.setMaterial(mat);
rootNode.attachChild(spark);
}
private void createSmokeTrail(){
smoketrail = new ParticleEmitter("SmokeTrail", Type.Triangle, 22 * COUNT_FACTOR);
smoketrail.setLocalTranslation(enemyX, enemyY, enemyZ);
smoketrail.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1.0f / COUNT_FACTOR_F)));
smoketrail.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
smoketrail.setStartSize(.2f);
smoketrail.setEndSize(1f);
// smoketrail.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
smoketrail.setFacingVelocity(true);
smoketrail.setParticlesPerSec(0);
smoketrail.setGravity(1);
smoketrail.setLowLife(.4f);
smoketrail.setHighLife(.5f);
smoketrail.setStartVel(new Vector3f(0, 12, 0));
smoketrail.setVariation(1);
smoketrail.setImagesX(1);
smoketrail.setImagesY(3);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("m_Texture", assetManager.loadTexture("Effects/Explosion/smoketrail.png"));
smoketrail.setMaterial(mat);
rootNode.attachChild(smoketrail);
}
private void createDebris(){
debris = new ParticleEmitter("Debris", Type.Triangle, 15 * COUNT_FACTOR);
debris.setLocalTranslation(enemyX, enemyY, enemyZ);
debris.setSelectRandomImage(true);
debris.setRandomAngle(true);
debris.setRotateSpeed(FastMath.TWO_PI * 4);
debris.setStartColor(new ColorRGBA(1f, 0.59f, 0.28f, (float) (1.0f / COUNT_FACTOR_F)));
debris.setEndColor(new ColorRGBA(.5f, 0.5f, 0.5f, 0f));
debris.setStartSize(.2f);
debris.setEndSize(.2f);
// debris.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f));
debris.setParticlesPerSec(0);
debris.setGravity(12f);
debris.setLowLife(1.4f);
debris.setHighLife(1.5f);
debris.setStartVel(new Vector3f(0, 15, 0));
debris.setVariation(.60f);
debris.setImagesX(3);
debris.setImagesY(3);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("m_Texture", assetManager.loadTexture("Effects/Explosion/Debris.png"));
debris.setMaterial(mat);
rootNode.attachChild(debris);
}
private void createShockwave(){
shockwave = new ParticleEmitter("Shockwave", Type.Triangle, 1 * COUNT_FACTOR);
shockwave.setLocalTranslation(enemyX, enemyY, enemyZ);
// shockwave.setRandomAngle(true);
shockwave.setFaceNormal(Vector3f.UNIT_Y);
shockwave.setStartColor(new ColorRGBA(.48f, 0.17f, 0.01f, (float) (.8f / COUNT_FACTOR_F)));
shockwave.setEndColor(new ColorRGBA(.48f, 0.17f, 0.01f, 0f));
shockwave.setStartSize(0f);
shockwave.setEndSize(7f);
shockwave.setParticlesPerSec(0);
shockwave.setGravity(0);
shockwave.setLowLife(0.5f);
shockwave.setHighLife(0.5f);
shockwave.setStartVel(new Vector3f(0, 0, 0));
shockwave.setVariation(0f);
shockwave.setImagesX(1);
shockwave.setImagesY(1);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("m_Texture", assetManager.loadTexture("Effects/Explosion/shockwave.png"));
shockwave.setMaterial(mat);
rootNode.attachChild(shockwave);
}
private void attack() {
control = enemyNode.getControl(AnimControl.class);
channel = control.createChannel();
channel.setAnim("Attack1");
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
System.out.println("[ Inside the onAnimCycleDone…]");
if (animName.equals("Attack1")){
channel.setAnim("Attack2", 0.50f);
channel.setLoopMode(LoopMode.DontLoop);
channel.setSpeed(1f);
}
}
private void enemyWalk() {
// control1 = ottoNode.getControl(AnimControl.class);
// channel1 = control1.createChannel();
// AnimChannel shootingChannel = control1.createChannel();
// channel1.addBone(control1.getSkeleton().getBone("uparm.right"));
// channel1.addBone(control1.getSkeleton().getBone("arm.right"));
// channel1.addBone(control1.getSkeleton().getBone("hand.right"));
// channel1.setAnim("Walk", 0.50f);
// checking for any obstacle
// CollisionResults results = new CollisionResults();
// Ray ray = new Ray(new Vector3f(ottoX, ottoY, ottoZ), new Vector3f(0, 0, 1));
// 3. Collect intersections between Ray and Shootables in results list.
// ottoNode.collideWith(ray, results);
// 4. Print the results
// System.out.println("
Collisions? " + results.size() + "
");
}
}
This is the exception I am getting;
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at com.bulletphysics.collision.dispatch.CollisionDispatcher.freeCollisionAlgorithm(CollisionDispatcher.java:119)
at com.bulletphysics.collision.dispatch.CompoundCollisionAlgorithm.destroy(CompoundCollisionAlgorithm.java:76)
at com.bulletphysics.collision.dispatch.CollisionDispatcher.freeCollisionAlgorithm(CollisionDispatcher.java:120)
at com.bulletphysics.collision.dispatch.CompoundCollisionAlgorithm.destroy(CompoundCollisionAlgorithm.java:76)
at com.bulletphysics.collision.dispatch.CollisionDispatcher.freeCollisionAlgorithm(CollisionDispatcher.java:120)
at com.bulletphysics.collision.broadphase.HashedOverlappingPairCache.cleanOverlappingPair(HashedOverlappingPairCache.java:219)
at com.bulletphysics.collision.broadphase.HashedOverlappingPairCache.removeOverlappingPair(HashedOverlappingPairCache.java:91)
at com.bulletphysics.collision.broadphase.DbvtBroadphase.collide(DbvtBroadphase.java:145)
at com.bulletphysics.collision.broadphase.DbvtBroadphase.calculateOverlappingPairs(DbvtBroadphase.java:235)
at com.bulletphysics.collision.dispatch.CollisionWorld.performDiscreteCollisionDetection(CollisionWorld.java:139)
at com.bulletphysics.dynamics.DiscreteDynamicsWorld.internalSingleStepSimulation(DiscreteDynamicsWorld.java:372)
at com.bulletphysics.dynamics.DiscreteDynamicsWorld.stepSimulation(DiscreteDynamicsWorld.java:337)
at com.jme3.bullet.PhysicsSpace.update(PhysicsSpace.java:359)
at com.jme3.bullet.PhysicsSpace.update(PhysicsSpace.java:303)
at com.jme3.app.SimpleBulletApplication.update(SimpleBulletApplication.java:301)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:112)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:162)
at java.lang.Thread.run(Thread.java:619)
[/java]
P. S Currently my code is not well formatted.