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

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

 

6.4Actions

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

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

    }

 

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

 

    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漂移。然而,这个逻辑有点瑕疵,这就给读者作为练习去弄清那是什么。一点暗示,当玩家按下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

 *

 */

public class 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 用于控制的结点

     */

    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.6AccelerateAction.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.7BrakeAction.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.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;

 

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

 

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.10DriftAction.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);

    }

}

6.11、总结

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

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

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值