thirdpersonhandler.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 633 行 · 第 1/2 页
JAVA
633 行
/*
* Copyright (c) 2003-2009 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme.input;
import java.util.HashMap;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
import com.jme.input.thirdperson.MovementPermitter;
import com.jme.input.thirdperson.ThirdPersonBackwardAction;
import com.jme.input.thirdperson.ThirdPersonForwardAction;
import com.jme.input.thirdperson.ThirdPersonJoystickPlugin;
import com.jme.input.thirdperson.ThirdPersonLeftAction;
import com.jme.input.thirdperson.ThirdPersonRightAction;
import com.jme.input.thirdperson.ThirdPersonStrafeLeftAction;
import com.jme.input.thirdperson.ThirdPersonStrafeRightAction;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.scene.Spatial;
/**
* <code>ThirdPersonHandler</code> defines an InputHandler that sets input to
* be controlled similar to games such as Zelda Windwaker and Mario 64, etc.
*
* @author <a href="mailto:josh@renanse.com">Joshua Slack</a>
* @version $Revision: 1.30 $
*/
public class ThirdPersonHandler extends InputHandler {
public static final String PROP_TURNSPEED = "turnSpeed";
public static final String PROP_DOGRADUAL = "doGradual";
public static final String PROP_ROTATEONLY = "rotateOnly";
public static final String PROP_PERMITTER = "permitter";
public static final String PROP_UPVECTOR = "upVector";
public static final String PROP_LOCKBACKWARDS = "lockBackwards";
public static final String PROP_CAMERAALIGNEDMOVE = "cameraAlignedMovement";
public static final String PROP_STRAFETARGETALIGN = "targetAlignStrafe";
public static final String PROP_KEY_FORWARD = "fwdKey";
public static final String PROP_KEY_BACKWARD = "backKey";
public static final String PROP_KEY_LEFT = "leftKey";
public static final String PROP_KEY_RIGHT = "rightKey";
public static final String PROP_KEY_STRAFELEFT = "strfLeftKey";
public static final String PROP_KEY_STRAFERIGHT = "strfRightKey";
/** Default character turn speed is 1.5pi per sec. */
public static final float DEFAULT_TURNSPEED = 1.5f * FastMath.PI;
public static float angleEpsilon = 0.001f;
protected float speed = 0;
/** The Spatial we are controlling with this handler. */
protected Spatial targetSpatial;
/**
* The previous location of the target node... used to maintain where the
* node is before actions are run. This allows a comparison to see where the
* node wants to be taken.
*/
protected Vector3f prevLoc = new Vector3f();
/**
* The previous rotation of the target node... used to maintain the node's
* rotation before actions are run. This is used when target aligned
* movement is used and strafing is done.
*/
protected Quaternion prevRot = new Quaternion();
/**
* Stores the new location of the node after actions. used internally by
* update method
*/
protected Vector3f loc = new Vector3f();
/**
* The current facing direction of the controlled target in radians in terms
* of relationship to the world.
*/
protected float faceAngle;
/**
* How fast the character can turn per second. Used when doGradualRotation
* is set to true.
*/
protected float turnSpeed = DEFAULT_TURNSPEED;
/**
* When true, the controlled target will do turns by moving forward and
* turning at the same time. When false, a turn will cause immediate
* rotation to the given angle.
*/
protected boolean doGradualRotation = true;
/**
* When not null, gives a means for denying movement to the controller. See
* MovementPermitter javadoc for more.
*/
protected MovementPermitter permitter;
/** World up vector. Currently 0,1,0 is the only guarenteed value to work. */
protected Vector3f upVector = new Vector3f(0, 1, 0);
/** An internal vector used for calculations to prevent object creation. */
protected Vector3f calcVector = new Vector3f();
/** The camera this handler uses for determining action movement. */
protected Camera camera;
/**
* if true, backwards movement will not cause the target to rotate around to
* point backwards. (useful for vehicle movement) Default is false.
*/
protected boolean lockBackwards;
/**
* if true, strafe movements will always be target aligned, even if other
* movement is camera aligned. Default is false.
*/
protected boolean strafeAlignTarget;
/**
* if true, left and right keys will rotate the target instead of moving them.
* Default is false.
*/
protected boolean rotateOnly;
/**
* if true, movements of the character are in relation to the current camera
* view. If false, they are in relation to the current target's facing
* vector. Default is true.
*/
protected boolean cameraAlignedMovement;
/**
* internally used boolean for denoting that a backwards action is currently
* being performed.
*/
protected boolean walkingBackwards;
/**
* internally used boolean for denoting that a forward action is currently
* being performed.
*/
protected boolean walkingForward;
/**
* internally used boolean for denoting that a turning action is currently
* being performed.
*/
protected boolean nowTurning;
/**
* internally used boolean for denoting that a turning action is currently
* being performed.
*/
protected boolean nowStrafing;
protected ThirdPersonJoystickPlugin plugin = null;
protected KeyInputAction actionForward;
protected KeyInputAction actionBack;
protected KeyInputAction actionRight;
protected KeyInputAction actionLeft;
protected KeyInputAction actionStrafeRight;
protected KeyInputAction actionStrafeLeft;
/**
* Basic constructor for the ThirdPersonHandler. Sets all non specified args
* to their defaults.
*
* @param target
* the target to move
* @param cam
* the camera for movements to be in relation to
*/
public ThirdPersonHandler(Spatial target, Camera cam) {
this(target, cam, null);
}
/**
* Full constructor for the ThirdPersonHandler. Properties in the props arg
* will be used to set handler fields if set, otherwise default values are
* used.
*
* @param target
* the target to move
* @param cam
* the camera for movements to be in relation to
* @param props
* a hashmap of properties used to set handler characteristics
* where the key is one of this class's static PROP_XXXX fields.
*/
public ThirdPersonHandler(Spatial target, Camera cam, HashMap<String, Object> props) {
this.targetSpatial = target;
this.camera = cam;
updateProperties(props);
setActions();
}
/**
*
* <code>setProperties</code> sets up class fields from the given hashmap.
* It also calls updateKeyBindings for you.
*
* @param props
*/
public void updateProperties(HashMap<String, Object> props) {
turnSpeed = getFloatProp(props, PROP_TURNSPEED, DEFAULT_TURNSPEED);
doGradualRotation = getBooleanProp(props, PROP_DOGRADUAL, true);
lockBackwards = getBooleanProp(props, PROP_LOCKBACKWARDS, false);
strafeAlignTarget = getBooleanProp(props, PROP_STRAFETARGETALIGN, false);
cameraAlignedMovement = getBooleanProp(props, PROP_CAMERAALIGNEDMOVE, true);
rotateOnly = getBooleanProp(props, PROP_ROTATEONLY, false);
permitter = (MovementPermitter)getObjectProp(props, PROP_PERMITTER, null);
upVector = (Vector3f)getObjectProp(props, PROP_UPVECTOR, Vector3f.UNIT_Y.clone());
updateKeyBindings(props);
}
/**
*
* <code>updateKeyBindings</code> allows a user to update the keys mapped to the various actions.
*
* @param props
*/
public void updateKeyBindings(HashMap<String, Object> props) {
KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager();
keyboard.set(PROP_KEY_FORWARD, getIntProp(props, PROP_KEY_FORWARD, KeyInput.KEY_W));
keyboard.set(PROP_KEY_BACKWARD, getIntProp(props, PROP_KEY_BACKWARD, KeyInput.KEY_S));
keyboard.set(PROP_KEY_LEFT, getIntProp(props, PROP_KEY_LEFT, KeyInput.KEY_A));
keyboard.set(PROP_KEY_RIGHT, getIntProp(props, PROP_KEY_RIGHT, KeyInput.KEY_D));
keyboard.set(PROP_KEY_STRAFELEFT, getIntProp(props, PROP_KEY_STRAFELEFT, KeyInput.KEY_Q));
keyboard.set(PROP_KEY_STRAFERIGHT, getIntProp(props, PROP_KEY_STRAFERIGHT, KeyInput.KEY_E));
}
/**
*
* <code>setActions</code> sets the keyboard actions with the
* corresponding key command.
*
*/
protected void setActions() {
actionForward = new ThirdPersonForwardAction( this, 100f );
actionBack = new ThirdPersonBackwardAction( this, 100f );
actionRight = new ThirdPersonRightAction( this, 100f );
actionLeft = new ThirdPersonLeftAction( this, 100f );
actionStrafeRight = new ThirdPersonStrafeRightAction( this, 100f );
actionStrafeLeft = new ThirdPersonStrafeLeftAction( this, 100f );
addAction( actionForward, PROP_KEY_FORWARD, true );
addAction( actionBack, PROP_KEY_BACKWARD, true );
addAction( actionRight, PROP_KEY_RIGHT, true );
addAction( actionLeft, PROP_KEY_LEFT, true );
addAction( actionStrafeRight, PROP_KEY_STRAFERIGHT, true );
addAction( actionStrafeLeft, PROP_KEY_STRAFELEFT, true );
}
/**
* <code>update</code> updates the position and rotation of the target
* based on the movement requested by the user.
*
* @param time
* @see com.jme.input.InputHandler#update(float)
*/
public void update(float time) {
if ( !isEnabled() ) return;
walkingForward = false;
walkingBackwards = false;
nowTurning = false;
nowStrafing = false;
prevLoc.set(targetSpatial.getLocalTranslation());
loc.set(prevLoc);
doInputUpdate(time);
if (walkingBackwards && walkingForward && !nowStrafing && !nowTurning) {
targetSpatial.getLocalTranslation().set(prevLoc);
return;
}
targetSpatial.getLocalTranslation().subtract(loc, loc);
if (!loc.equals(Vector3f.ZERO)) {
float distance = loc.length();
if (distance != 0 && distance != 1.0f)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?