一、创建标准项目、导入资源、编辑游戏场景

1. 创建标准项目、导入资源

(1)项目路径不要使用中文和空格;
(2) Canvas: Node + cc.Canvas组件(设计分辨率+适配策略)
Main Camera : Node + cc.Camera
(3)做一个规范的项目要醒目的目录结构;
(4)导入资源

2. 编辑游戏场景(可视化编辑)

(1) Sprite设置Tiled模式,能够使用小的”砖块”来平铺游戏地图;
(2) 注意节点的层次关系,节点的命名一定要规范;

二、组件化开发:TS制作游戏摇杆

(1)摇杆的属性:控制杆运动→stick节点,杆只能在套内运动→套的半径max_R;
(2) stick节点来监听触摸消息,触摸到哪里,我们的黄色的stick就跟到哪里。弹起恢复到中心位置(0, 0)。stick监听触摸消息:touch_move, touch_end、touch_cancel。
const {ccclass, property} = cc._decorator;

@ccclass
export default class joystick extends cc.Component {
// 摇杆手柄,加@property装饰器能被编辑器访问到
@property(cc.Node)
stick: cc.Node = null;
// 摇杆偏离中心点的最大距离
@property
max_R: number = 118;

  1. // 摇杆最终要传递给外部的一个向量,用于控制物体运动<br /> public dir : cc.Vec2 = cc.v2(0, 0);
  2. onLoad () {<br /> this.stick.on(cc.Node.EventType.TOUCH_MOVE, this.on_stick_move, this);<br /> this.stick.on(cc.Node.EventType.TOUCH_END, function() {<br /> this.on_stick_end();<br /> }, this);<br /> this.stick.on(cc.Node.EventType.TOUCH_CANCEL, function() {<br /> this.on_stick_end();<br /> }, this);<br /> }
  3. // 触摸事件对象, e里面保存了触摸信息<br /> on_stick_move(_e _: cc.Touch) : void{<br /> // 获取触摸坐标(屏幕坐标)<br /> var screen_pos : cc.Vec2 = _e_.getLocation();<br /> // 将屏幕坐标转换为相对于摇杆容器节点**joystick**的坐标<br /> var pos : cc.Vec2 = this.**node**.convertToNodeSpaceAR(screen_pos);
  4. // 求出向量dir,修正摇杆手柄的位置(不能脱肛)<br /> var len : number = pos.mag();<br /> // 修正摇杆手柄的位置,不能脱肛<br /> if(len > this.max_R){<br /> pos.x = pos.x * this.max_R / len;<br /> pos.y = pos.y * this.max_R / len;<br /> }<br /> this.stick.setPosition(pos);<br /> this.dir = pos;<br /> }
  5. on_stick_end() : void {<br /> this.dir = cc.v2(0, 0);<br /> this.stick.setPosition(cc.v2(0, 0));<br /> }
  6. start () {}<br /> // update (dt) {}<br />}<br />![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711682121-fac8d40c-11c0-4baf-ab88-d00ccfef05e3.png#crop=0&crop=0&crop=1&crop=1&height=121&id=aeK0U&originHeight=211&originWidth=305&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=175) ![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711682377-d93204d7-6200-4b39-bd85-4ed3beac8245.png#crop=0&crop=0&crop=1&crop=1&height=119&id=FXGIy&originHeight=316&originWidth=289&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=109)另外摇杆适配右下角。<br />![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711682618-76d450da-f0ef-4fb2-891a-7b6533675baa.png#crop=0&crop=0&crop=1&crop=1&height=154&id=hL37C&originHeight=250&originWidth=672&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=415)

三、基于物理引擎搭建逻辑地图

【1】给物体加一个刚体cc.RigidBody;刚体:物理计算—》形状不会发生变化;【动态、静态】
【2】给物体加一个形状;坦克刚体Dynamic,Circle,地图Map四边static。
【3】编写脚本来开启物理引擎。
a:打开物理引擎;
b:配置物理引擎的中重力大小;
c:配置我们物理引擎的调试区域。

const {ccclass, property} = cc._decorator;

@ccclass
export default class joystick extends cc.Component {
  // 摇杆手柄,加@property 装饰器能被编辑器访问到
  @property(cc.Node)
  stick: cc.Node = null;
  // 摇杆偏离中心点的最大距离
  @property
  max_R: number = 118;
  // 摇杆最终要传递给外部的一个向量,用于控制物体运动
  public dir : cc.Vec2 = cc.v2(0, 0);

