因为兴趣接触到了JMonkey,后来又由于项目需求去学了下cocos。
这里先放上一个之前挺火的一个游戏的改版 合成武汉理工{:target="_blank"},用cocos creator开发,很久之前入门前端时,还纯Web原生写过一个 2048小游戏{:target="_blank"},这个2048也是典型的MVC模型开发。
MVC即Model、View、Controller即模型、视图、控制器,视图根据模型现实,控制器修改模型。
View <=> Model <=> Controller
游戏开发感觉合传统的应用开发挺不一样的,用不同的一套思路去开发。
简单来说来说可以分成2D游戏和3D游戏,二者主要在视图和物理逻辑层面不太一样,后者需要考虑立体空间坐标系。
本文主要说的是基于cocos的游戏开发笔记,据说cocos和unity很像。最新的cocos creator 3已经全面使用typescript
来进行脚本的编写。
开发流程 #
创建场景-节点-物体 > 创建脚本 > 将脚本绑定到节点 > 编写逻辑 > 调试等
架构 #
这里指的是开发中的设计。
一般是一个gameManager
类或者脚本来控制游戏的主核心逻辑,然后对于角色,再分配playerControl
类来控制角色的行为。对于一般的游戏引擎,绑定在物体上的脚本都会有个类似update
的函数,会随着游戏进行周期性的运行,并且间隔非常短,通过update
函数,我们就可以实现角色状态的实时更新。
对于可能会有事件或者自定义行为的物理,往往是绑定上一个脚本来进行定制。
物理 #
除了瞬移或者直接添加速度的方式,游戏如果启用了物理引擎,那么一般使用两种方式来运动,一个是力,一个是冲量。
如果要给物体启用物理属性,就需要给物体添加上刚体组件(RigidBody)和碰撞器组件(Collider)。这里又分为2d组件和3d组件。这两个不同的组件会有不同的行为。
实现物体的移动的话,可以参考cocos的 文档,通过改变刚体的受力或者冲量,亦或者直接设置一个速度来实现。
2D平面游戏控制 #
就在这里放一下我实现的2d有重力情况下,玩家控制角色移动的方法把。
总结一些大概的流程:
- 玩家按下键盘,触发
SystemEvent.EventType.KEY_DOWN
- 系统事件处理机制执行对应的处理函数
onKeyDown
onKeyDown
中为角色对象更新受力的值,如_xforce=10
update
周期性函数执行时,根据受力值,如_xforce
,对物体的刚体组件施加对应的冲量/力
首先将事件处理函数绑定到绑定键盘输入事件。
setInputActive(active: boolean) {
if (active) {
systemEvent.on(SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
systemEvent.on(SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
} else {
systemEvent.off(SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
systemEvent.off(SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
}
}
键盘输入的处理函数,可以看到,这里我是给角色节点施加了一个力来实现状态的改变。键盘按下时添加对应方向的力,松开时解除力。
onKeyDown(event: EventKeyboard) {
this._isMoving = true;
switch (event.keyCode) {
case macro.KEY.a:
case macro.KEY.left:
this._xForce = -this._force / 2;
this._yForce = 0;
break;
case macro.KEY.d:
case macro.KEY.right:
this._xForce = this._force / 2;
this._yForce = 0;
break;
case macro.KEY.w:
case macro.KEY.up:
if (!this.isUping) {
this.isUping = true;
this._yForce = this._force;
let that = this;
setTimeout(() => {
that._yForce = 0;
}, 200)
}
break;
case macro.KEY.s:
case macro.KEY.down:
this._yForce = 0;
break;
}
}
onKeyUp(event: EventKeyboard) {
this._isMoving = false;
this._keydown = String(event.keyCode);
switch (event.keyCode) {
case macro.KEY.a:
case macro.KEY.left:
case macro.KEY.d:
case macro.KEY.right:
this._xForce = 0;
break;
case macro.KEY.w:
case macro.KEY.s:
// this._yForce = 0;
break;
}
}
实时更新函数,update函数会在游戏运行时,被游戏主线程周期性的调用。通过update
函数,就可以实现将角色受到的力转换成具体的行为。
update(deltaTime: number) {
if (this.player) {
const player = this.player;
const rigidbody2d: RigidBody2D | null = player.getComponent(RigidBody2D);
if (rigidbody2d) {
// 使用刚体运动
// https://docs.cocos.com/creator/3.0/manual/zh/physics/physics-collider.html
rigidbody2d?.applyForceToCenter(new Vec2(this._xForce, this._yForce), true);
const velocity: Vec2 = rigidbody2d?.linearVelocity;
if (velocity) {
// 限制刚体速度
if (Math.abs(velocity.x) > this.maxspeed) {
velocity.x = velocity.x > 0 ? this.maxspeed : -this.maxspeed;
}
if (this._xForce == 0) {
velocity.x /= 1.1;
}
rigidbody2d.linearVelocity = velocity;
}
}
}
}
最后编辑于:2021-03-07