您的当前位置:首页正文

jMonkeyEngine译文FlagRush6(2)控制交通工具

2020-11-09 来源:汇智旅游网

天气有点冷,早上竟然出奇般的七点多就起床了,呵呵~~ 6.4 、 Actions 在第五课,我们创建一个 InputHandler ,它调用了 4 个分开的 InputAction : KeyNodeForwardAction , KeyNodeBackwardAction , KeyTurnLeftAction , KeyTurnRightAction 。我们现

天气有点冷,早上竟然出奇般的七点多就起床了,呵呵~~

6.4、Actions

在第五课,我们创建一个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的时候发生了什么?我将在下一节课修复和讨论这个瑕疵。是的,我现在给出作业了。

6.5、FlagRushHandler.java

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);

}

}

6.6、AccelerateAction.java

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);

}

}

6.7、BrakeAction.java

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);

}

}

6.8、VehicleRotateLeftAction.java

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();

}

}

6.9、VehicleRotateRightAction.java

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();

}

}

6.10、DriftAction.java

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);

}

}

6.11、总结

就那样,我们现在已经创建自己的action去允许我们的vehicle以一种更真实的方式运行。这将给我们一种控制玩家执行特性的能力,包括后面的敌人。

下一步,我们将看看改善terrain和图形外观。

显示全文