Proceed to Next Level

Hi guys. So I’m making a game for a project in my class and I really wanted mine to stand out so I went for jMonkey. I have been with this since Feb this year so I am quite a noob and as early as now, I would like to apologize for any consequences that my noobness can cause.

Anyways, my game must comprise of different levels and I have already successfully made one already - in its own class (WithWater). In an attempt to test switching or transitioning to the next level, I copied and refactored it. Here is where I got stuck. I have no idea how to call refactored class (the next level).

Basically I have a thread which plays music (I am using jlayer) and when it should end, the game should then take the player to a new level. I have already read about appstates but I’m just not sure on how to use them. Can you please help me and try to explain them to me a bit?

Here is the code for the original “WithWater” class
[java]package mygame;

import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AppState;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.collision.CollisionResults;
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.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Plane;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.Spatial.CullHint;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
import com.jme3.scene.shape.Sphere;
import com.jme3.ui.Picture;
import com.jme3.water.SimpleWaterProcessor;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import javax.swing.JOptionPane;
import javazoom.jl.player.Player;

/**

  • test

  • @author normenhansen
    */
    public class WithWater extends SimpleApplication implements ActionListener, PhysicsCollisionListener, AnimEventListener {

    private Node playerBoat = new Node();
    private Node player, player2, room;
    private Node sphere, sphere2, sphere3, sphere4, sphere5, sphere6, sphere7, sphere8;
    private RigidBodyControl sphereRigid, sphere2Rigid, sphere3Rigid, sphere4Rigid, sphere5Rigid, sphere6Rigid, sphere7Rigid, sphere8Rigid;
    private static final String ANI_IDLE = “Idle”;
    private static final String ANI_WALK = “Walk”;
    private static final String ANI_RUN = “Run”;
    private Spatial sceneModel, boatModel;
    private boolean walk = false, run = false;
    private BetterCharacterControl physicsCharacter, sphereBetter, roomBetter;// sphereRigid;
    private RigidBodyControl sceneRigid, roomRigid, boatRigid;
    private Vector3f walkDirection = new Vector3f();
    private boolean left = false, right = false, up = false, down = false;
    private boolean sphereIsVisible = true;
    private AnimChannel animationChannel, animationChannel2;
    private AnimControl animationControl, animationControl2;
    //CollisionResults results = new CollisionResults();
    private BulletAppState bulletAppState;
    Geometry water;
    int gameEndCount1 = 0, gameEndCount4 = 0, gameEndCount3 = 0, gameEndCount2 = 0, gameEndCount5 = 0;
    int playerScore = 0;

    Thread playMusic;
    FileInputStream fileInput;
    BufferedInputStream buffInput;
    private Player musicPlayer;

    float time;

    private void setupKeys() {
    inputManager.addMapping(“CharLeft”, new KeyTrigger(KeyInput.KEY_A));
    inputManager.addMapping(“CharRight”, new KeyTrigger(KeyInput.KEY_D));
    inputManager.addMapping(“CharUp”, new KeyTrigger(KeyInput.KEY_W));
    inputManager.addMapping(“CharDown”, new KeyTrigger(KeyInput.KEY_S));
    inputManager.addMapping(“CharSpace”, new KeyTrigger(KeyInput.KEY_RETURN));
    inputManager.addMapping(“CharRun”, new KeyTrigger(KeyInput.KEY_LSHIFT));
    inputManager.addMapping(“CharJump”, new KeyTrigger(KeyInput.KEY_SPACE));
    inputManager.addListener(this, “CharLeft”);
    inputManager.addListener(this, “CharRight”);
    inputManager.addListener(this, “CharUp”);
    inputManager.addListener(this, “CharDown”);
    inputManager.addListener(this, “CharRun”);
    inputManager.addListener(this, “CharJump”);
    }

    public static void main(String[] args) {
    WithWater app = new WithWater();
    app.start();
    }

    @Override
    @SuppressWarnings(“empty-statement”)
    public void simpleInitApp() {

     time = 0;
     
     bulletAppState = new BulletAppState();
     stateManager.attach(bulletAppState);
     bulletAppState.getPhysicsSpace().addCollisionListener(this);
     //bulletAppState.setDebugEnabled(true);
    
     //attachGUI();
     rootNode.setShadowMode(ShadowMode.Receive);
     rootNode.attachChild(playerBoat);
     
     setupKeys();        
     initScene();
     initWater();
     initSphere();
     //initSphere2();
     initRoom();
     initBoat();
     initPlayer();
     initLight();        
     setupAnimationController();
     
     
     playMusic = new Thread(){
         public void run(){
             System.out.println("PLAYING MUSIC");
             playBGM();
         }
     };
     playMusic.setDaemon(true);
     playMusic.start();  
    

    }

    private void setupAnimationController() {
    animationControl = player.getControl(AnimControl.class);
    animationChannel = animationControl.createChannel();
    animationChannel.setAnim(“Animation”);

     animationControl2 = player2.getControl(AnimControl.class);
     animationChannel2 = animationControl2.createChannel();
     animationChannel2.setAnim("Animation");
    

    }

    public void onAction(String binding, boolean isPressed, float tpf) {
    if (binding.equals(“CharLeft”)) {
    if (isPressed) {
    left = true;
    walk = true;
    } else {
    left = false;
    }
    } else if (binding.equals(“CharRight”)) {
    if (isPressed) {
    right = true;
    walk = true;
    } else {
    right = false;
    }
    } else if (binding.equals(“CharUp”)) {
    if (isPressed) {
    up = true;
    walk = true;
    } else {
    up = false;
    }
    } else if (binding.equals(“CharDown”)) {
    if (isPressed) {
    down = true;
    walk = true;
    } else {
    down = false;
    }
    }
    else if (binding.equals(“CharJump”) && playerBoat.getLocalTranslation().getY() <= 1) {
    physicsCharacter.jump();
    }
    if (binding.equals(“CharRun”) && walk){
    if (isPressed) {
    run = true;
    } else {
    run = false;
    }
    }

    }

    public void simpleUpdate(float tpf) {
    System.out.println(playerScore);
    if(sphere.getLocalTranslation().getX() > 5 || sphere.getLocalTranslation().getZ() > 5 || sphere.getLocalTranslation().getX() < -6 || sphere.getLocalTranslation().getZ() < -5){
    System.out.println(“DETACH!”);
    rootNode.detachChild(sphere);
    initSphere();
    }
    gameEndCount1 = checkSphereColl(sphere, sphereRigid, gameEndCount1);
    if(sphere2 != null){
    if(sphere2.getLocalTranslation().getX() > 5 || sphere2.getLocalTranslation().getZ() > 5 || sphere2.getLocalTranslation().getX() < -6 || sphere2.getLocalTranslation().getZ() < -5){
    System.out.println(“DETACH2!”);
    rootNode.detachChild(sphere2);
    initSphere2();
    }
    gameEndCount2 = checkSphereColl(sphere2, sphere2Rigid, gameEndCount2);
    }
    if(sphere3 != null){
    if(sphere3.getLocalTranslation().getX() > 5 || sphere3.getLocalTranslation().getZ() > 5 || sphere3.getLocalTranslation().getX() < -6 || sphere3.getLocalTranslation().getZ() < -5){
    System.out.println(“DETACH3!”);
    rootNode.detachChild(sphere3);
    initSphere3();
    }
    gameEndCount3 = checkSphereColl(sphere3, sphere3Rigid, gameEndCount3);
    }
    if(sphere4 != null){
    if(sphere4.getLocalTranslation().getX() > 5 || sphere4.getLocalTranslation().getZ() > 5 || sphere4.getLocalTranslation().getX() < -6 || sphere4.getLocalTranslation().getZ() < -5){
    System.out.println(“DETACH4!”);
    rootNode.detachChild(sphere4);
    initSphere4();
    }
    gameEndCount4 = checkSphereColl(sphere4, sphere4Rigid, gameEndCount4);
    }

     if(sphere5 != null){
         if(sphere5.getLocalTranslation().getX() &gt; 5 || sphere5.getLocalTranslation().getZ() &gt; 5 || sphere5.getLocalTranslation().getX() &lt; -6 || sphere5.getLocalTranslation().getZ() &lt; -5){
             System.out.println("DETACH4!");
             rootNode.detachChild(sphere5);
             initSphere5();
         }
         gameEndCount4 = checkSphereColl(sphere5, sphere5Rigid, gameEndCount4);
     }
     
    
     time += 1;
    
     if (time%6000 == 0){
         if(time/6000 == 1){
             initSphere2();
         }
         else if(time/6000 == 2){
             initSphere3();
         }
         else if(time/6000 == 3){
             initSphere4();
         }
         else if(time/6000 == 4){
             initSphere5();
         }            
     }
     if(!playMusic.isAlive()){
         //THIS IS THE PART WHERE THE PLAYER IS TO BE TAKEN TO THE NEXT LEVEL
     }
    
     
     Vector3f camDir = cam.getDirection().clone().multLocal(1.5f);
     Vector3f camLeft = cam.getLeft().clone().multLocal(1.5f);
     camDir.y = 0;
     camLeft.y = 0;
     walkDirection.set(0, 0, 0);
     if (left) {
         if(run){
             camDir = cam.getDirection().clone().multLocal(6f);
             camLeft = cam.getLeft().clone().multLocal(6f);
         }
         walkDirection.addLocal(camLeft);
     }
     if (right) {
         if(run){
             camDir = cam.getDirection().clone().multLocal(6f);
             camLeft = cam.getLeft().clone().multLocal(6f);
         }
         walkDirection.addLocal(camLeft.negate());
     }
     if (up) {
         if(run){
             camDir = cam.getDirection().clone().multLocal(6f);
             camLeft = cam.getLeft().clone().multLocal(6f);
         }
         walkDirection.addLocal(camDir);
         
     }
     if (down) {
         if(run){
             camDir = cam.getDirection().clone().multLocal(6f);
             camLeft = cam.getLeft().clone().multLocal(6f);
         }
         walkDirection.addLocal(camDir.negate());            
     }
     
     if (walkDirection.length() == 0) {
    

// if (!“Idle”.equals(animationChannel.getAnimationName())) {
// animationChannel.setAnim(ANI_IDLE);
// }
}
else {

        physicsCharacter.setViewDirection(walkDirection);
        
        if (!"Run".equals(animationChannel.getAnimationName()) &amp;&amp; run &amp;&amp; walk) {           
            //animationChannel.setAnim(ANI_RUN);       
            //walk = false;                
        }
        else if ((!"Walk".equals(animationChannel.getAnimationName()) &amp;&amp; walk &amp;&amp; !run)) {
            //animationChannel.setAnim(ANI_WALK);  
            run = false;
        }

    }
    physicsCharacter.setWalkDirection(walkDirection);
}

@Override
public void simpleRender(RenderManager rm) {
    //TODO: add render code
}

private int checkSphereColl(Node currSphere, RigidBodyControl currRigid, int gameEndCount){
    CollisionResults playerResults = new CollisionResults();
    currSphere.collideWith(playerBoat.getWorldBound(), playerResults);
    if(playerResults.size() &gt; 0 &amp;&amp; sphereIsVisible){
        currRigid.setGravity(new Vector3f(0, 2, 0));            
        playerScore += 1;
        //System.out.println("PLAYER SCORE: " + playerScore);
    }
    else{
        currRigid.setGravity(new Vector3f(0, -0.45f, 0));
        //System.out.println(currRigid.getGravity());
    }
    
    CollisionResults roomResults = new CollisionResults();
    currSphere.collideWith(room.getWorldBound(), roomResults);
    if(roomResults.size() &gt; 0 &amp;&amp; currSphere.getLocalTranslation().getY() &gt; 4){
        //System.out.println(currRigid.getLinearVelocity());
        
        currRigid.setLinearVelocity(new Vector3f(0, -1f, (float) -(Math.random())/2));   
    }
    
    CollisionResults waterResults = new CollisionResults();
    currSphere.collideWith(water.getWorldBound(), waterResults);
    if(waterResults.size() &gt; 0 &amp;&amp; sphereIsVisible){            
        //System.out.println("COLLIDED WITH WATER! --- " + gameEndCount);
        gameEndCount += 1;
        if(gameEndCount % 1000 == 0){
            System.out.println("SECONDS ELAPSED: " + gameEndCount);
            if(gameEndCount == 5000){
                //System.exit(0);
                inputEnabled = false;
            }
        }
    }
    else{
        gameEndCount = 0;
    }
    return gameEndCount;
    
}

private void initSphere(){
    FilterPostProcessor fpp=new FilterPostProcessor(assetManager);
    BloomFilter bf=new BloomFilter(BloomFilter.GlowMode.Objects);
    fpp.addFilter(bf);
    viewPort.addProcessor(fpp);
    
    sphere = (Node) assetManager.loadModel("Models/OGRE_Sphere2/Sphere.mesh.j3o");
    rootNode.attachChild(sphere);
    sphere.setLocalTranslation(new Vector3f(0, 3, 1));
    sphere.setShadowMode(ShadowMode.CastAndReceive);
    sphereRigid = new RigidBodyControl(1f);     
    sphere.addControl(sphereRigid);
    bulletAppState.getPhysicsSpace().add(sphereRigid);
    sphereRigid.setGravity(new Vector3f(0, -0.2f, 0));        
}

private void initSphere2(){
    sphere2 = (Node) assetManager.loadModel("Models/MyModel1/Sphere.mesh.j3o");
    rootNode.attachChild(sphere2);
    sphere2.setLocalTranslation(new Vector3f(-1, 3, 0));
    sphere2Rigid = new RigidBodyControl(1f);     
    sphere2.addControl(sphere2Rigid);
    bulletAppState.getPhysicsSpace().add(sphere2Rigid);
    sphere2Rigid.setGravity(new Vector3f(0, -0.2f, 0));
}

private void initSphere3(){
    sphere3 = (Node) assetManager.loadModel("Models/MyModel1/Sphere.mesh.j3o");
    rootNode.attachChild(sphere3);
    sphere3.setLocalTranslation(new Vector3f(0, 3, 1));
    sphere3Rigid = new RigidBodyControl(1f);  
    sphere3.addControl(sphere3Rigid);
    bulletAppState.getPhysicsSpace().add(sphere3Rigid);
    sphere3Rigid.setGravity(new Vector3f(0, -0.2f, 0));
}

private void initSphere4(){
    sphere4 = (Node) assetManager.loadModel("Models/MyModel1/Sphere.mesh.j3o");
    rootNode.attachChild(sphere4);
    sphere4.setLocalTranslation(new Vector3f(2, 3, -2));
    sphere4Rigid = new RigidBodyControl(1f);     
    sphere4.addControl(sphere4Rigid);
    bulletAppState.getPhysicsSpace().add(sphere4Rigid);
    sphere4Rigid.setGravity(new Vector3f(0, -0.2f, 0));
}

 private void initSphere5(){
    sphere5 = (Node) assetManager.loadModel("Models/MyModel1/Sphere.mesh.j3o");
    rootNode.attachChild(sphere5);
    sphere5.setLocalTranslation(new Vector3f(-1.2f, 3, -2));
    sphere5Rigid = new RigidBodyControl(1f);     
    sphere5.addControl(sphere5Rigid);
    bulletAppState.getPhysicsSpace().add(sphere5Rigid);
    sphere5Rigid.setGravity(new Vector3f(0, -0.2f, 0));
}

private void initRoom(){ 
    room = (Node) assetManager.loadModel("Models/OGRE_Room/Room.mesh.j3o");
    room.setCullHint(CullHint.Always);
    rootNode.attachChild(room);
    //room.setLocalScale(1.3f, 2f, 1f);
    room.setLocalScale(settings.getWidth()/1000, 1.6f, 0.8f);
    
    //sphere.setLocalTranslation(new Vector3f(1, 4f, -3));
    room.setLocalTranslation(new Vector3f(0, 0, 0));
    roomRigid = new RigidBodyControl(0f);   
    room.addControl(roomRigid);
    bulletAppState.getPhysicsSpace().add(roomRigid);
    
}

private void initScene(){
    sceneModel = assetManager.loadModel("Scenes/Scene1.j3o");
    sceneRigid = new RigidBodyControl(0.0f);
    sceneModel.addControl(sceneRigid);
    bulletAppState.getPhysicsSpace().add(sceneRigid);
    rootNode.attachChild(sceneModel);
    sceneRigid.setKinematic(true);
}

private void initWater(){
    // we create a water processor
    SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
    waterProcessor.setReflectionScene(sceneModel);

    // we set the water plane
    Vector3f waterLocation=new Vector3f(0,0.1f,0);
    waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
    viewPort.addProcessor(waterProcessor);

    // we set wave properties
    waterProcessor.setWaterDepth(40);         // transparency of water
    waterProcessor.setDistortionScale(0.05f); // strength of waves
    waterProcessor.setWaveSpeed(0.05f);       // speed of waves

    // we define the wave size by setting the size of the texture coordinates
    Quad quad = new Quad(400,400);
    quad.scaleTextureCoordinates(new Vector2f(6f,6f));

    // we create the water geometry from the quad
    water = new Geometry("water", quad);
    water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
    water.setLocalTranslation(-200, 0.1f, 250);
    water.setShadowMode(ShadowMode.Receive);
    water.setMaterial(waterProcessor.getMaterial());
    rootNode.attachChild(water);
}

private void initBoat(){
    boatModel = assetManager.loadModel("Models/OGRE_Boat/Boater.mesh.j3o");
    boatModel.setLocalScale(new Vector3f(0.8f, 0.8f, 0.8f));
    boatRigid = new RigidBodyControl(0.01f);
    boatModel.addControl(boatRigid);
    bulletAppState.getPhysicsSpace().add(boatRigid);
    playerBoat.attachChild(boatModel);
    
    boatRigid.setKinematic(true);
}

private void initPlayer(){ 
    player = (Node) assetManager.loadModel("Models/OGRE_AF1/AF_Sit.mesh.j3o");
    player.setLocalTranslation(new Vector3f(0, 0.03f, -0.1f));
    player.setLocalScale(new Vector3f(0.8f, 0.8f, 0.8f));
    player2 = (Node) assetManager.loadModel("Models/OGRE_AM1/AM_Sit.mesh.j3o");
    //player2.setLocalRotation(Quaternion.ZERO);
    player2.setLocalTranslation(new Vector3f(0, 0.03f, 0.1f));
    playerBoat.setLocalTranslation(0, 1f, 0);
    player2.setLocalScale(new Vector3f(0.8f, 0.8f, 0.8f));
    //physicsCharacter = new CharacterControl(comp, 0.3f);
    physicsCharacter = new BetterCharacterControl(0.65f, 1.4f, 100f);
    playerBoat.attachChild(player);
    playerBoat.attachChild(player2);
    playerBoat.addControl(physicsCharacter);     
    
    bulletAppState.getPhysicsSpace().add(physicsCharacter);
    physicsCharacter.setJumpForce(new Vector3f(0, 200f, 0));
    setPlayerCam();
}

private void setPlayerCam(){
    flyCam.setEnabled(false);
    cam.setLocation(new Vector3f(0, 2f, 10));
}

private void attachGUI(){
    Picture pic = new Picture("HUD Picture");
    pic.setImage(assetManager, "Interface/Images/frame2.png", true);
    pic.setWidth(settings.getWidth());
    pic.setHeight(settings.getHeight());
    pic.setPosition(0,0);
    guiNode.attachChild(pic);
}

private void initLight(){
    DirectionalLight sun = new DirectionalLight();
    sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)));
    sun.setColor(ColorRGBA.White);
    rootNode.addLight(sun);
    
    DirectionalLight spot = new DirectionalLight();
    spot.setDirection((new Vector3f(0f, 0f, -1f)));
    spot.setColor(ColorRGBA.White);
    rootNode.addLight(spot);

}


