Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            jMonkeyEngine3: Привет мир, Обучающая Серия
                jMonkeyEngine3 урок (15) — Hello Chase camera

jMonkeyEngine3 урок (15) — Hello Chase camera

Опубликованно: 06.04.2017, 14:08
Последняя редакция, Andry: 02.10.2017 14:31

Предыдущий: Hello Vector3f, Вернуться к Уроки для начинающих.

Ютуб видео

chasecamera

Модельки:

Напоминание:

  1. jMonkeyEngine вызывает методы обновления всех объектов AppState в том порядке, в котором вы прикрепили их.
  2. JMonkeyEngine вызывает методы controlUpdate() всех элементов управления в том порядке, в котором вы добавили их.
  3. JMonkeyEngine вызывает метод simpleUpdat() основного класса SimpleApplication.

AbstractPhysicBodyContext (физика)

package org.jmonkey3.chasecam;
 
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.BulletAppState;
 
/*
 Пример камеры от 3 лица
 Основан на официальном TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public abstract class AbstractPhysicBodyContext extends AbstractAppState
{
 
    private AppStateManager stateManager = null;
    //
    private static final BulletAppState bulletAppState;
 
    static
    {
        bulletAppState = new BulletAppState();
    }
 
    public AbstractPhysicBodyContext()
    {
    }
 
    /**
     @return the bulletAppState
     */
    public BulletAppState getBulletAppState()
    {
        return bulletAppState;
    }
 
    /**
     @param stateManager the stateManager to set
     Attaching BulletAppstate to Initialize PhysicsSpace
     */
    public void attachBulletAppstate(AppStateManager stateManager)
    {
        this.stateManager = stateManager;
        stateManager.attach(bulletAppState);
    }
}

AbstractSpatialBodyContext.java (модель)

package org.jmonkey3.chasecam;
 
import com.jme3.app.state.AbstractAppState;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public abstract class AbstractSpatialBodyContext extends AbstractAppState
{
 
    public AbstractSpatialBodyContext()
    {
    }
 
}

ApplicationContext.java (приложение)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.input.FlyByCamera;
import com.jme3.input.InputManager;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
import com.jme3.system.AppSettings;
import org.jmonkey.utils.Debug;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class ApplicationContext extends AbstractAppState
{
 
    private final Node rootNode;
//
    private final CameraContext sceneCameraContext;
    private final AvatarBodyManager avatarBodyManager;
    private final SceneBodyManager sceneBodyManager;
 
/**
 
    @param stateManager
    @param am
    @param settings
    @param inputManager
    @param rootNode
    @param cam
    @param flyByCam 
    */
    public ApplicationContext(AppStateManager stateManager, AssetManager am, AppSettings 
settings, InputManager inputManager, Node rootNode, Camera cam, FlyByCamera flyByCam)
    {
 
        this.rootNode = rootNode;
        this.sceneCameraContext = new CameraContext(settings, inputManager, cam, flyByCam);
        this.sceneBodyManager = new SceneBodyManager(stateManager, am, rootNode);
        this.avatarBodyManager = new AvatarBodyManager(am, rootNode, sceneCameraContext);
    }
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
        //super.initialize(stateManager, app);
        //TODO: инициализируйте ваше AppState, и т. д. прикрепите модели к rootNode
        //это вызовет OpenGL следом за AppState
 
//
        stateManager.attach(this.sceneCameraContext);
        stateManager.attach(this.sceneBodyManager);
        //initialize physic spacein constructor
        stateManager.attach(this.avatarBodyManager);
        //
        Debug.showNodeAxes(app.getAssetManager(), this.rootNode, 1024.0f);
        Debug.attachWireFrameDebugGrid(app.getAssetManager(), 
rootNode, Vector3f.ZERO, 2048, ColorRGBA.DarkGray);
    }
 
    @Override
    public void update(float tpf)
    {
 
    }
}

AvatarAnimationEventListener.java (слушатель анимации)

