天气有点冷,早上竟然出奇般的七点多就起床了,呵呵~~
6.4、Actions
在第五课,我们创建一个InputHandler,它调用了4个分开的InputAction:KeyNodeForwardAction,KeyNodeBackwardAction,KeyTurnLeftAction,KeyTurnRightAction。我们现在将编写我们自定义的Action去使用新的Vehicle类。
首先,我们想用一个加速vehicle的action替换KeyNodeForwardAction。我决定创建5个新的InputAction(比之前多了一个)。所以,为了替换keyNodeForwardAction,我们将创建AccelerateAction。
我们不再需要关心action的速度,因为这是由vehicle决定的。我们只需要在action执行的时候更新它的速度,然后基于这个新的速度移动vehicle。
public void 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之外。
public void 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正在后退,所以转弯的效果将相反。
public void 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();
}
和
public void 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方法并更新位置。
public void 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
*
*/
public class 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 用于控制的结点
*/
private void 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
*/
private void 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
public void 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;
public class AccelerateAction extends InputAction {
private Vehicle node;
private Vector3f tempVa=new Vector3f();
public AccelerateAction(Vehicle node){
this.node = node;
}
@Override
public void 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;
public class BrakeAction extends InputAction {
private Vehicle node;
private Vector3f tempVa=new Vector3f();
public BrakeAction(Vehicle node){
this.node = node;
}
@Override
public void 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;
public class VehicleRotateLeftAction extends InputAction {
//处理旋转的临时变量
private static final Matrix3f incr = new Matrix3f();
private static final Matrix3f tempMa = new Matrix3f();
private static final Matrix3f tempMb = new Matrix3f();
//我们使用Y轴作为上
private Vector3f upAxis = new Vector3f(0,1,0);
//操纵的结点
private Vehicle vehicle;
public VehicleRotateLeftAction(Vehicle vehicle){
this.vehicle = vehicle;
}
@Override
public void 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;
public class VehicleRotateRightAction extends InputAction {
//用于处理旋转的临时变量
private static final Matrix3f incr = new Matrix3f();
private static final Matrix3f tempMa = new Matrix3f();
private static final Matrix3f tempMb = new Matrix3f();
//用于操作的结点
private Vehicle vehicle;
private Vector3f upAxis = new Vector3f(0, 1, 0);
public VehicleRotateRightAction(Vehicle vehicle){
this.vehicle = vehicle;
}
@Override
public void 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;
public class DriftAction extends InputAction {
private Vehicle vehicle;
private Vector3f tempVa = new Vector3f();
public DriftAction(Vehicle vehicle) {
this.vehicle = vehicle;
}
@Override
public void 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和图形外观。
分享到:
相关推荐
FlagRush6——控制交通工具 FlagRush7——拥抱大地让我们驾驶的不再是Box FlagRush8——增加随机的Flag FlagRush9——墙壁检测系统(Detection System) FlagRush10——墙壁检测系统(Detection System) 如果确实...
6、 控制交通工具 74 6.1、介绍 74 6.2、增加一个交通工具 74 6.3、Vehicle.java 76 6.4、Actions 79 6.5、FlagRushHandler.java 81 6.6、AccelerateAction.java 83 6.7、BrakeAction.java 84 6.8、...
jmonkeyengine是一个面向冒险的java开发人员的三维游戏引擎。它是开源的、跨平台的、尖端的。3.2.4是jmonkeyengine 3 sdk的最新稳定版本,是一个完整的游戏开发套件。我们将发布3.2.x更新,直到主要的3.3版本到来。
Jmonkeyengine 3.0 Beginners Guide
jMonkeyEngine(jME)是一个开源的Java 3D引擎,它的效果非常好,速度也不错
sdk, 在netbeans上,基于 jMonkeyEngine3 SDK jMonkeyEngine软件开发工具包( SDK ) 欢迎使用jMonkeyEngine软件开发工具包( SDK )的知识库。 这个SDK使用jMonkeyEngine简化了 3D 个应用程序的开发。 它包含开发完整...
NULL 博文链接:https://hjk685.iteye.com/blog/1912303
jMonkeyEngine 3.0 Beginner's Guide
jmonkeyengine, 在Java中,一个完整的3D 游戏开发 jMonkeyEngine jMonkeyEngine是一款用于冒险Java开发人员的3D 游戏引擎。 它是开放的,跨平台的,和cutting的。 3.2.0是 jMonkeyEngine 3 SDK的最新稳定版本,一个...
共12章JME中文教程,演示代码经测试无错
jmonkeyengine:纯Java编写的一个完整的3D游戏开发套件
NULL 博文链接:https://snake.iteye.com/blog/578982
jMonkeyEngine软件开发套件(SDK) 欢迎使用jMonkeyEngine软件开发套件(SDK)的存储库。 该SDK简化了使用jMonkeyEngine开发3D应用程序的过程。 它包含开发完整应用程序所需的一切。 我们的SDK(或jmonkeyplatform...
JME学习文档 中文版 jMonkeyEngine 入门学习
SimpleJmonkeyGame引言由JmonkeyEngine开发的3D游戏Scenerio。 在此简单游戏中导入的3D动画由Blender制作。脚步使用Blender制作3D鱼动画,包括向前游泳,静止的闲置动画和180度转弯动画。 将Blender模型导入Jmonkey ...
jMonkeyEngine是一个众所周知且广泛使用的免费开放源代码游戏引擎。 该演示应用程序展示了最新的jME版本jME 3的功能和某些功能。jMonkeyEngine使用OpenGL作为其图形库。 该软件包含的一些功能包括:粒子效果,水渲染...
赛车游戏 使用 JMonkeyEngine 创建的赛车游戏。 汽车的转向非常僵硬。 按住 F 将车轮摩擦设置为 0 并改为漂移。