Cocos Creator | 主角光环之摄像机跟随
The following article is from CocosCreator笔记 Author 请容我安眠
one 1
演示
瓦片地图
碰撞分组
摄像机
更新摄像机位置
限制摄像机边界
two 2
实现
1瓦片地图
大地图使用的是 TileMap :
TileMap 是由一个个格子拼凑而成:
导入图块后,就可以对每个格子进行贴图,还可以摆放各种障碍物和陷阱:
关于 TileMap 的制作方法这里就不多做介绍了
TileMap 的格子本身就是一个二维数组,所以用它来做 A* 寻路的地图也是超级方便
关于 TileMap和A* 寻路的详细介绍:
Creator | TileMap坐标转换
Creator | A*(A-Star)寻路实现及优化浅析
由于个人审美有限,所以简单的拼了个 Creator
将拼好的地图及图块元素拖入到资源管理器:
从编辑器的控件库中拖拽 TileMap 到场景中:
拖拽地图资源到组件中:
大地图的尺寸为 3072*1728 ,远远超过我们游戏的设计分辨率
图之大,一个屏幕装不下:
为了保证主角光环效果,即玩家的视角一直保持在屏幕中心,所以需要添加额外的摄像机
2
分组管理
在添加摄像机之前,需要先添加分组
因为摄像机的 cullingMask 属性决定了它渲染场景的哪些部分
分组管理:
https://docs.cocos.com/creator/manual/zh/physics/collision/collision-group.html
一般的游戏都会有 UI 层,比如我们这里的控制玩家移动的按钮:
所以这里设计为:
UI 层的元素放到 ui 分组( UI 摄像机渲染)
地图,玩家等元素放到 default 分组(主摄像机渲染)
在编辑器中添加分组:
项目->项目设置->分组管理->添加分组
设置新添加分组的名字为:ui
3Camera
摄像机:
https://docs.cocos.com/creator/manual/zh/render/camera.html
几个关键属性:
① depth 摄像机深度,用于决定摄像机的渲染顺序。值越大,则摄像机越晚被渲染
② cullingMask 将决定这个摄像机用来渲染场景的哪些部分
③ clearFlags 指定渲染摄像机时需要做的清除操作
新建摄像机节点:
或者直接复制 Main Camera 节点
名字改为 UI Camera
设置 UI Camera 属性:
① ui 一般在游戏中处于最上层,所以将 depth 设置为一个较大的数字:100
② cullingMask 只勾选 ui 分组
③clearFlags 取消勾选 color(清除背景颜色),否则看不到 Main Camera 中物体,只能看到黑色(即 UI Camera 的 backgroundColor)
设置 Main Camera 属性:
4脚本控制
在编辑器中拖拽对应的节点到脚本中
这里需要的是节点是 Main Camera(摄像机)、tiledmap(地图)、player(玩家)
首先计算摄像机的位置边界:
//摄像机边界
this._cameraMaxX = this.tileMap.node.width/2 - cc.winSize.width/2;
this._cameraMaxY = this.tileMap.node.height/2 - cc.winSize.height/2;
然后在玩家移动的过程中调用 updateCameraPosition 函数
updateCameraPosition() {
let target = this.nodePlayer.position;
if (target.x > this._cameraMaxX) {
target.x = this._cameraMaxX;
}
if (target.x < -this._cameraMaxX) {
target.x = -this._cameraMaxX;
}
if (target.y > this._cameraMaxY) {
target.y = this._cameraMaxY;
}
if (target.y < -this._cameraMaxY) {
target.y = -this._cameraMaxY;
}
this.mainCamera.node.position = target;
}
因为这里玩家移动用的 action,所以就直接在 update 中更新摄像机位置了
实际开发中可以根据需要,自己选择合理的时机
当玩家移动的时候,需要控制玩家的朝向为目标方向,Creator 为我们封装了 API ,使用起来很方便:
sub:向量减法,并返回新结果
signAngle:带方向的夹角的弧度
radiansToDegrees:弧度转为角度
this.nodePlayer.angle = 90 - cc.misc.radiansToDegrees(target.sub(this.nodePlayer.position).signAngle(cc.v2(1,0)));
当摄像机到达边界后,摄像机不会再移动,只有玩家移动,这样可以防止屏幕内出现黑边:
需要注意的是
当摄像机被移动、旋转或者缩放后,点击事件获取到的坐标是屏幕坐标系下的坐标,需要将该坐标转换到世界坐标系下,才能继续与节点的世界坐标进行运算:
// 将一个屏幕坐标系下的点转换到世界坐标系下
camera.getScreenToWorldPoint(point, out);
// 将一个世界坐标系下的点转换到屏幕坐标系下
camera.getWorldToScreenPoint(point, out);
ps:工程源码地址:https://git.dev.tencent.com/Valiancer/CameraFollowing.git
更多精彩
- end -