package org.jmonkey3.chasecam;
 
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.objects.PhysicsCharacter;
import com.jme3.scene.Spatial;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class AvatarAnimationEventListener extends AbstractAppState implements AnimEventListener
{
 
    private final AnimChannel channel;
    private final AnimControl control;
    private final PlayerInputActionListener pial;
    private final AvatarAnimationHelper animHelper;
    private final PhysicsCharacter physicBody;
/**
 
    @param pial
    @param pc
    @param avatarMesh 
    */
    public AvatarAnimationEventListener(PlayerInputActionListener pial, PhysicsCharacter pc, Spatial avatarMesh)
    {
        this.pial = pial;
        this.control = avatarMesh.getControl(AnimControl.class);
        assert (this.control != null);
        this.channel = this.control.createChannel();
        this.physicBody = pc;
        this.animHelper = new AvatarAnimationHelper(this.physicBody, this.channel);
    }
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
        this.control.addListener(this);
        this.channel.setAnim("Idle1");
        this.channel.setSpeed(0.5f);
    }
 
    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.
 
    }
 
    /**
     @return the channel
     */
    protected AnimChannel getChannel()
    {
        return channel;
    }
 
    /**
     @return the control
     */
    protected AnimControl getControl()
    {
        return control;
    }
 
    /**
     * @return the animHelper
     */
    protected AvatarAnimationHelper getAnimHelper()
    {
        return animHelper;
    }
}

AvatarAnimationHelper.java (помощник анимации)

package org.jmonkey3.chasecam;
 
import com.jme3.animation.AnimChannel;
import com.jme3.animation.LoopMode;
import com.jme3.bullet.objects.PhysicsCharacter;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class AvatarAnimationHelper
{
 
    private final AnimChannel animChannel;
    private final PhysicsCharacter physicBody;
/**
 
    @param pc
    @param ac 
    */
    public AvatarAnimationHelper(PhysicsCharacter pc, AnimChannel ac)
    {
        this.animChannel = ac;
        this.physicBody = pc;
    }
 
    protected void idle()
    {
        animChannel.setAnim("Idle1");
        animChannel.setSpeed(0.5f);
    }
 
    protected boolean forward(boolean pressed)
    {
        if (pressed)
        {
            if (this.physicBody.onGround())
            {
                animChannel.setAnim("Walk");
                animChannel.setSpeed(AvatarConstants.FORWARD_MOVE_SPEED * 2f);
                animChannel.setLoopMode(LoopMode.Loop);
            }
            return true;
        } else
        {
            idle();
            return false;
        }
        //throw new UnsupportedOperationException("Not supported yet."); 
        //To change body of generated methods, choose Tools | Templates.
    }
 
    protected boolean backward(boolean pressed)
    {
        if (pressed)
        {
            return true;
        } else
        {
            return false;
        }
    }
 
    protected boolean rightward(boolean pressed)
    {
        if (pressed)
        {
            return true;
        } else
        {
            return false;
        }
    }
 
    protected boolean leftward(boolean pressed)
    {
        if (pressed)
        {
            return true;
        } else
        {
            return false;
        }
    }
 
    protected boolean jump(boolean pressed)
    {
            if (pressed)
            {
                if (this.physicBody.onGround())
                {
                    animChannel.setAnim("HighJump");
                    animChannel.setSpeed(AvatarConstants.FORWARD_MOVE_SPEED / 1.8f);
                    animChannel.setLoopMode(LoopMode.DontLoop);
                    //
                    this.physicBody.jump();
                }
                return true;
            } else
            {
                return false;
            }
    }
}