public void collision(PhysicsCollisionEvent event) {
    //System.out.println("collision"); //To change body of generated methods, choose Tools | Templates.
    
}

public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public void playBGM() {
    try {
        fileInput = new FileInputStream("assets/Sounds/Boater.mp3");
        buffInput = new BufferedInputStream(fileInput);
        musicPlayer = new Player(buffInput);
        //musicPlayer.play();
    }
    catch (Exception e) {           
       System.out.println("No file has been selected yet.\nPlease choose a file to be opened.");
    }
}

}
[/java]

theres a lot of ways to implement this sort of thing…

to use an app state you just make a class that extends AbstractAppState instead of SimpleApplication, and then do stateManager.attach(new YourLevelAppState());. its not that different from writing your code directly in simple application.

you’ll probably want an app state for each level.

@icamefromspace said: theres a lot of ways to implement this sort of thing...

to use an app state you just make a class that extends AbstractAppState instead of SimpleApplication, and then do stateManager.attach(new YourLevelAppState());. its not that different from writing your code directly in simple application.

you’ll probably want an app state for each level.

Thanks. I do get that idea of having an app state for each level. My problem now is how do I sort of “translate” my SimpleApplication into a class extending AbstractAppState? I am currently in the process of doing so but it wouldn’t allow me to implement PhysicsCollisionListener like the SimpleApplication would allow me.

