游戏开发入门

上了自己的新博客后的第一篇博客

因为兴趣接触到了JMonkey,后来又由于项目需求去学了下cocos。

这里先放上一个之前挺火的一个游戏的改版合成武汉理工,用cocos creator开发,很久之前入门前端时,还纯Web原生写过一个2048小游戏,这个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有重力情况下,玩家控制角色移动的方法把。

总结一些大概的流程:

  1. 玩家按下键盘,触发SystemEvent.EventType.KEY_DOWN
  2. 系统事件处理机制执行对应的处理函数onKeyDown
  3. onKeyDown中为角色对象更新受力的值,如_xforce=10
  4. 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

REF

Star 0
Prev: 前端笔记 - JS函数参数,类比Python