AvatarBodyManager.java (менеджер персонажа)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.objects.PhysicsCharacter;
import com.jme3.input.ChaseCamera;
import com.jme3.input.InputManager;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
import org.jmonkey.utils.Debug;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class AvatarBodyManager extends AbstractPhysicBodyContext
{
 
    private InputManager inputManager;
    private final Node rootNode;
    //
    private final CameraContext cc;
    private final Camera cam;
    private final ChaseCamera chaseCam;
    //
    private final AvatarPhysicBodyContext apbc;
    private final AvatarSpatialBodyContext asbc;
    //
    private final PhysicsCharacter physicBody;
    private final Node avatar;
    private final BetterCharacterControl bcc;
    //
 
    private final PlayerInputActionListener playerInputListener;
 
/**
 
    @param am
    @param rootNode
    @param cc 
    */
    public AvatarBodyManager(AssetManager am, Node rootNode, CameraContext cc)
    {
 
        //
        this.rootNode = rootNode;
        //
        this.asbc = new AvatarSpatialBodyContext(am, rootNode);
        this.apbc = new AvatarPhysicBodyContext();
        //
        this.physicBody = apbc.getPhysicBody();
 
        this.avatar = asbc.getAvatar();
        this.bcc = new BetterCharacterControl(AvatarConstants.COLLISION_SHAPE_RADIUS, 
        AvatarConstants.COLLISION_SHAPE_RADIUS * 2, AvatarConstants.PHYSIC_BODY_MASS);
        //
        this.playerInputListener = new PlayerInputActionListener(this.physicBody, 
        this.asbc.getAvatarMesh());
        //
        this.cc = cc;
        this.cam = cc.getCam();
        this.chaseCam = cc.getChaseCam();
    }
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
        //TODO: initialize your AppState, e.g. attach spatials to rootNode
        //this is called on the OpenGL thread after the AppState has been attached
 
        stateManager.attach(this.asbc);
        stateManager.attach(this.apbc);
        stateManager.attach(this.playerInputListener);
 
 
//
        this.avatar.addControl(new AvatarBodyMoveControl(playerInputListener, physicBody, cam));
        this.avatar.addControl(chaseCam);
        this.avatar.addControl(bcc);
 
        //DEBUG
        Debug.showNodeAxes(app.getAssetManager(), avatar, 4);
        getBulletAppState().getPhysicsSpace().enableDebug(app.getAssetManager());
    }
 
 
 
    @Override
    public void update(float tpf)
    {
        //assert (sceneCameraContext != null);
 
        //correctDirectionVectors(cam.getDirection(), cam.getLeft());
 
    }
}

AvatarBodyMoveControl.java (контроллер движений героя)

package org.jmonkey3.chasecam;
 
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.objects.PhysicsCharacter;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.control.AbstractControl;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class AvatarBodyMoveControl extends AbstractControl
{
    private final Camera cam;
    private final PhysicsCharacter physicBody;
    private final PlayerInputActionListener pial;
/**
 
    @param pial
    @param physicBody
    @param cam 
    */
    public AvatarBodyMoveControl(PlayerInputActionListener pial, 
    PhysicsCharacter physicBody, Camera cam)
    {
        this.pial = pial;
        this.physicBody = physicBody;
        this.cam = cam;
    }
    private final Vector3f walkDirection = new Vector3f();
 
    @Override
    protected void controlUpdate(float tpf)
    {
        //throw new UnsupportedOperationException("Not supported yet."); 
       //To change body of generated methods, choose Tools | Templates.
        correctDirectionVectors();
    }
 
    @Override
    protected void controlRender(RenderManager rm, ViewPort vp)
    {
        //throw new UnsupportedOperationException("Not supported yet."); 
        //To change body of generated methods, choose Tools | Templates.
    }
 
 
        /**
 
     @param camDir
     @param camLeft
     */
    public void correctDirectionVectors()
    {
//        assert (camDir != null);
//        assert (camLeft != null);
//        assert (walkDirection != null);
        //Affect forward, backward move speed 0.6f lower - 1.0f faster
        Vector3f camDirVector = cam.getDirection().clone().multLocal(AvatarConstants.FORWARD_MOVE_SPEED);
        //Affect left, right move speed 0.6f lower - 1.0f faster
        Vector3f camLeftVector = cam.getLeft().clone().multLocal(AvatarConstants.SIDEWARD_MOVE_SPEED);
 
        walkDirection.set(0, 0, 0);//critical
        if (pial.isLeftward())
        {
            walkDirection.addLocal(camLeftVector);
        }
        if (pial.isRightward())
        {
            walkDirection.addLocal(camLeftVector.negate());
        }
        if (pial.isForward())
        {
            walkDirection.addLocal(camDirVector);
        }
        if (pial.isBackward())
        {
            //@TODO Bug if cam direction (0, -n, 0) - character fly upwards 😉
            walkDirection.addLocal(camDirVector.negate());
        }
        physicBody.setWalkDirection(walkDirection);//Critical
 
 
 
        //Avoid vibration
        spatial.setLocalTranslation(physicBody.getPhysicsLocation());
        //Translate Node accordingly
        spatial.getControl(BetterCharacterControl.class).warp(physicBody.getPhysicsLocation());
        //Rotate Node accordingly to camera
        spatial.getControl(
                BetterCharacterControl.class).setViewDirection(
                cam.getDirection().negate());
 
    }
}

