在babylon.js中,通过键盘控制实现类似吃鸡中的汽车控制--以赛车为例

一.前言

我们在玩一些通过键盘和鼠标控制模型移动的游戏,例如赛车类的或者人物之类(比如吃鸡吧),没有注意到模型运动的时候有一些特征。这些都是比较简单逻辑没有涉及到物理引擎,而实际开发中会用到物理引擎,比如刚体运动,限制,软体啥等,车子的运动也是通过施加力的作用让它加速或者旋转,这里就不详细展开说了。顺便说一下babylon.js的用到的HK物理引擎真的太棒了,但是遇到了一点小bug,希望官方快点修复

一、当我们往前移动的时候或者只有角速度的时候,汽车的速度是由0慢慢加速然后打到一个速度最大值后速度就不再增加;当我们停止前进,车子就会慢慢减速直到停止;

二、当汽车在在左右旋转的时候,如果车子没有移动(指的是前进),车子是没有办法旋转的,也就是绕着车子整体的Y轴(上方向)旋转,而且汽车在拐弯的时候,它旋转的角速度和线路度是呈正相关的;

三、车轮的转速和旋转的方向和当前车子速度也有关系,我们只需给车轮增加一个绕着车轮本地坐标的Z轴方向一个旋转动画即可

四、当车子前进速度很快,却想让快速停下来可以按下后退来实现刹车效果,比如前进速度很快时,可以按下后退实现刹车;当后退速度很快可以按下前进来实现反向刹车

好了,分析完毕我们开始吧

1.对于场景必要的比如,渲染引擎、相机、灯光、模型加载啥的这些基本都是必须的就不写了

补充说明:我们需要两台相机,一个是第一人称的,另一个是和车子绑定的

 // 车轮动画
 this.tireAnimationGroup = new AnimationGroup('tireGroupAnimation')
 this.tireAnimation = initTireAnimation()
 // 键盘事件
 var inputMap: any = {};

 // 初始值
 var carSpeed = 0;
 const acceleration = 0.002
 var carRotationSpeed = 0.02;
 const maxSpeed = 0.8

 const braker = (keydown: boolean) => {
 // 阻力作用下停车
  if (keydown === false && carSpeed > 0) {
        carSpeed = Math.max(0, carSpeed - acceleration * 1.5)
   } else if (keydown === false && carSpeed < 0) {
       carSpeed = Math.min(0, carSpeed + acceleration * 1.5)
     }
 }

    scene.actionManager = new ActionManager(scene);

    scene.actionManager.registerAction(new ExecuteCodeAction(ActionManager.OnKeyDownTrigger, (evt: any) => {
      inputMap[evt.sourceEvent.key.toLowerCase()] = evt.sourceEvent.type == "keydown";
    }));

    scene.actionManager.registerAction(new ExecuteCodeAction(ActionManager.OnKeyUpTrigger, function (evt: any) {
      inputMap[evt.sourceEvent.key.toLowerCase()] = evt.sourceEvent.type == "keydown";
    }));

braker 这个函数是比较关键的,当我们车加速到一定的速度,然后放开键盘,或者是键盘只按下了A或者D也就是方向,此时车子需要在负的加速度下慢慢减速,直到车子速度为0.

这里没有给车子别的加速度,比如不同的挡(手动挡),加速度应该是不一样的,你们也可以加上其他的按键加上不同的加速度,实现换挡的效果

2.在每一帧里调用,在三维场景模型的位置改变其实就是坐标的改变

补充:当车子移动的时候,顺便把第一人称的相机位置也更新一下,下车的时候,第一人称相机也就是停车后的位置了

   scene.onBeforeRenderObservable.add(() => {
      var keydown = false;
      // 前进,给车动力
      if (inputMap["s"]) {
        carSpeed = Math.min(maxSpeed, carSpeed + acceleration * 2)
        keydown = true;
      }
      // 反向给力
      if (inputMap["w"]) {
        carSpeed = Math.max(-maxSpeed, carSpeed - acceleration)
        keydown = true;
      }
      // 向左拐
      if (inputMap["a"]) {
        this.car.rotate(Vector3.Up(), carRotationSpeed * carSpeed * 2);
        if (!inputMap["w"] && !inputMap["s"]) {
          braker(false)
        }
        keydown = true;
      }
      // 向右拐
      if (inputMap["d"]) {
        this.car.rotate(Vector3.Up(), -carRotationSpeed * carSpeed * 2);
        if (!inputMap["w"] && !inputMap["s"]) {
          braker(false)
        }
        keydown = true;
      }

      // 阻力作用下停车
      braker(keydown)
      // 速度改变影响车子的位移,car.forward是模型的朝向,carSpeed具有大小,这样就 
      //得到一个具有大小和方向的速度
      this.car.moveWithCollisions(this.car.forward.scale(carSpeed));

      // 在车子开动的时候,顺便把第一人称的相机位置也更新一下
      if (scene.activeCamera instanceof ArcRotateCamera) {
        const carPosition = this.car.position.clone()
        carPosition.y += 2
        fcamera.position = carPosition
      }
      // 车轮转起来,就是让车轮绕着其本地坐标的X轴旋转,根据速度改变speedRatio 
      this.tireAnimationGroup.play(true)
      this.tireAnimationGroup.speedRatio = -carSpeed * 14

    });

总结:在文中只是用到一个核心变量carSpeed ,因为车子的运动,正负决定前进和后退,再结合car.forward也就是模型的方向就可以得到一个具有大小和方向的速度,代码的作用在注释都写的比较明白了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Babylon.js,你需要使用WebGL来渲染3D场景,而访问安卓相册的路径需要使用JavaScript来实现,因此你需要将两者结合起来。 以下是一个基本的实现步骤: 1. 创建一个input元素,类型为file,用于选择本地文件(图片)。 ```javascript <input type="file" id="fileInput" accept="image/*"> ``` 2. 监听input元素的change事件,获取选择的文件路径。 ```javascript const fileInput = document.getElementById("fileInput"); fileInput.addEventListener("change", handleFileSelect, false); function handleFileSelect(event) { const selectedFile = event.target.files[0]; const url = URL.createObjectURL(selectedFile); // do something with the url, such as load it into a texture } ``` 3. 将获取到的文件路径加载到Babylon.js的纹理。 ```javascript const texture = new BABYLON.Texture(url, scene); ``` 4. 在安卓,你需要使用Cordova插件来访问相册路径。首先,安装Cordova插件: ```bash cordova plugin add cordova-plugin-file ``` 5. 然后,使用以下代码来获取相册路径: ```javascript window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, function(dirEntry) { dirEntry.getDirectory("DCIM/Camera", { create: false }, function(subDirEntry) { subDirEntry.getFile(fileName, {}, function(fileEntry) { fileEntry.file(function(file) { const reader = new FileReader(); reader.onloadend = function() { const url = this.result; // do something with the url, such as load it into a texture }; reader.readAsDataURL(file); }, errorHandler); }, errorHandler); }, errorHandler); }, errorHandler); ``` 注意,上述代码的fileName应该是你想要访问的图片的文件名,errorHandler是用来处理错误的函数。 综上所述,你需要将以上代码整合到一起,才能在Babylon.js访问安卓相册路径并获取相册的图片。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值