  onLoad () {
    this.stick.on(cc.Node.EventType.TOUCH_MOVE, this.on_stick_move, this);
    this.stick.on(cc.Node.EventType.TOUCH_END, function() {
      this.on_stick_end();
    }, this);
    this.stick.on(cc.Node.EventType.TOUCH_CANCEL, function() {
      this.on_stick_end();
    }, this);
  }

    // 触摸事件对象, e 里面保存了触摸信息
  on_stick_move(e : cc.Touch) : void{
    // 获取触摸坐标(屏幕坐标)
    var screen_pos : cc.Vec2 = e.getLocation();
    // 将屏幕坐标转换为相对于摇杆容器节点 joystick 的坐标
    var pos : cc.Vec2 = this.node.convertToNodeSpaceAR(screen_pos);
    // 求出向量 dir,修正摇杆手柄的位置(不能脱肛)
    var len : number = pos.mag();
    // 修正摇杆手柄的位置,不能脱肛
    if(len > this.max_R){
      pos.x = pos.x * this.max_R / len;
      pos.y = pos.y * this.max_R / len;
    }
    this.stick.setPosition(pos);
    this.dir = pos;
   }

  on_stick_end() : void {
    this.dir = cc.v2(0, 0);
    this.stick.setPosition(cc.v2(0, 0));
  }

  start () {}
    // update (dt) {}
}

}
可以到官方API网站去搜索getphysicsmanager参考,查看PhysicsManager 最后三属性。
在Canvas节点上添加此用户自定义脚本组件,编译,运行,发现,坦克会往下掉。说明物理引擎开启成功,因为游戏中坦克是在水平面运动,不需要向下的重力加速度,故将向下的重力加速度分量改为0。

四、摇杆控制坦克移动

(1)编写坦克控制的脚本;
(2)定义一些属性:坦克的速度speed、 joystick摇杆对象
(3)获取摇杆的方向,根据摇杆方向来操作坦克的物理刚体,给坦克的物理刚体一个摇杆方向的线性速度。新建tank_ctrl.js,给tank节点添加此用户脚本组件。
import joystick from “./joystick”

const {ccclass, property} = cc._decorator;