AvatarConstants.java (постоянные величины для персонажа)

package org.jmonkey3.chasecam;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class AvatarConstants
{
    public static final float COLLISION_SHAPE_CENTERAL_POINT = 0.0f;
    public static final float COLLISION_SHAPE_RADIUS = 4.0f;
    //
    public static final float PHYSIC_BODY_MASS = 1.0f;
    public static float FORWARD_MOVE_SPEED = 0.8f;
    public static float SIDEWARD_MOVE_SPEED = 0.6f;
}

AvatarPhysicBodyContext.java (физика)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.objects.PhysicsCharacter;
import com.jme3.math.Vector3f;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class AvatarPhysicBodyContext extends AbstractPhysicBodyContext
{
 
 
 
    private final PhysicsCharacter physicBody;
 
 
    public AvatarPhysicBodyContext()
    {
 
        this.physicBody = new PhysicsCharacter(new SphereCollisionShape(AvatarConstants.COLLISION_SHAPE_RADIUS), .01f);
 
    }
 
 
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
//
        assert (getBulletAppState() != null);
        System.out.println(this.getClass().getName() + ".getBulletAppState().hashCode() = " + getBulletAppState().hashCode());
 
//
        this.physicBody.setJumpSpeed(32);
        this.physicBody.setFallSpeed(32);
        this.physicBody.setGravity(32);
        this.physicBody.setPhysicsLocation(new Vector3f(0, 10, 0));
        //
        getBulletAppState().getPhysicsSpace().add(this.physicBody);
 
    }
 
    @Override
    public void update(float tpf)
    {
    }
 
    @Override
    public void cleanup()
    {
        super.cleanup();
    }
 
    /**
     @return the physicBody
     */
    public PhysicsCharacter getPhysicBody()
    {
        return this.physicBody;
    }
}

AvatarSpatialBodyContext.java (модель)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class AvatarSpatialBodyContext extends AbstractSpatialBodyContext
{
 
    //
    private final Node rootNode;
    //
    private final Node avatar;
    private final Spatial avatarMesh;
    private final Vector3f correction;
/**
 
    @param am
    @param rootNode 
    */    
    public AvatarSpatialBodyContext(AssetManager am, Node rootNode)
    {
        this.rootNode = rootNode;
        //
        this.avatar = new Node();
        this.avatarMesh = am.loadModel("Models/Ninja/Ninja.mesh.xml");
        this.correction = new Vector3f(
                0,
                AvatarConstants.COLLISION_SHAPE_CENTERAL_POINT - AvatarConstants.COLLISION_SHAPE_RADIUS,
                0);
    }
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
 
 
        this.avatarMesh.setLocalScale(new Vector3f(0.05f, 0.05f, 0.05f));//Trouble with scales?
        this.avatarMesh.setLocalTranslation(this.correction);
        this.avatar.attachChild(this.avatarMesh);
        this.rootNode.attachChild(this.avatar);
 
        //super.initialize(stateManager, app); //To change body of generated methods, choose Tools | Templates.
    }
 
    /**
     @return the avatar
     */
    public Node getAvatar()
    {
        return avatar;
    }
 
    /**
     * @return the avatarMesh
     */
    public Spatial getAvatarMesh()
    {
        return avatarMesh;
    }
}

