天氣有點冷,早上竟然出奇般的七點多就起床了,呵呵~~ 6.4 、 Actions 在第五課,我們創建一個 InputHandler ,它調用了 4 個分開的 InputAction : KeyNodeForwardAction , KeyNodeBackwardAction , KeyTurnLeftAction , KeyTurnRightAction 。我們現
天氣有點冷,早上竟然出奇般的七點多就起床了,呵呵~~
在第五課,我們創建一個InputHandler,它調用了4個分開的InputAction:KeyNodeForwardAction,KeyNodeBackwardAction,KeyTurnLeftAction,KeyTurnRightAction。我們現在將編寫我們自定義的Action去使用新的Vehicle類。
首先,我們想用一個加速vehicle的action替換KeyNodeForwardAction。我決定創建5個新的InputAction(比之前多了一個)。所以,為了替換keyNodeForwardAction,我們將創建AccelerateAction。
我們不再需要關心action的速度,因為這是由vehicle決定的。我們只需要在action執行的時候更新它的速度,然后基于這個新的速度移動vehicle。
publicvoid performAction(InputActionEvent e) {
node.accerate(e.getTime());
Vector3f loc = node.getLocalTranslation();
loc.addLocal(
node.getLocalRotation().getRotationColumn(2,tempVa)
.multLocal(node.getVelocity()*e.getTime())
);
node.setLocalTranslation(loc);
}
正如你看到的,我們僅僅調用Vehicle的accelerate方法(AccelerateAction也在構造期間接收一個Vehicle對象,而不是Node),然后改變它的移動。
BrakeAction也一樣,除了我們叫它brake之外。
publicvoid performAction(InputActionEvent e) {
node.brake(e.getTime());
Vector3f loc = node.getLocalTranslation();
loc.addLocal(
node.getLocalRotation().getRotationColumn(2,tempVa)
.multLocal(node.getVelocity()*e.getTime())
);
node.setLocalTranslation(loc);
}
這些action現在將允許我們加速和停止vehicle。現在我們需要允許它轉彎。正如你可能猜到它和KeyNodeTurn*Action類是一樣的,除了我們使用Vehicle的轉彎速度代替action的速度。一點不同的是我加入了判斷我們的速度是正的還是負的。如果它是正的,那么我們正常工作,但如果它是負的,Vehicle正在后退,所以轉彎的效果將相反。
publicvoid performAction(InputActionEvent evt) {
//我們想轉不同的方向,這取決于我們往哪個方向行駛
if(vehicle.getVelocity() < 0) {
incr.fromAngleNormalAxis(
-vehicle.getTurnSpeed() * evt.getTime()
, upAxis
);
} else {
incr.fromAngleNormalAxis(
vehicle.getTurnSpeed() * evt.getTime(),
upAxis
);
}
vehicle.getLocalRotation().fromRotationMatrix(
incr.mult(
vehicle.getLocalRotation()
.toRotationMatrix(tempMa),
tempMb
)
);
vehicle.getLocalRotation().normalize();
}
和
publicvoid performAction(InputActionEvent evt) {
if (vehicle.getVelocity() < 0) {
incr.fromAngleNormalAxis(
vehicle.getTurnSpeed() * evt.getTime(),
upAxis
);
} else {
incr.fromAngleNormalAxis(
-vehicle.getTurnSpeed() * evt.getTime(),
upAxis
);
}
vehicle.getLocalRotation().fromRotationMatrix(
incr.mult(
vehicle.getLocalRotation()
.toRotationMatrix(tempMa),
tempMb
)
);
vehicle.getLocalRotation().normalize();
}
我們最后的InputAction將處理vehicle的漂移。這個action是不同的,因為它不會由key觸發,但在每次update都發生。這將在下一節講到。現在,我們調用Vehicle的drift方法并更新位置。
publicvoid performAction(InputActionEvent evt) {
vehicle.drift(evt.getTime());
Vector3f loc = vehicle.getLocalTranslation();
loc.addLocal(
vehicle.getLocalRotation()
.getRotationColumn(2, tempVa)
.multLocal(
vehicle.getVelocity() * evt.getTime()
)
);
vehicle.setLocalTranslation(loc);
}
你可能注意到一堆重復的代碼。相當于大多類都做相同的事情,只是調用vehicle不同的方法。下一節,我們將清理并優化。
既然我們現在已經有了我們5個新的aciton,我們需要在FlagRushHandler中調用它們。我們將賦予相同的鍵(WASD)。
所以在setActions方法中我們只是創建4個移動action,傳入vehicle對象作為參數。
Drift也被實例化而并沒有賦給一個觸發器。這是因為我們現在覆蓋了update方法。update調用super去檢查其他常規action,然后調用drift action。這確保了當沒有鍵被按下時drift漂移。然而,這個邏輯有點瑕疵,這就給讀者作為練習去弄清那是什么。一點暗示,當玩家按下W或S的時候發生了什么?我將在下一節課修復和討論這個瑕疵。是的,我現在給出作業了。
import lesson6.actions.AccelerateAction;
import lesson6.actions.DriftAction;
import lesson6.actions.VehicleRotateLeftAction;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.action.KeyNodeBackwardAction;
import com.jme.input.action.KeyNodeRotateRightAction;
/**
* 游戲的InputHnadler。這控制了一個給出的Spatial
* 允許我們去把它往前移、往后移和左右旋轉。
* @author John
*
*/
publicclass FlagRushInputHandler extends InputHandler {
private DriftAction drift;
/**
* 提供用于控制的node。api將處理input的創建
* @param node 我們想移動的那個node
* @param api library將處理input的創建
*/
public FlagRushInputHandler(Vehicle node, String api){
setKeyBindings(api);
setActions(node);
}
/**
* 將action類賦給trigger。這些action處理結點前移、后移和旋轉
* @param node 用于控制的結點
*/
privatevoid setActions(Vehicle node) {
AccelerateAction forward =
new AccelerateAction(node);
addAction(forward,"forward",true);
KeyNodeBackwardAction backward =
new KeyNodeBackwardAction(node,15f);
addAction(backward,"backward",true);
VehicleRotateLeftAction rotateLeft =
new VehicleRotateLeftAction(node);
addAction(rotateLeft,"turnLeft",true);
KeyNodeRotateRightAction rotateRight =
new KeyNodeRotateRightAction(node,5f);
rotateRight.setLockAxis(
node.getLocalRotation().getRotationColumn(1)
);
addAction(rotateRight,"turnRight",true);
//不由key觸發
drift = new DriftAction(node);
}
/**
* 創建keyboard對象,當鍵被按下時允許我們獲取鍵盤的值。
* 它接著設置action作為觸發器的基礎,如果確認了鍵被按下(WASD)
* @param api
*/
privatevoid setKeyBindings(String api) {
KeyBindingManager keyboard =
KeyBindingManager.getKeyBindingManager();
keyboard.set("forward", KeyInput.KEY_W);
keyboard.set("backward", KeyInput.KEY_S);
keyboard.set("turnLeft", KeyInput.KEY_A);
keyboard.set("turnRight", KeyInput.KEY_D);
}
@Override
publicvoid update(float time) {
if(!isEnabled()) return;
super.update(time);
//我們通常想讓摩擦力控制漂移
drift.performAction(event);
}
}
import lesson6.Vehicle;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.math.Vector3f;
publicclass AccelerateAction extends InputAction {
private Vehicle node;
private Vector3f tempVa=new Vector3f();
public AccelerateAction(Vehicle node){
this.node = node;
}
@Override
publicvoid performAction(InputActionEvent e) {
node.accerate(e.getTime());
Vector3f loc = node.getLocalTranslation();
loc.addLocal(
node.getLocalRotation().getRotationColumn(2,tempVa)
.multLocal(node.getVelocity()*e.getTime())
);
node.setLocalTranslation(loc);
}
}
import lesson6.Vehicle;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.math.Vector3f;
publicclass BrakeAction extends InputAction {
private Vehicle node;
private Vector3f tempVa=new Vector3f();
public BrakeAction(Vehicle node){
this.node = node;
}
@Override
publicvoid performAction(InputActionEvent e) {
node.brake(e.getTime());
Vector3f loc = node.getLocalTranslation();
loc.addLocal(
node.getLocalRotation().getRotationColumn(2,tempVa)
.multLocal(node.getVelocity()*e.getTime())
);
node.setLocalTranslation(loc);
}
}
import lesson6.Vehicle;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.math.Matrix3f;
import com.jme.math.Vector3f;
publicclass VehicleRotateLeftAction extends InputAction {
//處理旋轉的臨時變量
privatestaticfinal Matrix3f incr = new Matrix3f();
privatestaticfinal Matrix3f tempMa = new Matrix3f();
privatestaticfinal Matrix3f tempMb = new Matrix3f();
//我們使用Y軸作為上
private Vector3f upAxis = new Vector3f(0,1,0);
//操縱的結點
private Vehicle vehicle;
public VehicleRotateLeftAction(Vehicle vehicle){
this.vehicle = vehicle;
}
@Override
publicvoid performAction(InputActionEvent evt) {
//我們想轉不同的方向,這取決于我們往哪個方向行駛
if(vehicle.getVelocity() < 0) {
incr.fromAngleNormalAxis(
-vehicle.getTurnSpeed() * evt.getTime()
, upAxis
);
} else {
incr.fromAngleNormalAxis(
vehicle.getTurnSpeed() * evt.getTime(),
upAxis
);
}
vehicle.getLocalRotation().fromRotationMatrix(
incr.mult(
vehicle.getLocalRotation()
.toRotationMatrix(tempMa),
tempMb
)
);
vehicle.getLocalRotation().normalize();
}
}
import lesson6.Vehicle;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.math.Matrix3f;
import com.jme.math.Vector3f;
publicclass VehicleRotateRightAction extends InputAction {
//用于處理旋轉的臨時變量
privatestaticfinal Matrix3f incr = new Matrix3f();
privatestaticfinal Matrix3f tempMa = new Matrix3f();
privatestaticfinal Matrix3f tempMb = new Matrix3f();
//用于操作的結點
private Vehicle vehicle;
private Vector3f upAxis = new Vector3f(0, 1, 0);
public VehicleRotateRightAction(Vehicle vehicle){
this.vehicle = vehicle;
}
@Override
publicvoid performAction(InputActionEvent evt) {
if (vehicle.getVelocity() < 0) {
incr.fromAngleNormalAxis(
vehicle.getTurnSpeed() * evt.getTime(),
upAxis
);
} else {
incr.fromAngleNormalAxis(
-vehicle.getTurnSpeed() * evt.getTime(),
upAxis
);
}
vehicle.getLocalRotation().fromRotationMatrix(
incr.mult(
vehicle.getLocalRotation()
.toRotationMatrix(tempMa),
tempMb
)
);
vehicle.getLocalRotation().normalize();
}
}
import lesson6.Vehicle;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.math.Vector3f;
publicclass DriftAction extends InputAction {
private Vehicle vehicle;
private Vector3f tempVa = new Vector3f();
public DriftAction(Vehicle vehicle) {
this.vehicle = vehicle;
}
@Override
publicvoid performAction(InputActionEvent evt) {
vehicle.drift(evt.getTime());
Vector3f loc = vehicle.getLocalTranslation();
loc.addLocal(
vehicle.getLocalRotation()
.getRotationColumn(2, tempVa)
.multLocal(
vehicle.getVelocity() * evt.getTime()
)
);
vehicle.setLocalTranslation(loc);
}
}
就那樣,我們現在已經創建自己的action去允許我們的vehicle以一種更真實的方式運行。這將給我們一種控制玩家執行特性的能力,包括后面的敵人。
下一步,我們將看看改善terrain和圖形外觀。
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com