欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

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

程序员文章站 2022-05-13 07:54:30
...

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

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

6.4Actions

在第五课,我们创建一个InputHandler,它调用了4个分开的InputActionKeyNodeForwardActionKeyNodeBackwardActionKeyTurnLeftActionKeyTurnRightAction。我们现在将编写我们自定义的Action去使用新的Vehicle类。

首先,我们想用一个加速vehicleaction替换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);

}

正如你看到的,我们仅仅调用Vehicleaccelerate方法(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()

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

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都发生。这将在下一节讲到。现在,我们调用Vehicledrift方法并更新位置。

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漂移。然而,这个逻辑有点瑕疵,这就给读者作为练习去弄清那是什么。一点暗示,当玩家按下WS的时候发生了什么?我将在下一节课修复和讨论这个瑕疵。是的,我现在给出作业了。

6.5FlagRushHandler.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;

/**

* 提供用于控制的nodeapi将处理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.6AccelerateAction.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.7BrakeAction.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.8VehicleRotateLeftAction.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()

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.9VehicleRotateRightAction.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()

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.10DriftAction.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和图形外观。