CameraContext.java (камера)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.input.ChaseCamera;
import com.jme3.input.FlyByCamera;
import com.jme3.input.InputManager;
import com.jme3.renderer.Camera;
import com.jme3.system.AppSettings;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class CameraContext extends AbstractAppState
{
 
    private final AppSettings settings;
    private final InputManager inputManager;
    /*
     http://hub.jmonkeyengine.org/javadoc/com/jme3/renderer/Camera.html
     public class Camera
     extends java.lang.Object
     implements Savable, java.lang.Cloneable
 
     Width and height are set to the current Application's settings.getWidth() and settings.getHeight() values.
     Frustum Perspective:
     Frame of view angle of 45° along the Y axis
     Aspect ratio of width divided by height
     Near view plane of 1 wu
     Far view plane of 1000 wu
     Start location at (0f, 0f, 10f).
     Start direction is looking at the origin.
     */
    private final Camera cam;
    /*
     http://hub.jmonkeyengine.org/javadoc/com/jme3/input/ChaseCamera.html
     public class ChaseCamera
     extends java.lang.Object
     implements ActionListener, AnalogListener, Control
 
     A camera that follows a spatial and can turn around it by dragging the mouse
     Constructs the chase camera, and registers inputs if you use this 
     constructor you have to attach the cam later to a spatial doing 
     spatial.addControl(chaseCamera);
     */
    private final ChaseCamera chaseCam;
    private final FlyByCamera flyByCam;
 
/**
 
    @param settings
    @param inputManager
    @param cam
    @param flyByCam 
    */
    public CameraContext(AppSettings settings, InputManager inputManager, 
    Camera cam, FlyByCamera flyByCam)
    {
 
        assert (settings != null);
        this.settings = settings;
        assert (inputManager != null);
        this.inputManager = inputManager;
        assert (cam != null);
        this.cam = cam;
        assert (flyByCam != null);
        this.flyByCam = flyByCam;
        this.chaseCam = new ChaseCamera(this.cam, this.inputManager);
    }
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
        super.initialize(stateManager, app);
        //TODO: initialize your AppState, e.g. attach spatials to rootNode
        //this is called on the OpenGL thread after the AppState has been attached
 
        this.cam.setFrustumPerspective(116.0f, (settings.getWidth() / settings.getHeight()), 1.0f, 2000.0f);
        //this.flyByCam.setMoveSpeed(100);
        this.flyByCam.setEnabled(false);
    }
 
    /**
     @return the cam
     */
    public Camera getCam()
    {
        return cam;
    }
 
    /**
     @return the chaseCam
     */
    public ChaseCamera getChaseCam()
    {
        return chaseCam;
    }
}

PlayerInputActionListener.java (слушатель событий для игрока)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.objects.PhysicsCharacter;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.scene.Spatial;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class PlayerInputActionListener extends AbstractAppState implements ActionListener
{
 
    private final PhysicsCharacter physicBody;
//
    private boolean leftward = false;
    private boolean rightward = false;
    private boolean forward = false;
    private boolean backward = false;
    private boolean jump = false;
    private final AvatarAnimationEventListener aael;
/**
 
    @param pc
    @param avatar 
    */
    public PlayerInputActionListener(PhysicsCharacter pc, Spatial avatar)
    {
        this.physicBody = pc;
        this.aael = new AvatarAnimationEventListener(this, this.physicBody, avatar);
    }
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
        stateManager.attach(this.aael);
        //
        app.getInputManager().addMapping("LEFTWARD", new KeyTrigger(KeyInput.KEY_A));
        app.getInputManager().addMapping("RIGHTWARD", new KeyTrigger(KeyInput.KEY_D));
        app.getInputManager().addMapping("FORWARD", new KeyTrigger(KeyInput.KEY_W));
        app.getInputManager().addMapping("BACKWARD", new KeyTrigger(KeyInput.KEY_S));
        app.getInputManager().addMapping("JUMP", new KeyTrigger(KeyInput.KEY_SPACE));
        app.getInputManager().addListener(this, "LEFTWARD");
        app.getInputManager().addListener(this, "RIGHTWARD");
        app.getInputManager().addListener(this, "FORWARD");
        app.getInputManager().addListener(this, "BACKWARD");
        app.getInputManager().addListener(this, "JUMP");
        //
    }
 
    /**
     @param binding
     @param keyPressed
     @param tpf
     */
    public void onAction(String binding, boolean keyPressed, float tpf)
    {
 
        if (binding.equals("LEFTWARD"))
        {
 
            this.leftward = this.aael.getAnimHelper().leftward(keyPressed);
 
        } else if (binding.equals("RIGHTWARD"))
        {
 
            this.rightward = this.aael.getAnimHelper().rightward(keyPressed);
 
        } else if (binding.equals("FORWARD"))
        {
 
            this.forward = this.aael.getAnimHelper().forward(keyPressed);
 
        } else if (binding.equals("BACKWARD"))
        {
 
                this.backward = this.aael.getAnimHelper().backward(keyPressed);
 
        } else if (binding.equals("JUMP"))
        {
 
            this.jump = this.aael.getAnimHelper().jump(keyPressed);
 
        }
    }
 
    /**
     @return the leftward
     */
    public boolean isLeftward()
    {
        return this.leftward;
    }
 
    /**
     @return the rightward
     */
    public boolean isRightward()
    {
        return this.rightward;
    }
 
    /**
     @return the forward
     */
    public boolean isForward()
    {
        return this.forward;
    }
 
    /**
     @return the backward
     */
    public boolean isBackward()
    {
        return this.backward;
    }
 
    /**
     @return the jump
     */
    public boolean isJump()
    {
        return this.jump;
    }
}