@ccclass
export default class tank_ctrl extends cc.Component {
// 控制坦克运动的摇杆
@property(joystick)
stick: joystick = null;
// 坦克的最大速度或速度(若使用单位向量就是速度)
@property
speed: number = 2;
// 注意:一定要控制刚体运动,直接修正坦克节点坐标会穿透
private body: cc.RigidBody = null;

onLoad () {<br />        this.body = this.getComponent(cc.RigidBody);<br />    }

start () {    }

update (_dt_) {<br />        if(this.stick.dir.x === 0 && this.stick.dir.y ===0){<br />            this.body.linearVelocity = cc.v2(0,0);<br />            return;<br />        }<br />        // 将摇杆中包含的运动速度和方向信息传递给坦克刚体<br />        var vx : number = this.speed * this.stick.dir.x;<br />        var vy : number = this.speed * this.stick.dir.y;<br />        this.body.linearVelocity = cc.v2(vx, vy);<br />        // 设置坦克炮口朝向<br />        var r : number = _Math_.atan2(this.stick.dir.y, this.stick.dir.x);<br />        var degree : number = 180 * r/_Math_.PI;<br />        //this.node.rotation = -degree+90;<br />        this.node.angle = degree - 90;<br />    }<br />}<br />![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711683018-1219026b-b801-4cbd-abdc-e3da1e496fd2.png#crop=0&crop=0&crop=1&crop=1&height=116&id=VajLs&originHeight=205&originWidth=319&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=180)<br />编译运行,坦克会跑出视野范围。男人一定要会开车,但是一旦开出你老婆的视线范围,那你一定想好回去家里是否还有榴莲可用。所以我们要控制坦克在视野范围内运动,怎么办,自己主动在车顶装一个遥控无人机,紧跟着你拍摄。让你老婆能够实时观察到你在干嘛。<br />五、       TS实现地图滚动与漫游<br />1.      地图滚动:摄像机跟随坦克运动<br />设置摄像机的位置跟坦克节点的位置一致即可。<br />【1】在tank_ctrl.ts中添加属性camera,并通过编辑器实例化:<br />@property(cc.Node)<br />camera : cc.Node = null;<br />![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711683266-b91b811c-86ac-4301-8b6a-09eddb24461f.png#crop=0&crop=0&crop=1&crop=1&height=136&id=tngRf&originHeight=210&originWidth=339&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=219)<br />【2】update(dt)方法中设置camera的位置跟坦克节点tank的的位置一致<br />if(this.camera !== null){<br />    this.camera.setPosition(this.node.getPosition());<br />}<br />编译运行,发现坦克会在屏幕中央,地图会滚动,但是,摇杆消失了。有些事我们可以凭感觉进行,而有些事不能。尤其是你的把柄不在你老婆手里的时候,你老婆要想再控制你就难了。所以,你还得设法让你的把柄始终暴露在你媳妇的视野内。怎么办?你媳妇除了在你的车顶上装一个摄像机外,她是不是还可以在你的车内装一个摄像机,专门盯着你的档位。<br />2.      双摄像机解决摇杆消失问题<br />为了到时候,将UI_root制成一个预制体(浮动在屏幕上的摇杆组件),到任何游戏中都可以应用。故我们在UI_root新建一个空节点UI_Camera,给此空节点添加其他组件Camera。<br />然后,添加分组UI,设置UI_root分组为UI,~~UI_Camera分组为default~~,将tank_ctrl用户自定义组件中的属性Camera依然设置为Main Camera。Main Camera拍摄UI以外的所有组,UI_Camera只拍摄UI组。如下图所示:<br />![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711683653-c25bfea2-e9f2-4817-9b2d-2d65d4f470e6.png#crop=0&crop=0&crop=1&crop=1&height=316&id=tycpj&originHeight=335&originWidth=774&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=729)<br />解决摇杆位于屏幕中央的问题:将最开始UI_Camera的位置设置为跟坦克位置一致!这样确保拍摄的摇杆不会位于屏幕中央!如下图操作:<br />![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711684159-5f0177d2-7020-4a53-bef3-5cc327d12275.png#crop=0&crop=0&crop=1&crop=1&height=232&id=p4GCA&originHeight=252&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=588)<br />或者保持最开始的UI_root的position为(0,0)也就是和tank重合,然后UI_root内的UI_Camera的初始位置也会是(0,0),位于屏幕最中心,将摇杆节点joystick拖动到屏幕右下角,设置布局为右下角即可。(此种操作更合符规范!如下图所示)<br />![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711684735-7185e3f1-1827-429f-9347-607a90a7dcb4.png#crop=0&crop=0&crop=1&crop=1&height=168&id=Oeoyi&originHeight=309&originWidth=575&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=313)<br />3.      坦克摩擦转动问题<br />勾选坦克节点tank上的刚体组件RigidBody的Fixed Rotation固定旋转即可。因为刚体碰撞的时候会有摩擦力,故会旋转。<br />![](https://cdn.nlark.com/yuque/0/2022/png/12595208/1650711685178-fdfde5a2-4189-40e3-891b-771e2eab929f.png#crop=0&crop=0&crop=1&crop=1&height=27&id=gkHsv&originHeight=62&originWidth=254&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=112)<br />六、       打包发布微信小游戏<br />