前面有两篇文章关于控制小车来实现漫游的 Cesium开发实践(一) ,但是我觉得还是没那味,想研究一下能不能实现类似FPS游戏那样的感觉。
这就是实现后的效果,代码没有太多改动,主要是关于GLFT格式的模型引入问题。目前我仅用过GLTF格式和GLB格式,两种格式都可以实现动画,只是这两个格式的文件不好找。我给大家推荐两个。
GLTF:https://sketchfab.com/feed
GLB:https://www.kenney.nl/
思路
刚开始是使用了两个模型,一个动态一个静态,然后监听键盘按下和抬起,在按下的移除静态模型,然后添加动态模型;在键盘抬起且是最后一个抬起的按键就移除动态模型,然后添加静态模型。但是这样有点消耗性能,而且代码冗余也不健壮。于是查看API文档发现了这个属性:runAnimations。跟之前那两篇文章写得一样,用回调函数来修改就可以实现动静切换了。
代码改动部分
添加模型
// 添加模型
let woman = viewer.entities.add({
id:'woman',
position: new Cesium.CallbackProperty(getPositin, false),
// 根据所提供的速度计算点
orientation: new Cesium.CallbackProperty(getOrientation, false),
model: {
uri: '/static/model/walking/scene.gltf',
runAnimations:new Cesium.CallbackProperty(getRun, false),
scale:0.012,
// 贴地
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
},
});
监听事件
// 状态,停下时false,开始运动后都是true。
var run = false;
document.addEventListener('keydown',(e)=>{
setFlagStatus(e, true);
if(e.which===40||e.which===39||e.which===38||e.which===37){
if(!run){
run = true
}
}
});
document.addEventListener('keyup',(e)=>{
setFlagStatus(e, false);
if(e.which===40||e.which===39||e.which===38||e.which===37){
if(flag.moveUp|flag.moveDown|flag.moveLeft|flag.moveRight){
return
}else{
run = false
}
}
});
增加一个函数,返回状态值就好了
function getRun(){
return run
}
By the way
在引入模型的时候还是遇到了一些问题,比如模型的方向不太对,用方向键控制会倒着走或者斜着走,所以在这顺带提一下这个问题。
这个hproll在第一次时也会被设置为姿态,所以初始位置的方向可以通过这个调整,我这里加了一个顺时针旋转90度。
let hpRoll = new Cesium.HeadingPitchRoll();
hpRoll.heading = Cesium.Math.toRadians(90.0);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position,hpRoll)
//north south east west up down
let fixedFrameTransforms = Cesium.Transforms.localFrameToFixedFrameGenerator('east', 'north');
这里的heading是镜头的方向角,综上就是这三个地方控制着方向。
viewer.camera.setView({
destination:Cesium.Cartesian3.fromDegrees(lng,lat,alt),
orientation:{
heading:hpRoll.heading +Cesium.Math.toRadians(90.0),
pitch:Cesium.Math.toRadians(-15.0),
roll:0.0
}
});