SceneBodyManager.java (сцена)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.scene.Node;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class SceneBodyManager extends AbstractPhysicBodyContext
{
 
    private final ScenePhysicBodyContext spbc;
    private final SceneSpatialBodyContext ssbc;
 
/**
 
    @param stateManager
    @param am
    @param rootNode 
    */
    public SceneBodyManager(AppStateManager stateManager, AssetManager am, Node rootNode)
    {
 
 
        this.ssbc = new SceneSpatialBodyContext(am, rootNode);
        this.spbc = new ScenePhysicBodyContext(ssbc.getScene());
    }
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
 
        //PhysicsSpace Initialization
        attachBulletAppstate(stateManager);
//
        stateManager.attach(this.ssbc);
        stateManager.attach(this.spbc);
 
    }
}

ScenePhysicBodyContext.java (физика сцены)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.scene.Node;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class ScenePhysicBodyContext extends AbstractPhysicBodyContext
{
    private final RigidBodyControl rigidBodyControl;
    private final Node scene;
 
/**
 
    @param scene 
    */
    public ScenePhysicBodyContext(Node scene)
    {
        this.scene = scene;
        this.rigidBodyControl = new RigidBodyControl(.0f);       
    }
 
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
        //
        //Add scene to PhysicsSpace
        System.out.println(this.getClass().getName() + ".getBulletAppState().hashCode() = " + getBulletAppState().hashCode());
        scene.addControl(rigidBodyControl);
        getBulletAppState().getPhysicsSpace().addAll(scene);
    }
 
}

SceneSpatialBodyContext.java (модель сцены)

package org.jmonkey3.chasecam;
 
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class SceneSpatialBodyContext extends AbstractSpatialBodyContext
{
 
    private final Node rootNode;
    //
    private final Node scene;
    private AmbientLight ambient;
    private DirectionalLight sun;
/**
 
    @param am
    @param rootNode 
    */
    public SceneSpatialBodyContext(AssetManager am, Node rootNode)
    {
        this.rootNode = rootNode;
        //
        am.registerLocator("town.zip", ZipLocator.class);
        this.scene = (Node) am.loadModel("main.scene");
        this.ambient = new AmbientLight();
        this.sun = new DirectionalLight();
    }
 
    @Override
    public void initialize(AppStateManager stateManager, Application app)
    {
        //Main Scene loading
 
        this.scene.setLocalScale(0.1f);
        this.scene.scale(32.0f);
        //
        this.sun.setDirection(new Vector3f(1.4f, -1.4f, -1.4f));
        this.scene.setLocalTranslation(Vector3f.ZERO);
        //
 
        rootNode.attachChild(this.scene);
        rootNode.addLight(this.ambient);
        rootNode.addLight(this.sun);
    }
 
    /**
     @return the scene
     */
    public Node getScene()
    {
        return scene;
    }
}

TheGame.java (игра)

package org.jmonkey3.chasecam;
 
import com.jme3.app.SimpleApplication;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class TheGame extends SimpleApplication
{
 
    private ApplicationContext applicationContext;
 
    public TheGame()
    {
    }
 
    //
    public static void main(String[] args)
    {
        TheGame game = new TheGame();
        game.setShowSettings(false);
        game.start();
    }
 
    @Override
    public void simpleInitApp()
    {
        this.applicationContext = new ApplicationContext(stateManager, assetManager, settings, 
        inputManager, rootNode, cam, flyCam);
        //
        stateManager.attach(applicationContext);     
    }
}

Debug.java (оладчик)

package org.jmonkey.utils;
 
