KUOKUO的物理小游戏(三)
摘要
时间过的真快,阔阔工作之余录制的物理小游戏视频教程也已经更新到了14集!可能这就是对技术的热爱吧!本文就对教程做下阶段性的总结!
正文
使用版本
CocosCreator 版本 2.3.4
按钮动作&工具类Util(第5集)
按钮的动作我没有使用按钮组件,而是使用了节点事件监听;使用解构简化事件类型的书写:
const { TOUCH_START, TOUCH_END, TOUCH_CANCEL } = cc.Node.EventType
this.startButton.on(TOUCH_START, () => {
// 改变按钮节点的 scale
}, this)
改变节点的动作可以封装到一个工具类里:
export class Util {
static clickDownTween(node: cc.Node | undefined) {
if (!node) { return }
cc.tween(node).to(0.1, { scale: 0.9 }).start()
}
static clickUpTween(node: cc.Node | undefined) {
if (!node) { return }
cc.tween(node).to(0.1, { scale: 1 }).start()
}
}
优化后的代码:
this.startButton.on(TOUCH_START, () => {
Util.clickDownTween(this.startButton)
}, this)
动作后回调(第6集)
触摸开始是让节点缩放,松手是放大回正常尺寸,但是如果不等动作完成后触发事件,会出现事件触发时,按钮还在进行放大的现象。理应在动作结束后进行事件的触发,对 Util.clickUpTween()
进行改造:
static clickUpTween(node: cc.Node | undefined, callback?: () => void) {
if (!node) { return }
cc.tween(node).to(0.1, { scale: 1 }).call(() => {
callback && callback()
}).start()
}
使用:
this.startButton.on(TOUCH_END, () => {
Util.clickUpTween(this.startButton, () => {
uiManager.gameStart()
})
}, this)
uiMap与枚举(第7集)
我们有 6 个 UI 要进行管理,每个 UI 都应该有显示与隐藏的方法,故抽出其共有属性与方法,实现一个 UIBase,让 6 个 UI 脚本去继承 UIBase,然后要对于实例化后的进行管理,采用了一个 map
数据结构:
private uiMap = new Map()
UIType 是为了方便使用的枚举:
export enum UIType {
ControlPanel,
LevelInfo,
LevelSelect,
StartMenu,
WinPanel,
LossPanel
}
关卡选择界面与逻辑(第8-9集)
关卡选择界面主要涉及一个列表,我这里距离了六关,也可以多放些使用 Scrollview 做成滚动的。如何识别每个关卡按钮,可以使用下标的形式,在创建时就按照顺序,这样从上到下就是对于 node.children
这个数组的下标:
button.on(TOUCH_END, () => {
Util.clickUpTween(button, () => {
// 从 1 开始
const level = index + 1
// 传入参数
uiManager.gameStart(level)
})
}, this)
轮盘限位相似三角形原理(第10集)
轮盘这里注意两点,一个是触摸事件放在背景上,区域大点,方便定位;一个是限位处理,设置一个半径,如果手指触点到中心位置距离大于半径,根据相似原理乘以这个比例的倒数就会回到半径这个长度,然后把 x 和 y 乘以这个比率就是位置:
limitMidNodePos(pos: cc.Vec2): cc.Vec2 {
const R = 130
// 取当前位置长度,(x,y)=>len
const len = pos.mag()
// 计算 len 与 R 的关系,是内部还是外部,在外部,利用比例,限制回区域
const ratio = len > R ? R / len : 1
return cc.v2(pos.x * ratio, pos.y * ratio)
}
食物刚体旋转位移控制逻辑(第11-13集)
为了逻辑清晰,所有 UI 由 UIManager 管理,然后由其负责与 GameManager 通讯:
简单封装物理模块(第14集)
对于物理模块,封装这么五个方法:openPhysicsSystem()
closePhysicsSystem()
setRigidBodyStatic()
setRigidBodyDynamic()
setRigidBodyLinearVelocity()
顾名思义,分别是:开启物理系统、关闭物理系统、设置一个节点上的刚体类型为静态、设置一个节点上的刚体类型为动态、设置一个节点上的刚体线速度,以下为具体实现,都是比较简单的封装:
export class PhysicsManager {
static openPhysicsSystem() {
cc.director.getPhysicsManager().enabled = true
}
static closePhysicsSystem() {
cc.director.getPhysicsManager().enabled = false
}
static setRigidBodyStatic(node: cc.Node) {
const body = node.getComponent(cc.RigidBody)
body.type = cc.RigidBodyType.Static
}
static setRigidBodyDynamic(node: cc.Node) {
const body = node.getComponent(cc.RigidBody)
body.type = cc.RigidBodyType.Dynamic
}
static setRigidBodyLinearVelocity(node: cc.Node, v: cc.Vec2) {
const body = node.getComponent(cc.RigidBody)
body.linearVelocity = v
}
}
结语
KUOKUO 会坚持更新视频哦,哔哩哔哩求关注,视频链接为:
https://www.bilibili.com/video/BV1ck4y167mR
2020!我们一起进步!O(∩_∩)O~~