前言

麒麟子在开发中搞出来的框架,都是遵守“大道至简,实用至上”这两个基本原则。

接触一个引擎的第一件事,就是搞出一个实用的框架,方便在此基础上做开发。

由于目前的引擎已经是对象+组件模式,所以在场景对象管理上,不需要花太多功夫了。我们主要集中在界面管理这块。

1

常见的几种游戏类型

既然我们的框架想要满足日常开发,就不得不满足星辰大海般的需求。从客户端的角度,我们可以把游戏分为三类。

1.1、纯界面玩法

像一些SLG、卡牌、象棋等可以视作纯界面玩法。(也有某些大作要求3D表现效果的,我们不作讨论),比如下面的这类游戏。

动物餐厅

1.2、某些纯界面&战场场景

王者荣耀

1.3、从头到尾都是3D场景

魔兽世界

1.4、小结

仔细分析以后我们可以发现,假如我们的框架始终支持 2D/3D场景 + 界面 这样的能力。就可以了。

2

单场景 vs 多场景

单场景+Prefab 和 多场景从 Cocos 2d-x 提供了 replaceScene 函数开始,就一直有人在争论这个话题。只要引擎提供了“场景”这个定义的,都会遇上决策问题。

麒麟子看得很明白,所谓的引擎场景管理,就是给了你一次无脑销毁所有结点的机会。

如果你是在两个截然不同的逻辑之间切换,那其实是可以使用引擎的场景切换功能的。 如果逻辑相差不大,我建议依然采用单场景方式。

而麒麟子更推荐的是单场景+Prefab方式,这样会迫使你自己更注重场景节点和资源的管理。

3

框架内容

3.1、程序启动入口

程序启动入口包含两个部分。

3.1.1、最小场景

最小场景如果不出意外,我们只需要一个Canvas节点,一个MainCamera节点,一个MainLight节点就好了。

3.1.2、App.ts

麒麟子喜欢以 App.ts 作为程序入口,将这个App.ts挂在Canvas节点上即可。App.ts的内容并不多,如下所示

import { _decorator, Component, Node } from 'cc';
import { UIMgr, UILayer } from './UIMgr';
import { HUD } from './HUD';
const { ccclass, property } = _decorator;@ccclass('AppTs')
export class AppTs extends Component {
start () {UIMgr.inst.setup(UILayer.NUM);UIMgr.inst.showUI(HUD); }
}

我们可以清晰地看到,在这里,麒麟子只启动了 UIMgr,如果还有其他游戏管理器需要一开始就初始化,那么把它们放在这里就好了。

3.2、界面管理器

  • 界面管理器至少要包含几个功能

  • 动态加载和销毁界面

  • 界面层级管理

  • 界面事件自动管理机制

  • 界面与游戏业务逻辑通信机制

上面说的这些,框架里都自带了。

4

分辨率自适应

很多小伙伴一定还在纠结是用 fitWidth 还是 fitHeight 吧。

如果使用 fitWidth 遇上更细长的设备,界面上面部分可能被裁剪。

如果使用 fitHeight 遇上更短的设备,界面左右部分可能被裁剪。

其实我们想要的只有一句话:任何时候,都不要裁剪。

基于这个目标,我们制定出的策略就是。

  • 在比设计分辨率更细长的设备上,我们使用 fitHeight,这样一来,他长由他长,我们只需要保证背景左右能够填充就行。

    在比设计分辨率更短的设备上,我们使用 fitWidth这样一来,他高由他高,我们只需要保证背景上下能够填充就行。上面的适配机制,已经被麒麟子写成了一个函数。

    public resize() {//根据屏幕大小决定适配策略let dr = view.getDesignResolutionSize();var s = cc.view.getFrameSize();var rw = s.width;var rh = s.height;var finalW = rw;var finalH = rh;if ((rw / rh) > (dr.width / dr.height)) {//!#zh: 是否优先将设计分辨率高度撑满视图高度。//cvs.fitHeight = true;//如果更长,则用定高finalH = dr.height;finalW = finalH * rw / rh;}else {/*!#zh: 是否优先将设计分辨率宽度撑满视图宽度。*///cvs.fitWidth = true;//如果更短,则用定宽finalW = dr.width;finalH = rh / rw * finalW;}view.setDesignResolutionSize(finalW, finalH, ResolutionPolicy.UNKNOWN);let cvs = find('Canvas').getComponent(UITransformComponent);cvs.node.width = finalW;cvs.node.height = finalH;
    }
    

