一、创建标准项目、导入资源、编辑游戏场景
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;
// 摇杆最终要传递给外部的一个向量,用于控制物体运动<br /> public dir : cc.Vec2 = cc.v2(0, 0);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 /> }// 触摸事件对象, 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);// 求出向量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 /> }on_stick_end() : void {<br /> this.dir = cc.v2(0, 0);<br /> this.stick.setPosition(cc.v2(0, 0));<br /> }start () {}<br /> // update (dt) {}<br />}<br /> 另外摇杆适配右下角。<br />
三、基于物理引擎搭建逻辑地图
【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 /><br />编译运行,坦克会跑出视野范围。男人一定要会开车,但是一旦开出你老婆的视线范围,那你一定想好回去家里是否还有榴莲可用。所以我们要控制坦克在视野范围内运动,怎么办,自己主动在车顶装一个遥控无人机,紧跟着你拍摄。让你老婆能够实时观察到你在干嘛。<br />五、 TS实现地图滚动与漫游<br />1. 地图滚动:摄像机跟随坦克运动<br />设置摄像机的位置跟坦克节点的位置一致即可。<br />【1】在tank_ctrl.ts中添加属性camera,并通过编辑器实例化:<br />@property(cc.Node)<br />camera : cc.Node = null;<br /><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 /><br />解决摇杆位于屏幕中央的问题:将最开始UI_Camera的位置设置为跟坦克位置一致!这样确保拍摄的摇杆不会位于屏幕中央!如下图操作:<br /><br />或者保持最开始的UI_root的position为(0,0)也就是和tank重合,然后UI_root内的UI_Camera的初始位置也会是(0,0),位于屏幕最中心,将摇杆节点joystick拖动到屏幕右下角,设置布局为右下角即可。(此种操作更合符规范!如下图所示)<br /><br />3. 坦克摩擦转动问题<br />勾选坦克节点tank上的刚体组件RigidBody的Fixed Rotation固定旋转即可。因为刚体碰撞的时候会有摩擦力,故会旋转。<br /><br />六、 打包发布微信小游戏<br />