@dicdicjalique said: Thanks. I do get that idea of having an app state for each level. My problem now is how do I sort of "translate" my SimpleApplication into a class extending AbstractAppState? I am currently in the process of doing so but it wouldn't allow me to implement PhysicsCollisionListener like the SimpleApplication would allow me.

Sure it would. But we can’t help with errors we aren’t told about.

Please tell me if I’m wrong, but I think I do not need to implement PhysicsCollisionListener anymore in a class that extends AbstractAppState? I got this after reading several resources.

@pspeed said: Sure it would. But we can't help with errors we aren't told about.

Don’t mind my previous post about not needing to implement PhysicsCollisionListener… Anyways, I get a ‘{’ expected error when I try extending AbstractAppState then implementing PhysicsCollisionListener and the whole public class BoaterAppState extends AbstractAppState, implements PhysicsCollisionListener is underlined in red.

@dicdicjalique said: Please tell me if I'm wrong, but I think I do not need to implement PhysicsCollisionListener anymore in a class that extends AbstractAppState? I got this after reading several resources.

I have no idea what you are trying to do so I can’t comment on a guess. But you said “wouldn’t allow me to” which isn’t true. You can have an app state implement PhysicsCollisionListener and add/remove it from the space as needed. Nothing prevents it.

…whether you will want to or not is an entirely different matter.

I get the point. Maybe putting up my code for the class extending AbstractAppState would help. The main problem I have here is to “translate” my class extending SimpleApplication (the one with the code posted above) to one extending AbstractAppState. (that is why I am looking for ways to implement PhysicsCollisionListener).

[java]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package mygame;

import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.collision.CollisionResults;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Plane;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
import com.jme3.ui.Picture;
import com.jme3.water.SimpleWaterProcessor;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import javazoom.jl.player.Player;
import com.jme3.renderer.ViewPort;

/**
*

  • @author Dicdic
    */
    public class BoaterAppState extends AbstractAppState {
    private SimpleApplication app;
    private Node rootNode;
    private AssetManager assetManager;
    private Camera cam = new Camera();
    private ViewPort viewPort;
    private Node playerBoat = new Node();
    private Node player, player2, room;
    private Node sphere, sphere2, sphere3, sphere4, sphere5, sphere6, sphere7, sphere8;
    private RigidBodyControl sphereRigid, sphere2Rigid, sphere3Rigid, sphere4Rigid, sphere5Rigid, sphere6Rigid, sphere7Rigid, sphere8Rigid;
    private static final String ANI_IDLE = “Idle”;
    private static final String ANI_WALK = “Walk”;
    private static final String ANI_RUN = “Run”;
    private Spatial sceneModel, boatModel;
    private boolean walk = false, run = false;
    private BetterCharacterControl physicsCharacter, sphereBetter, roomBetter;// sphereRigid;
    private RigidBodyControl sceneRigid, roomRigid, boatRigid;
    private Vector3f walkDirection = new Vector3f();
    private boolean left = false, right = false, up = false, down = false;
    private boolean sphereIsVisible = true;
    private AnimChannel animationChannel, animationChannel2;
    private AnimControl animationControl, animationControl2;
    //CollisionResults results = new CollisionResults();
    private BulletAppState bulletAppState;
    Geometry water;
    int gameEndCount1 = 0, gameEndCount4 = 0, gameEndCount3 = 0, gameEndCount2 = 0, gameEndCount5 = 0;
    int playerScore = 0;

    Thread playMusic;
    FileInputStream fileInput;
    BufferedInputStream buffInput;
    private Player musicPlayer;

    float time;

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
    super.initialize(stateManager, app);
    this.app = (SimpleApplication) app;
    this.rootNode = this.app.getRootNode();
    this.assetManager = this.app.getAssetManager();

     time = 0;
     
     bulletAppState = new BulletAppState();
     stateManager.attach(bulletAppState);
     bulletAppState.getPhysicsSpace().addCollisionListener(null);
     //bulletAppState.setDebugEnabled(true);
    
     //attachGUI();
     rootNode.setShadowMode(RenderQueue.ShadowMode.Receive);
     rootNode.attachChild(playerBoat);
     
     //setupKeys();        
     initScene();
     //initWater();
     initSphere();
     //initSphere2();
     initRoom();
     initBoat();
     initPlayer();
     initLight();        
     setupAnimationController();
     
     
     playMusic = new Thread(){
         public void run(){
             System.out.println("PLAYING MUSIC");
             playBGM();
         }
     };
     playMusic.setDaemon(true);
     playMusic.start();  
    

    }

    @Override
    public void update(float tpf) {
    System.out.println(playerScore);
    if(sphere != null){
    if(sphere.getLocalTranslation().getX() > 5 || sphere.getLocalTranslation().getZ() > 5 || sphere.getLocalTranslation().getX() < -6 || sphere.getLocalTranslation().getZ() < -5){
    System.out.println(“DETACH!”);
    rootNode.detachChild(sphere);
    initSphere();
    }
    gameEndCount1 = checkSphereColl(sphere, sphereRigid, gameEndCount1);
    }

     if(sphere2 != null){
         if(sphere2.getLocalTranslation().getX() &gt; 5 || sphere2.getLocalTranslation().getZ() &gt; 5 || sphere2.getLocalTranslation().getX() &lt; -6 || sphere2.getLocalTranslation().getZ() &lt; -5){
             System.out.println("DETACH2!");
             rootNode.detachChild(sphere2);
             initSphere2();
         }
         gameEndCount2 = checkSphereColl(sphere2, sphere2Rigid, gameEndCount2);
     }
     if(sphere3 != null){
         if(sphere3.getLocalTranslation().getX() &gt; 5 || sphere3.getLocalTranslation().getZ() &gt; 5 || sphere3.getLocalTranslation().getX() &lt; -6 || sphere3.getLocalTranslation().getZ() &lt; -5){
             System.out.println("DETACH3!");
             rootNode.detachChild(sphere3);
             initSphere3();
         }
         gameEndCount3 = checkSphereColl(sphere3, sphere3Rigid, gameEndCount3);
     }
     if(sphere4 != null){
         if(sphere4.getLocalTranslation().getX() &gt; 5 || sphere4.getLocalTranslation().getZ() &gt; 5 || sphere4.getLocalTranslation().getX() &lt; -6 || sphere4.getLocalTranslation().getZ() &lt; -5){
             System.out.println("DETACH4!");
             rootNode.detachChild(sphere4);
             initSphere4();
         }
         gameEndCount4 = checkSphereColl(sphere4, sphere4Rigid, gameEndCount4);
     }
     
     if(sphere5 != null){
         if(sphere5.getLocalTranslation().getX() &gt; 5 || sphere5.getLocalTranslation().getZ() &gt; 5 || sphere5.getLocalTranslation().getX() &lt; -6 || sphere5.getLocalTranslation().getZ() &lt; -5){
             System.out.println("DETACH4!");
             rootNode.detachChild(sphere5);
             initSphere5();
         }
         gameEndCount4 = checkSphereColl(sphere5, sphere5Rigid, gameEndCount4);
     }
     
    
     time += 1;
     /*if((time % 10 == 0) &amp;&amp; playMusic.isAlive()){
         System.out.println(time/1000);
     }*/
     //System.out.println(player2.getLocalRotation());
     if (time%6000 == 0){
         if(time/6000 == 1){
             initSphere2();
         }
         else if(time/6000 == 2){
             initSphere3();
         }
         else if(time/6000 == 3){
             initSphere4();
         }
         else if(time/6000 == 4){
             initSphere5();
         }            
     }
     if(!playMusic.isAlive()){
         //stateManager.detach((AppState) this);
        // rootNode.detachAllChildren();
         //BeachFun next = new BeachFun();
     }
    
     
     Vector3f camDir = cam.getDirection().clone().multLocal(1.5f);
     Vector3f camLeft = cam.getLeft().clone().multLocal(1.5f);
     camDir.y = 0;
     camLeft.y = 0;
     walkDirection.set(0, 0, 0);
     if (left) {
         if(run){
             camDir = cam.getDirection().clone().multLocal(6f);
             camLeft = cam.getLeft().clone().multLocal(6f);
         }
         walkDirection.addLocal(camLeft);
     }
     if (right) {
         if(run){
             camDir = cam.getDirection().clone().multLocal(6f);
             camLeft = cam.getLeft().clone().multLocal(6f);
         }
         walkDirection.addLocal(camLeft.negate());
     }
     if (up) {
         if(run){
             camDir = cam.getDirection().clone().multLocal(6f);
             camLeft = cam.getLeft().clone().multLocal(6f);
         }
         walkDirection.addLocal(camDir);
         
     }
     if (down) {
         if(run){
             camDir = cam.getDirection().clone().multLocal(6f);
             camLeft = cam.getLeft().clone().multLocal(6f);
         }
         walkDirection.addLocal(camDir.negate());            
     }
     
     if (walkDirection.length() == 0) {
    

// if (!“Idle”.equals(animationChannel.getAnimationName())) {
// animationChannel.setAnim(ANI_IDLE);
// }
}
else {

        physicsCharacter.setViewDirection(walkDirection);
        
        if (!"Run".equals(animationChannel.getAnimationName()) &amp;&amp; run &amp;&amp; walk) {           
            //animationChannel.setAnim(ANI_RUN);       
            //walk = false;                
        }
        else if ((!"Walk".equals(animationChannel.getAnimationName()) &amp;&amp; walk &amp;&amp; !run)) {
            //animationChannel.setAnim(ANI_WALK);  
            run = false;
        }

    }
    physicsCharacter.setWalkDirection(walkDirection);

}
@Override
public void cleanup() {

}

private int checkSphereColl(Node currSphere, RigidBodyControl currRigid, int gameEndCount){
    CollisionResults playerResults = new CollisionResults();
    currSphere.collideWith(playerBoat.getWorldBound(), playerResults);
    if(playerResults.size() &gt; 0 &amp;&amp; sphereIsVisible){
        currRigid.setGravity(new Vector3f(0, 2, 0));            
        playerScore += 1;
        //System.out.println("PLAYER SCORE: " + playerScore);
    }
    else{
        currRigid.setGravity(new Vector3f(0, -0.45f, 0));
        //System.out.println(currRigid.getGravity());
    }
    
    CollisionResults roomResults = new CollisionResults();
    currSphere.collideWith(room.getWorldBound(), roomResults);
    if(roomResults.size() &gt; 0 &amp;&amp; currSphere.getLocalTranslation().getY() &gt; 4){
        //System.out.println(currRigid.getLinearVelocity());
        
        currRigid.setLinearVelocity(new Vector3f(0, -1f, (float) -(Math.random())/2));   
    }
    
    CollisionResults waterResults = new CollisionResults();
    currSphere.collideWith(water.getWorldBound(), waterResults);
    if(waterResults.size() &gt; 0 &amp;&amp; sphereIsVisible){            
        //System.out.println("COLLIDED WITH WATER! --- " + gameEndCount);
        gameEndCount += 1;
        if(gameEndCount % 1000 == 0){
            System.out.println("SECONDS ELAPSED: " + gameEndCount);
            if(gameEndCount == 5000){
                //System.exit(0);
                
            }
        }
    }
    else{
        gameEndCount = 0;
    }
    return gameEndCount;
    
}

private void setupAnimationController() {
    animationControl = player.getControl(AnimControl.class);
    animationChannel = animationControl.createChannel();
    animationChannel.setAnim("Animation");
    
    animationControl2 = player2.getControl(AnimControl.class);
    animationChannel2 = animationControl2.createChannel();
    animationChannel2.setAnim("Animation");
}

private void initSphere(){
    
    sphere = (Node) assetManager.loadModel("Models/OGRE_Sphere2/Sphere.mesh.j3o");
    rootNode.attachChild(sphere);
    sphere.setLocalTranslation(new Vector3f(0, 3, 1));
    sphere.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
    sphereRigid = new RigidBodyControl(1f);     
    sphere.addControl(sphereRigid);
    bulletAppState.getPhysicsSpace().add(sphereRigid);
    sphereRigid.setGravity(new Vector3f(0, -0.2f, 0));        
}

private void initSphere2(){
    sphere2 = (Node) assetManager.loadModel("Models/MyModel1/Sphere.mesh.j3o");
    rootNode.attachChild(sphere2);
    sphere2.setLocalTranslation(new Vector3f(-1, 3, 0));
    sphere2Rigid = new RigidBodyControl(1f);     
    sphere2.addControl(sphere2Rigid);
    bulletAppState.getPhysicsSpace().add(sphere2Rigid);
    sphere2Rigid.setGravity(new Vector3f(0, -0.2f, 0));
}

private void initSphere3(){
    sphere3 = (Node) assetManager.loadModel("Models/MyModel1/Sphere.mesh.j3o");
    rootNode.attachChild(sphere3);
    sphere3.setLocalTranslation(new Vector3f(0, 3, 1));
    sphere3Rigid = new RigidBodyControl(1f);  
    sphere3.addControl(sphere3Rigid);
    bulletAppState.getPhysicsSpace().add(sphere3Rigid);
    sphere3Rigid.setGravity(new Vector3f(0, -0.2f, 0));
}

private void initSphere4(){
    sphere4 = (Node) assetManager.loadModel("Models/MyModel1/Sphere.mesh.j3o");
    rootNode.attachChild(sphere4);
    sphere4.setLocalTranslation(new Vector3f(2, 3, -2));
    sphere4Rigid = new RigidBodyControl(1f);     
    sphere4.addControl(sphere4Rigid);
    bulletAppState.getPhysicsSpace().add(sphere4Rigid);
    sphere4Rigid.setGravity(new Vector3f(0, -0.2f, 0));
}

 private void initSphere5(){
    sphere5 = (Node) assetManager.loadModel("Models/MyModel1/Sphere.mesh.j3o");
    rootNode.attachChild(sphere5);
    sphere5.setLocalTranslation(new Vector3f(-1.2f, 3, -2));
    sphere5Rigid = new RigidBodyControl(1f);     
    sphere5.addControl(sphere5Rigid);
    bulletAppState.getPhysicsSpace().add(sphere5Rigid);
    sphere5Rigid.setGravity(new Vector3f(0, -0.2f, 0));
}

private void initRoom(){ 
    room = (Node) assetManager.loadModel("Models/OGRE_Room/Room.mesh.j3o");
    room.setCullHint(Spatial.CullHint.Always);
    rootNode.attachChild(room);
    //room.setLocalScale(1.3f, 2f, 1f);
    room.setLocalScale(1.6f, 1.6f, 0.8f);
    
    //sphere.setLocalTranslation(new Vector3f(1, 4f, -3));
    room.setLocalTranslation(new Vector3f(0, 0, 0));
    roomRigid = new RigidBodyControl(0f);   
    room.addControl(roomRigid);
    bulletAppState.getPhysicsSpace().add(roomRigid);
    
}

private void initScene(){
    sceneModel = assetManager.loadModel("Scenes/Scene1.j3o");
    sceneRigid = new RigidBodyControl(0.0f);
    sceneModel.addControl(sceneRigid);
    bulletAppState.getPhysicsSpace().add(sceneRigid);
    rootNode.attachChild(sceneModel);
    sceneRigid.setKinematic(true);
}

private void initWater(){
    // we create a water processor
    viewPort = new ViewPort("view", cam);
    SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
    waterProcessor.setReflectionScene(sceneModel);

    // we set the water plane
    Vector3f waterLocation=new Vector3f(0,0.1f,0);
    waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
    viewPort.addProcessor(waterProcessor);

    // we set wave properties
    waterProcessor.setWaterDepth(40);         // transparency of water
    waterProcessor.setDistortionScale(0.05f); // strength of waves
    waterProcessor.setWaveSpeed(0.05f);       // speed of waves

    // we define the wave size by setting the size of the texture coordinates
    Quad quad = new Quad(400,400);
    quad.scaleTextureCoordinates(new Vector2f(6f,6f));

    // we create the water geometry from the quad
    water = new Geometry("water", quad);
    water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
    water.setLocalTranslation(-200, 0.1f, 250);
    water.setShadowMode(RenderQueue.ShadowMode.Receive);
    water.setMaterial(waterProcessor.getMaterial());
    rootNode.attachChild(water);
}

private void initBoat(){
    boatModel = assetManager.loadModel("Models/OGRE_Boat/Boater.mesh.j3o");
    boatModel.setLocalScale(new Vector3f(0.8f, 0.8f, 0.8f));
    boatRigid = new RigidBodyControl(0.01f);
    boatModel.addControl(boatRigid);
    bulletAppState.getPhysicsSpace().add(boatRigid);
    playerBoat.attachChild(boatModel);
    
    boatRigid.setKinematic(true);
}

private void initPlayer(){ 
    player = (Node) assetManager.loadModel("Models/OGRE_AF1/AF_Sit.mesh.j3o");
    player.setLocalTranslation(new Vector3f(0, 0.03f, -0.1f));
    player.setLocalScale(new Vector3f(0.8f, 0.8f, 0.8f));
    player2 = (Node) assetManager.loadModel("Models/OGRE_AM1/AM_Sit.mesh.j3o");
    //player2.setLocalRotation(Quaternion.ZERO);
    player2.setLocalTranslation(new Vector3f(0, 0.03f, 0.1f));
    playerBoat.setLocalTranslation(0, 1f, 0);
    player2.setLocalScale(new Vector3f(0.8f, 0.8f, 0.8f));
    //physicsCharacter = new CharacterControl(comp, 0.3f);
    physicsCharacter = new BetterCharacterControl(0.65f, 1.4f, 100f);
    playerBoat.attachChild(player);
    playerBoat.attachChild(player2);
    playerBoat.addControl(physicsCharacter);     
    
    bulletAppState.getPhysicsSpace().add(physicsCharacter);
    physicsCharacter.setJumpForce(new Vector3f(0, 200f, 0));
    setPlayerCam();
}

private void setPlayerCam(){
    //flyCam.setEnabled(false);
    
}



private void initLight(){
    DirectionalLight sun = new DirectionalLight();
    sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)));
    sun.setColor(ColorRGBA.White);
    rootNode.addLight(sun);
    
    DirectionalLight spot = new DirectionalLight();
    spot.setDirection((new Vector3f(0f, 0f, -1f)));
    spot.setColor(ColorRGBA.White);
    rootNode.addLight(spot);

}

public void playBGM() {
    try {
        fileInput = new FileInputStream("assets/Sounds/Boater.mp3");
        buffInput = new BufferedInputStream(fileInput);
        musicPlayer = new Player(buffInput);
        //musicPlayer.play();
    }
    catch (Exception e) {           
       System.out.println("No file has been selected yet.\nPlease choose a file to be opened.");
    }
}

}
[/java]

I apologize for all the stuff in this code that might confuse you. I am just a noob but I am really trying my best to find a way to sort this out. :slight_smile:

UPDATE: I have already sorted out the problem and am now able to run my game via a class extending an AbstractAppState. Thanks for all your help guys.