关于这个函数,有两个地方要注意:

  1. 在设置面板里面,fitWidth和fitHeight都得去掉,一个都不要勾,否则可能出现设置失效。

  2. 麒麟子在调用 view.setDesignResolutionSize 函数的时候,最后一个参数传的是ResolutionPolicy.UNKNOWN。

这样一来,这个函数是可以重复调用且生效的。当我们处于微信浏览器的时候,横竖屏旋转会导致宽高比不一致,这就需要再次调用这个函数来重新调整布局。

5

游戏逻辑与界面通信机制

麒麟子这里没有MVC,也没有MVVM,只有以下几个套路

  1. 数据、数据更新方法由逻辑管理器提供

  2. 数据变更,想让界面产生改变,则通过事件传递

  3. 界面可以直接调用逻辑管理器

  4. 两个界面之间,只能通过事件传递(需要两个界面联动的情况非常少,一般情况下界面之间的逻辑都是互不干扰的)

也就是说,逻辑管理器不知道界面的存在,但界面是知道逻辑管理器的存在的。

我举一个关于个人信息的例子。在这个例子中,我们会涉及到三个文件 MyInfoMgr.ts(用户信息逻辑管理器 M) 、UIMyInfoController.ts(用户信息界面控制器 C) 、MyInfo.prefab(用户信息界面布局 V)。

如果非要用MVC来对应的话,就按我后面标记的字母来对应吧。

当用户点击个人按钮时,UIMgr会实例化UIMyInfoController类,UIMyInfoController类会加载MyInfo.prefab。

当加载成功后,UIMyInfoController会有一个onCreated回调,我们可以在回调里初始化我们的显示信息。

UIMyInfoController需要监听用户信息改变相关的事件,当收到事件的时候,需要对应地做显示更新

MyInfoMgr持有用户数据并提供访问接口以及数据修改接口,当数据产生修改时,会抛出修改事件。它不关心这个事件是否有人要用。无脑抛出就行。


6

总结

与其说是框架,不如说是麒麟子的惯用套路。这个套路没有出色的地方,也不满足很多学术性的依赖解耦标准。但这个套路陪着我走过了大大小小很多项目。

如果要给它下一个定义的话,我觉得就是两个词:“简单、实用”。

哦对了,只能用Cocos Creator 3D 1.1.1打开。

源码地址:

https://gitee.com/qilinzi/creator3ddemos

点击阅读原文,可直接跳转到源码页面