import com.jme3.animation.AnimControl;
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.debug.Arrow;
import com.jme3.scene.debug.Grid;
import com.jme3.scene.debug.SkeletonDebugger;
import com.jme3.scene.shape.Line;
import static org.jmonkey.utils.SpatialUtils.makeGeometry;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class Debug
{
 
    public static void showNodeAxes(AssetManager am, Node n, float axisLen)
    {
        Vector3f v = new Vector3f(axisLen, 0, 0);
        Arrow a = new Arrow(v);
        Material mat = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Red);
        Geometry geom = new Geometry(n.getName() + "XAxis", a);
        geom.setMaterial(mat);
        n.attachChild(geom);
 
 
        //
        v = new Vector3f(0, axisLen, 0);
        a = new Arrow(v);
        mat = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Green);
        geom = new Geometry(n.getName() + "YAxis", a);
        geom.setMaterial(mat);
        n.attachChild(geom);
 
 
        //
        v = new Vector3f(0, 0, axisLen);
        a = new Arrow(v);
        mat = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        geom = new Geometry(n.getName() + "ZAxis", a);
        geom.setMaterial(mat);
        n.attachChild(geom);
    }
 
    //
    public static void showVector3fArrow(AssetManager am, Node n, Vector3f v, ColorRGBA color, String name)
    {
        Arrow a = new Arrow(v);
        Material mat = MaterialUtils.makeMaterial(am, "Common/MatDefs/Misc/Unshaded.j3md", color);
        Geometry geom = makeGeometry(a, mat, name);
        n.attachChild(geom);
    }
 
    public static void showVector3fLine(AssetManager am, Node n, Vector3f v, ColorRGBA color, String name)
    {
        Line l = new Line(v.subtract(v), v);
        Material mat = MaterialUtils.makeMaterial(am, "Common/MatDefs/Misc/Unshaded.j3md", color);
        Geometry geom = makeGeometry(l, mat, name);
        n.attachChild(geom);
    }
 
//Skeleton Debugger
    public static void attachSkeleton(AssetManager am, Node player, AnimControl control)
    {
        SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton", control.getSkeleton());
        Material mat2 = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
        mat2.setColor("Color", ColorRGBA.Yellow);
        mat2.getAdditionalRenderState().setDepthTest(false);
        skeletonDebug.setMaterial(mat2);
        player.attachChild(skeletonDebug);
    }
 
    ///
    public static void attachWireFrameDebugGrid(AssetManager assetManager, Node n, 
    Vector3f pos, Integer size, ColorRGBA color)
    {
        Geometry g = new Geometry("wireFrameDebugGrid", new Grid(size, size, 1.0f));//1WU
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.getAdditionalRenderState().setWireframe(true);
        mat.setColor("Color", color);
        g.setMaterial(mat);
        g.center().move(pos);
        n.attachChild(g);
    }
}

MaterialUtils.java (материал)

package org.jmonkey.utils;
 
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
 
/*
 Chase camera (aka 3rd person camera) example
 Based on official TestQ3.java
 
 @author Alex Cham aka Jcrypto
 */
public class MaterialUtils
{
 
    public MaterialUtils()
    {
    }
 
 
    //"Common/MatDefs/Misc/Unshaded.j3md"
    public static Material makeMaterial(AssetManager am, String name, ColorRGBA color)
    {
        Material mat = new Material(am, name);
        mat.setColor("Color", color);
        return mat;
    }
}

SpatialUtils.java (спатиал)

package org.jmonkey.utils;
 
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
 
/**
 
 @author java
 */
public class SpatialUtils
{
    //
    public static Node makeNode(String name)
    {
        Node n = new Node(name);
        return n;
    }
 
//
    public static Geometry makeGeometry(Mesh mesh, Material mat, String name)
    {
        Geometry geom = new Geometry(name, mesh);
        geom.setMaterial(mat);
        return geom;
    }
 
    //
    public static Geometry makeGeometry(Vector3f loc, Vector3f scl, Mesh mesh, Material mat, String name)
    {
        Geometry geom = new Geometry(name, mesh);
        geom.setMaterial(mat);
        geom.setLocalTranslation(loc);
        geom.setLocalScale(scl);
        return geom;
    }
}

Переведено для jmonkeyengine.ru, оригинал.
Автор перевода: BuGaGa

Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.