PS: 学习视频: https://www.bilibili.com/video/BV1JE411D7C5?p=1&spm_id_from=pageDriver
流程
一、创建一个标准的项目
1. 项目路径不要使用中文和空格
2. Canvas: Node + cc.Canvas 组件(设计分辨率 + 适配策略)
Main Camera: Node + cc.Camera
3. 做一个规范的项目目录结构
4. 导入资源
二、创建游戏场景
1. 创建一个 background 节点,在该节点下创建一个 view 节点,内置背景图片节点。 节点可以使用`Sprite tiled`进行平铺,这样图片会变成小砖块来填充节点。
2. 注意节点的层次关系
3. 将摇杆和坦克对象都放到界面上,摇杆有两个子节点,一个是背景,一个是摇杆的中心点。可以使用 widget 来设置摇杆一直在页面左下角
三、制作游戏摇杆
1. 在对应的脚本文件夹下创建摇杆的 ts 文件, 需要一个摇杆中心 stick 和最大半径(摇杆中心不能超出这个最大半径)
2. stick 节点来监听触摸,触摸移动到哪里,stick 节点就跟踪到哪里。
// 监听触摸消息
controlDown() {
// TOUCH_START:当手指触摸到屏幕时
// TOUCH_MOVE: 当手指在屏幕上移动时
// TOUCH_END: 当手指在目标节点区域内离开屏幕时
// TOUCH_CANCEL: 当手指在目标节点区域外离开屏幕时
this.stick.on(cc.Node.EventType.TOUCH_MOVE, this.stickMove, this);
this.stick.on(cc.Node.EventType.TOUCH_END, this.stickEnd, this);
this.stick.on(cc.Node.EventType.TOUCH_CANCEL, this.stickEnd, this);
}
// 摇杆中心触摸移动
stickMove(e: cc.Touch) {
// getLocation: 获取当前触点位置
// convertToNodeSpaceAR: 将一个点转换到节点 (局部) 空间坐标系
// console.log(e.getLocation());
let location = e.getLocation();
let pos = this.node.convertToNodeSpaceAR(location);
this.stick.setPosition(pos);
}
// 触摸结束
stickEnd() {
this.stick.setPosition(0, 2);
}
复制代码
3. 对摇杆中心最大移动范围进行限定, 当摇杆中心位置长度超过限定的最大范围,通过`比例`来限定在范围的边缘位置
4. 摇杆传递方向给用户使用
两种方式: 使用第二种方式
* 角度
* 向量 --> (x, y) --> 向量单位化(向量到原点长度为 1) --> 求得向量长度 len, (pos.x / len, pos.y / len)
四、搭建物理地图,开启物理引擎
1. 给物体添加刚体 cc.RigidBody (刚体:物理计算,形状不会发生变化)
2. 给物体添加一个形状
3. 添加一个边界范围, 在 background 下面创建一个 rangeWall 节点,添加刚体,并创建四个边界。
4. 编写脚本开启物理引擎
* 打开物理引擎
* 配置物理引擎中重力大小
* 配置我们物理引擎的调试区域
创建一个 physics.ts 脚本,在里面配置重力和是否调试两项属性,并且在 onLoad 中开启物理引擎。
@property
isDebug: boolean = false; // 是否打开调试区域
// 默认的重力加速度是 (0, -320) 世界单位/秒^2,按照上面描述的转换规则,即 (0, -10) 米/秒^2
@property(cc.Vec2)
gravity: cc.Vec2 = cc.v2(0, -320);
onLoad () {
// getPhysicsManager物理管理器
let gp:cc.PhysicsManager = cc.director.getPhysicsManager();
gp.enabled = true; // 开启物理引擎
gp.gravity = this.gravity;
// 绘制调试区域
gp.debugDrawFlags = this.isDebug? 1: 0; // debugDrawFlags设置调试绘制标志
}
复制代码
然后将 ts 脚本挂载到 canvas 上面,并开启调试
最后的效果:
五、摇杆控制坦克移动
1. 编写坦克控制脚本
2. 定义一些属性:坦克的速度 speed, 摇杆对象
@property
maxSpeed: number = 100;
// 摇杆对象
@property(remoteSensingHandle)
remoteSensingHandle: remoteSensingHandle;
// 当前坦克方向
tankDirect: cc.Vec2 = cc.v2(0, 0);
复制代码
坦克移动
3. 获取摇杆的方向,根据摇杆操作坦克的物理刚体,给坦克的物理刚体一个摇杆方向的线性速度
4. 已知向量(x, y) --> 角度 --> Math.atan2(y, x);
update (dt) {
// 添加物理碰撞引擎后,不能通过改变坐标来使人物移动,需要通过改变线性速度
let dir = this.remoteSensingHandle.direct;
// 不移动
if (dir.x === 0 && dir.y == 0) {
this.body.linearVelocity = cc.v2(0, 0);
this.node.angle = 90;
return ;
} else {
this.tankDirect.y = this.maxSpeed * dir.y;
this.tankDirect.x = this.maxSpeed * dir.x;
// console.log(dir);
this.body.linearVelocity = this.tankDirect;
let r:number = Math.atan2(dir.y, dir.x);
let degree:number = r * 180 / Math.PI;
// console.log(this.node.rotation);
this.node.angle = degree;
}
}
复制代码
实现效果:
六、游戏地图滚动
摄像机移动
坦克移动,带着摄像机移动,摄像机变化了,拍摄画面自然也跟着变了
以摄像机为节点,以屏幕大小为范围来拍摄画面
让摄像机跟着玩家走,玩家走到哪里,摄像机就跟到哪里
游戏的 UI,要和地图独立开来,地图的滚动不会影响 UI (这里摄像机移动后,摇杆超出摄像机范围了)单独创建一个 UI 摄像机 --> 专门负责绘制 UI,游戏摄像机专门负责绘制游戏地图相关
在分组中添加一个 UI 分组,让 Main Camera 主摄像机不绘制 UI,将摇杆分组改成 UI
评论