麒麟子惯用框架分享(建议收藏)相关推荐

  1. Oracle 数据怎么实时同步到 MySQL | 亲测干货分享建议收藏

      摘要: 这段时间负责一个老项目开发的数据库管理工作,这个项目中开发库与测试数据库分离,其中有些系统表数据与基础资料数据经常需要进行同步,相信很多 DBA 同学经常会遇到要从一个数据库实时同步到另一 ...

  2. Oracle 数据怎么实时同步到 Kafka | 亲测干货分享建议收藏

     摘要: 很多 DBA 同学经常会遇到要从一个数据库实时同步到另一个数据库的问题,同构数据还相对容易,遇上异构数据.表多.数据量大等情况就难以同步.我自己亲测了一种方式,可以非常方便地完成 Oracl ...

  3. Oracle 数据怎么实时同步到 SQL Server | 亲测干货分享建议收藏

    摘要: 很多 DBA 同学经常会遇到要从一个数据库实时同步到另一个数据库的问题,同构数据还相对容易,遇上异构数据.表多.数据量大等情况就难以同步.我自己亲测了一种方式,可以非常方便地完成 Oracle ...

  4. Oracle 数据怎么实时同步到 PgSQL | 亲测干货分享建议收藏

    摘要: 这段时间负责一个老项目开发的数据库管理工作,这个项目中开发库与测试数据库分离,其中有些系统表数据与基础资料数据经常需要进行同步,相信很多 DBA 同学经常会遇到要从一个数据库实时同步到另一个数 ...

  5. Oracle 数据怎么实时同步到 MongoDB | 亲测干货分享建议收藏

    摘要: 很多 DBA 同学经常会遇到要从一个数据库实时同步到另一个数据库的问题,同构数据还相对容易,遇上异构数据.表多.数据量大等情况就难以同步.我自己亲测了一种方式,可以非常方便地完成 Oracle ...

  6. “约见”面试官系列之常见面试题之第九十四篇之MVVM框架(建议收藏)

    目录 一句话总结:vm层(视图模型层)通过接口从后台m层(model层)请求数据,vm层继而和v(view层)实现数据的双向绑定. 1.我大前端应该不应该做复杂的数据处理的工作? 2.mvc和mvvm ...

  7. 6大热门开源自动化测试框架【建议收藏】

    如果您正在考虑构建自己的测试自动化框架,请在自荐之前,参考一下以下的六大热门自动化测试框架. 在大多数情况下,您将会很好地考虑一个或多个可用的开放源代码选项.这是因为一般来说,框架是可以在团队中使用的 ...

  8. 用一个文件,实现迷你 Web 框架(建议收藏)

    当下网络就如同空气一样在我们的周围,它以无数种方式改变着我们的生活,但要说网络的核心技术变化甚微. 随着开源文化的蓬勃发展,诞生了诸多优秀的开源 Web 框架,让我们的开发变得轻松.但同时也让我们不敢 ...

  9. 【微信小程序开发小白零基础入门】微信小程序框架【建议收藏】

    微信小程序框架 文章目录 微信小程序框架 一.逻辑层 1.注册程序 1.App()函数 2.onPageNotFound()函数 3.getApp()函数 2.注册页面 1.初始数据 2.生命周期回调 ...

最新文章

  1. 笔画宽度变化(C++和matlab算法)
  2. STL,ATL,WTL之间的联系和区别
  3. CountDownLatch、CyclicBarrier、Semaphore的区别,你知道吗?
  4. 4月22日(牛马不对嘴)
  5. 【RabbitMQ】一文带你搞定RabbitMQ延迟队列
  6. PyTorch基础-Dropout和正则化-05
  7. 十、Linux文件系统基本操作(mount挂载,umount卸载)
  8. Java中各种整形类型可以表示的范围
  9. XShell安装lrzsz实现文件上传到Linux服务器
  10. RocketMq 事务消息使用
  11. UVALive 4794 Sharing Chocolate DP
  12. C++STL笔记(三):array详解
  13. 明知道计算机是吃青春饭,为什么还有那么多人前仆后继
  14. unexpected error ConnectionError object has no attribute
  15. 终于注册csdn博客了!
  16. java 使用Apache PDFBox 对 PDF 文件进行剪裁
  17. RF射频信号,高速信号能将电源平面作为参考平面吗?
  18. Bert Ertman专访:将Spring及遗留应用迁移到Java EE 6平台
  19. web项目引入PDF.js并添加水印禁止下载
  20. 计算机日常应用之教学PPT-1

热门文章

  1. fiddler抓包新闻APP
  2. 运维真心苦,这次我要和大家说说心底话了
  3. matlab 负数二进制转成十进制
  4. 记录深度学习(五)----最小二乘法与梯度下降原理及实现
  5. 5条提升学习效率的法则
  6. 简单说说一个系统从单机到分布式到演变
  7. linux下i2c从设备可以主动发数据,Linux Kernel 设备驱动之I2C之host之数据传输
  8. jlink项目之成功前积累并最后已成功
  9. ftp 550 Failed to change directory
  10. pnd1 c语言,c语言实现中缀后缀前缀表达式相互转化并求值