【新手教程】【羊了个羊】

打算以新手教程的方式记录一下《羊了个羊》开发过程。算是回馈 CocosCreator 做的一篇教程。
新手向的教程要把开发游戏并上架过程中遇到的每一个问题讲清楚。这个过程只有 2 个核心:
1、做出产品;
2、受众是新手;

本工程开源于 gitee (无 license,随便改,随便用):
https://gitee.com/zhx86/ccyang

教程目录:
1、开发环境篇
2、新建工程并使用 git 托管
3、初始场景
4、屏幕适配策略
5、屏幕适配策略-实操
6、首屏展示
7、游戏界面
8、游戏界面的控制
9、实例化预制体方式创建游戏界面
10、动态加载预制体
11、关于框架的意义和演变
12、资源管理器
13、背景音乐
14、明确首场景任务,传递责任链
15、登录模块
16、修复 3.8.4 适配策略不生效的问题
17、编辑器效果图
18、音频管理器(初步)
19、添加主游戏场景入口
20、背景音乐资源移动到登录模块
21、手写字符串是很容易出错的-为自动化做准备
22、自动化脚本-生成音频配置文件 TODO
23、模拟登录态,预留登录接口
24、资源管理器提供加载 Bundle 的接口,其返回类型为 Promise<AssetManager.Bundle>
25、引入界面管理器 UIManager 的缘由
26、UIManager 初步实现
27、UIManager 中的层级管理
28、改造 UIManager.open 方法
29、getUIClassBUrl 的实现
30、 引入脚本包 GScriptBN
31、将屏幕适配逻辑移动到 UIManager 中

本游戏已经集成到微信小游戏《经典休闲益智单机游戏合集》中,欢迎扫码体验
小程序码
2025年1月1日,本游戏同步集成到抖音小游戏《经典休闲移植单机合集》中,使用抖音、头条等字节系应用扫码体验:
qrcode

44赞

我还以为说你是新手,刚想装个x说让你可以向我请教拼UI的技巧 :rofl:

2赞

一、开发环境篇

1、电脑: Mac2019

2、游戏引擎解决方案: CocosCreator 编辑器,版本 3.8.4

下载地址:Cocos Creator 下载 - 轻量高效的开发引擎

注意先下载 CocosDashboard 然后在 Dashboard 中点击【安装】后,安装 3.8.4 版本的编辑器

3、Edge 浏览器(用于开发环境下预览游戏和代码调试)

4、代码编辑器 VSCode (或者 WebStorm,哪个顺手用哪个)

5、nodejs v20.14.0 (开发过程中需要编写一些工具,个人通常倾向于使用 nodejs 实现这些工具)

下一篇 新建工程并使用 git 托管

新建工程并使用 git 托管

一、新建工程

1、打开【CocosDashboard】,后续简称 Dashboard。

2、在打开的 Dashboard 中点击左侧【项目】;

3、点击右上角【新建项目】;

4、编辑器版本勾选 3.8.4。选择 Empty3D 模板。项目名称命名为 “CCYang”,项目位置选择桌面(我的电脑是: /Users/z/Desktop),点击【创建并打开】;

这里为什么选择 Empty3D 而不用 Empty2D,这里个人是这么理解的:

Empty2D 和 Empty3D 的区别到底在哪里,这里我自己是说不太上来的。目前只知道引擎剪裁部分剔除了 3D 相关组件。其它的说实话,不知道。

所以所有的项目,都是从 Empty3D 开始(它是完整的),我们去剔除不要的部分(这样我们知道做了哪些操作),这样哪里出问题了,心里是有数的。

二、使用 git 进行版本控制并托管
什么是 git 托管?为什么要使用 git 托管?

git 是一种版本控制的工具,git 托管是一种将游戏备份在托管平台的方式,可以帮助我们快速恢复或者切换到游戏的历史版本,以及衍生出来针对版本的各种操作。

使用 git 及 git 托管好处多多。

1、可以帮助我们了解我们做出了哪些改动;
2、备份工程,防止因为误操作删除了工程,或者电脑损坏、失窃的情况下,恢复游戏工程;
3、多人协作。托管游戏工程后,他人也能够同步游戏工程进行开发;

回到正题,引擎自动帮忙初始化了一个 git 工程,并帮我们添加了忽略文件。

这里有几个地方需要修改:

1、.gitignore 文件中,需要增加 .DS_Store (Mac 上忽略的文件)

2、以下几个文件中,移除 “build/”,因为单独某个平台构建相关东西,比如微信,我希望构建层级再多一级 wx,并把构建相关内容,放在这个文件夹下的 wechatgame,这样微信构建相关的其它一些配置内容可以放在 build/wx/下,比如 jenkins 持续集成用到的微信小游戏平台的构建配置 buildConfig.json、机器人上传后台的密钥文件,或者是微信小游戏平台代码加固配置文件等。

3、将 “local/” 这类的斜杆移动到前面,否则如果我们的工程中如果有一些文件夹也是以 local 命名,将会被忽略掉,而这点显然官方没有注意到

因此将下面的内容

library/ 
temp/ 
local/ 
build/ 
profiles/ 
native/

更改为

/library 
/temp 
/local 
/profiles 
/native 
/build/wx/wechatgame/

然后将工程添加后提交。

git add . 
git commit -m "初始化创建 Empty3D 模板工程" 

git remote add gitee git@gitee.com:zhx86/ccyang.git 

git push gitee main -u

本工程开源于 gitee (无 license,随便改,随便用):
https://gitee.com/zhx86/ccyang

下一篇 初始场景

改成新手教程了

三、初始场景

1、保存场景。

Creator 通过 Empty3D 模板创建的空工程,默认创建了一个未保存状态的名为 Untitled 的场景。

我们通过 Ctrl + S 保存该场景,此时会让我们选择保存的目录,我们将它命名为 Main,并保存到

CCYang/assets/ 路径下,即

CCYang/assets/Main.scene

2、调整编辑器布局

拖拽编辑器相关界面,调整成下方样式,最重要的点在于,要把【层级管理器】和【属性检查器】相邻摆放,因为编辑器中有很多操作是拖拽节点或者拖拽预制体到脚本组件上,所以这样的布局能有效减少拖拽的距离,距离就是时间,时间就是生命,浪费生命是可耻的,切记。

3、删除 3D 相关内容

3.1、删除 Main.scene 中 3D 关联的天空盒相关资源。

选中【层级管理器】中的场景根节点【Main】。在【属性检查器】中找到 Skybox 组件,清除 Envmap 属性中的 HDR 和 LDR 关联的天空盒资源 “default_skybox”

删除后,需要将 Skybox 中的 Enabled 组件的 Enabled 复选框的勾选状态去除。

3.2、切换场景的显示模式为 2D 模式

在【场景编辑器中】点击 【3D】切换成 【2D】 模式。

3.3、添加 2D Canvas 和 2D 摄像机,并移除 3D 的光照和 3D 摄像机

在【层级管理器】中,选中场景节点【Main】,并鼠标左键双击这个节点,这样右侧的【场景编辑器】会自动聚焦到 Canvas 的原点位置

然后鼠标右键点击【Main】节点,选择【创建】【2D 节点】【Label文本】并命名为 Label。

这时候,编辑器会帮我们自动创建以下内容:
1)Canvas 节点(是一个 Node 节点,并挂载了 UITransform 组件、 Canvas 组件、 Widget 组件);
其中 UITransfrom 组件标识这是一个 2D 节点,此组件用于确定节点的锚点、尺寸,以及提供进行本地-世界坐标变换的相关接口。其余组件暂不用关心。
2)Camera 节点(Canvas 节点的子节点),在本游戏中,这将会是我们唯一的一个摄像机。
3)Label 节点,用于显示文本;

在对新创建的节点进行修改前,我们先删除旧的 【Main Light】和【Main Camera】节点。
分别右键点击这 2 个节点,选择【删除】后保存即可。

接下来我们继续对刚刚创建的 3 个节点进行修改:
1)首先,我们的 Canvas 节点,它的 Layer 是 UI_2D,请先牢记这个属性。
2)左键选中 Camera 节点,将其命名为 Camera_UI_2D;
并将其 Visibility 属性中的 UI_3D 去除(游戏中不会存在这类渲染节点,因此删除)


这样摄像机只会渲染Layer 为 UI_2D 的渲染节点了。
3)修改摄像机的 ClearFlags 为 SOLID_COLOR
4)Label 节点中的 cc.Label 组件中的【字符串】更改为 Hello World,字体大小更改为 40

保存后点击运行。
image

出现 Hello World 的运行结果即成功。

最后提交所有变化到 git,本小结结束。

下一篇 屏幕适配策略

屏幕适配策略

1、什么是屏幕适配策略

屏幕适配策略包含了 3 个要素:

  1. 屏幕朝向

  2. 设计分辨率

  3. 适配策略

在羊了个羊的游戏中,我们的【屏幕适配策略】是这样的:

  1. 竖屏

  2. 设计分辨率为 750x1334

  3. 适配策略是: 如果屏幕更宽(比如说 iPad),那么高度适配,屏幕更长(iPhone16),那么宽度适配。

具体是什么意思呢?下面逐一解释。

2、设计分辨率解决什么问题?

先说结论:

设计分辨率主要解决了【美术根据什么样的规范去设计整个游戏界面资源的问题】

在《羊了个羊》这个游戏中,我们确定了屏幕适配策略,并告知美术,于是美术就知道如何去出美术资源了。

美术出资源中,涉及适配策略的内容主要包含:

1) 游戏的背景图

2) 游戏中的 UI 元素布局

2.1 背景图

1)如果背景图是可以随便变形的,那么美术直接出成 750x1334 即可

2)如果背景图是可以平铺的,那么基本上和设计分辨率没什么关系,平铺即可

3)如果背景图必须保持比例,那么要考虑背景图是否允许缩放
3.1) 允许缩放,那么开发自己通过挂载缩放组件,去适配;
3.2) 不允许缩放,那么这时候,美术就必须考虑【适配策略】中的 2 种情况

3.2.1) 如果手机屏幕尺寸是更宽的(iPad),那么根据开发适配策略,如果美术出的图是 750x1334,那么进行高度适配后,屏幕左右两侧出现黑边。(这种情况下,美术有 2 种做法:A.提供图片,去补2侧黑边; B. 增加750这个宽度值到某个W,使其和 IPad 的宽高比一致。W 多少值呢?那取决于市面上最胖的那台设备的宽高比。或者综合考虑,看是否覆盖到哪个程度的机型来确定的)

3.2.2) 如果手机屏幕是更高的(iPhone16),那么根据开发适配策略,如果美术出的图是 750x1334,那么进行宽度适配后,屏幕上下两侧出现黑边。(同样的,美术通常的做法是,提供更高的图片,比如说 750x1750,具体原则和前面计算 W 值是类似的,这里不多说了。)

2.2 界面元素布局

美术出的界面元素,只能出现在 750x1334 的屏幕范围内,当然,要考虑到刘海屏、挖孔屏和小游戏平台的胶囊体对界面布局的影响。

综上所述,美术出图的策略,会影响到开发的适配,如果出的背景图是可拉伸的,那就非常的爽了,所以尽量去讨好美术大佬,让他们发挥自己的聪明才智,设计出这种背景图,才是最优解。

3、开发的适配策略

开发如何去将一套的美术资源显示在不同尺寸的设备屏幕的?

我们前面讲到了

如果屏幕更宽(比如说 iPad),那么高度适配,屏幕更长(iPhone16),那么宽度适配。

这到底是什么意思呢?

我们来看具体的例子:
分别看 2 台设备:
1)iPad 屏幕是尺寸 1668x2224
2)iPhone16 屏幕尺寸是 1179x2556

如果不做适配,理论上两台设备上应该分别是这样显示的:
iPad


iPhone

其中黑色表示屏幕,蓝色图片是美术的图片(750x1334)(这里我们先假设美术出了一张不规范的图,因为它没有考虑黑边的情况)

iPad 高度适配以后,它将变成以下样式:


实际上引擎对画布做了缩放,缩放比例为:
2224/1334 ≈ 1.6672

iPhone 宽度适配以后,它将变成以下样式:


实际上引擎对画布做了缩放,缩放比例为:
1179/750 = 1.572

实际上我们确实发现,美术只要给出 2 黑边的解决方案所需的资源(或者允许缩放,拉伸),我们就能很快的修复这个黑边问题。

在确定适配策略以后,本篇最重要的东西来了。
【在确定了适配策略以后,请问,之前的这 2 台设备 iPad 和 iPhone16 上运行我们的游戏时, 画布 Canvas 和屏幕的关系是什么?】
只有搞定了最后这个问题,屏幕适配才算真正掌握了。

结论1:Canvas 画布和屏幕的关系是缩放关系。

画布 Canvas 的尺寸,在我们适配完毕后,就是 750x1334 + 黑边所组成的部分。它的尺寸分别是:

iPad 设备中的画布尺寸 = 1001 x 1334 (其中 1001 ≈ 1668/1.6672)
iPhone16设备中的画布尺寸 = 750 x1626(其中 1626 = 2556/1.572)

即我们做完适配策略后,Canvas 画布被标准化下来了。Canvas 要么比设计分辨率更胖,要么比设计分辨率更长,但是总有一边是“贴合”的。
我们所有以上的工作,都是为了让我们只需要去关心画布,不用关心设备尺寸(说白了就是解耦设备尺寸)。

当然,还会有需要关注的时候,比如胶囊体、刘海之类的,他们是在屏幕坐标系下的度量衡,并不是在我们的设计分辨率 750x1334 标准下的度量衡。

结论2: 同一对象,在 Canvas 画布的尺寸和设计分辨率的尺寸是一致的。

结论3:设计分辨率在 Canvas 画布中完全可见,并且宽和高至少有一个是相同的。

以上就是个人理解的适配策略,也一直沿用至今。
本节属于理论部分,下节将进入实操。

下一篇 屏幕适配策略-实操

3赞

mark :heartbeat:

1赞

点赞!真正手把手。

以前找资料说的“新手教程”,都会默认新手知道“创建按钮”、“label组件”在哪里

1赞

真心有用,干货

1赞

mark!

1赞

坐等更新,太实用了

1赞

屏幕适配实操

修改项目的设计分辨率

点击菜单栏【项目】,点击【项目设置】,找到【设计宽度】,将它更改为 750,找到【设计高度】,将它更改为 1334。

然后点击【场景编辑器】,我们发现,屏幕已经变成 750x1334

开发添加适配策略组件

点击【资源管理器】中的 assets 目录,右键点击【创建】【脚本(TypeScript),将脚本命名为 Boost

然后双击 Boost.ts 脚本打开 VSCode 编辑器(配置请参考官方的脚本编辑器配置文档),将 Boost.ts 的内容如下

import { _decorator, Component, ResolutionPolicy, screen, Size, view } from 'cc';
const { ccclass, property } = _decorator;

/** 
 * 画布的标准化尺寸,就是之前说的
 * iPad 设备中的画布尺寸 = 1001 x 1334 (其中 1001 ≈ 1668/1.6672)
 * iPhone16设备中的画布尺寸 = 750 x1626(其中 1626 = 2556/1.572)
 */
export const G_VIEW_SIZE = new Size(0, 0);

@ccclass('Boost')
export class Boost extends Component {
    start() {
        this.adapterScreen();
    }

    adapterScreen() {
        let resolutionPolicy: ResolutionPolicy = view.getResolutionPolicy();
        let designSize = view.getDesignResolutionSize();
        let frameSize = screen.windowSize;
        let frameW = frameSize.width;
        let frameH = frameSize.height;
        /** 是否是屏幕更宽 */
        const isScreenWidthLarger = (frameW / frameH) > (designSize.width / designSize.height);
        let targetResolutionPolicy = isScreenWidthLarger ? ResolutionPolicy.FIXED_HEIGHT : ResolutionPolicy.FIXED_WIDTH;
        if (targetResolutionPolicy !== resolutionPolicy.getContentStrategy().strategy) {
            /** 保证设计分辨率的内容都能显示出来 */
            view.setDesignResolutionSize(designSize.width, designSize.height, targetResolutionPolicy);
        }

        /** 实际的尺寸会和设计分辨率在一个维度,但是宽或高更大 */
        if (isScreenWidthLarger) {
            G_VIEW_SIZE.width = Math.ceil(designSize.height * frameSize.width / frameSize.height);
            G_VIEW_SIZE.height = designSize.height;
        } else {
            G_VIEW_SIZE.width = designSize.width;
            G_VIEW_SIZE.height = Math.ceil(designSize.width * frameSize.height / frameSize.width);
        }

        console.log(`屏幕${isScreenWidthLarger ? "更宽, 高度适配" : "更高, 宽度适配"} 设计分辨率比例下的屏幕尺寸: ${G_VIEW_SIZE.width}x${G_VIEW_SIZE.height}`);
    }
}

这里除了根据屏幕尺寸去调整适配策略外,还将画布的尺寸记录在了 G_VIEW_SIZE 变量中,方便后续使用。

Canvas 节点挂载 Boost 脚本

创建的 Boost 脚本是一个组件,继承自 Component,它并不会被实例化成一个对象。我们主要有 2 种实例化组件的方式:

  1. 将脚本组件拖拽到节点上,节点实例化的时候,其挂载的组件也会被实例化;
  2. 在另一个脚本中,通过编写代码的方式,对已经实例化并激活的节点,调用其addComponent(组件)的方式进行实例化;

这里我们用第一种方式,【层级管理器】中,选中 Canvas 节点,将脚本拖拽到【属性检查器】中(或者选中 Canvas 节点后,点击【添加组件】按钮,输入 Boost,后,选中 Boost 组件即可)。


于是我们基本完成了适配的实操。

至于屏幕方向的设置,这需要等到构建的时候,才会进行设置。

下一篇 首屏展示

1赞

first star

1赞

太强了 :smiley:

1赞

首屏展示

在完成屏幕适配后,我们现在首先需要一些资源。在 github 上搜索一下关键字:“Cocos 羊了个羊”,找到工程:https://github.com/blakeyi/yanglegeyang-client/tree/master/assets/res
拿到里面的羊了个羊的背景相关资源。
或者在 Cocos 商店上找点免费或者付费资源 https://store.cocos.com/app/

这里我从资源库里找了点素材(素材皆来自互联网免费资源,或者付费资源,当然有些是盗版资源,请使用前进行换皮,谢谢!)。

在导入资源前,我们先设置一下项目默认导入图片的格式,方便我们在 2D 游戏中使用(因为默认导入到图片资源类型是 texture,无法在 2D 界面中使用)。在 Mac 下点击【Cocos Creator】,点击【设置】,在打开的【偏好设置】里,选择【资源数据库】,将【默认资源导入类型】中的【图片】【类型】更改为 sprite-frame。

这个操作后,引擎在隐藏文件夹 CCYang/.creator/ 下会新建了一个文件 default-meta.json 文件,持久化了我们的设置:

最后,在 assets 目录下,我们新建 yang 文件夹,将资源导入。
并添加一个自动图集并命名为 auto-atlas-match3。(参考官方文档-如何添加自动图集
并且设置不剔除未引用的资源。

添加背景图和游戏名称,并添加健康游戏忠告

添加背景图

首先声明一下,我们要添加的背景图是纯色的。

点击【场景编辑器】,然后在左侧【层级管理器】中选中 Canvas 节点,右键【创建】 【2D 对象】【Sprite 精灵】 ,并将其命名为 BG。

这时候,我们注意到,官方会默认为图片设置了一个 sprite-frame ,这个 sprite-frame 是 internal 文件夹下的资源。

这里注意一个原则,官方的资源,一定要替换成游戏内自己的资源。哪怕是复制一份到 assets 文件夹下。

然后将这个 sprite-frame 替换成我们的纯色资源 bg-2x2。

这里我提前对 bg-2x2 的 sprite-frame 进行了操作:更改了其九宫格的 4 个边距 Border Top、 Border Bottom、Border Left 和 Border Right 4 个属性分别为 1。具体可点击 bg-2x2 查看。

将 BG 节点的 Sprite 组件的 Size Mode 更改为 Custom,Type 更改为 Slice,然后将其尺寸设置为 750x1334,颜色值更改为 CFFB9A。最后添加一个 Widget 组件(在 BG 节点的【属性检查器】 中,点击【添加组件】,输入 Widget 后,选中 Widget 组件即可),并设置水平约束和垂直约束。

添加游戏名称

将【BG】节点拖拽到【Label】节点和【Camera_UI_2D】节点之间;
调整【Label】节点的 y 值为 160;
更改 Label 的字符串为羊了个羊
【字体大小】和【行高】都调整为 80;
勾选【启用描边】;
【描边宽度】更改为4。

新增健康游戏忠告

尤其是游戏备案和版本审核,都会要求首屏显示健康游戏忠告。这是每个游戏人应尽的义务。

Canvas 下创建 advice 节点
设置文本:

健康游戏忠告
抵制不良游戏 拒绝盗版游戏 注意自我保护 谨防受骗上当
适度游戏益脑 沉迷游戏伤身 合理安排时间 享受健康生活

字体大小和字高调整到 24,颜色更改为黑色。
新增 Widget 对齐组件,对齐Canvas节点的下边缘,距离 8 个像素。如图所示:

点击运行,我们完成了首屏展示

下一篇 游戏界面

1赞

游戏界面展示

首先我们用最简单的方式展示游戏主界面:在 Canvas 节点下添加一个名为【Match3UI】的精灵(Sprite) 节点,设置尺寸为 750x1334。设置颜色为红色,调整透明度为 80。(我们已经知道如何添加精灵节点了,这里不复述了)并且这个节点上,我们暂时不挂载 Widget 对齐组件。

羊了个羊本质是一个三消类型的游戏, 因此取名 Match3

上面这个做法,是为了演示,在 iPad 设备情况下,首屏界面和游戏界面尺寸的一个对比情况。
因此运行游戏的时候,我们需要在浏览器中选中模拟器。

这时候,我们发现在 iPad 的屏幕适配出了问题,这不是我预期的情况。
原因是适配策略未生效。
因此这里做了一个不是很优雅的修复。
在 Boost.ts 脚本的 adapterScreen 方法中,最后一行添加

    adapterScreen() {
        // 保持不变....

        return isScreenWidthLarger;
    }

然后修改 start 方法中的内容为:

    start() {
        const WIN_SIZE_W = screen.windowSize.width;
        const WIN_SIZE_H = screen.windowSize.height;
        let isScreenWidthLarger = this.adapterScreen();
        if (isScreenWidthLarger) {
            screen.windowSize = new Size(WIN_SIZE_W + 1, WIN_SIZE_H);
            screen.windowSize = new Size(WIN_SIZE_W, WIN_SIZE_H);
        }
    }

重新运行后,发现符合我们的预期,游戏界面确实是高度适配。

下一篇 游戏界面的控制

1赞

很用心的教程:+1:

1赞

游戏界面的控制

我们希望能够在进入首页,延迟 1 秒后,再显示游戏界面(半透明的红色部分)。用来模拟加载后进入游戏的情形。

因此,我们需要先将【游戏界面节点 Match3UI】绑定到组件 Boost 的属性上,然后在 Boost 脚本上控制界面的显示。

首先在 Boost.ts 脚本中,添加属性:

export class Boost extends Component {
    // 下面这行为新添加的代码
    @property(Node) private match3Node: Node = null;
}

新添加的属性是 Cocos Creator 提供的绑定机制(参考 官方文档)。

然后点击【层级管理器】中的【Canvas】节点,将 Match3UI 节点拖拽到该属性中。

接下来在 Boost.ts 脚本的 start 方法中添加控制逻辑:

    start() {
        // 省略旧逻辑

        this.match3Node.active = false;

        this.scheduleOnce(()=> {
            this.match3Node.active = true;
        }, 1)
    }

运行后发现,确实在延迟 1 秒后,出现了游戏界面。

但是目前 游戏界面的尺寸,并没有覆盖全屏。因此我们需要设置 Match3UI 节点的尺寸到全屏(我们已经知道全屏对于 Canvas 画布的尺寸,这个尺寸经过计算已经被我们填充在 G_VIEW_SIZE 变量中)。

因此在 start 方法中继续添加逻辑

    start() {
        // 省略旧逻辑

        this.match3Node.active = false;

        this.scheduleOnce(()=> {
            this.match3Node.active = true;
        }, 1)

        this.match3Node.getComponent(UITransform).setContentSize(G_VIEW_SIZE.clone());
    }

重新运行,符合预期!

1赞

实例化预制体方式创建游戏界面

在上个小节中,我们是直接在场景 Main 中的【Canvas】节点下,直接创建好【Match3UI】节点的方式去实例化游戏界面的。

这种方式其实是不好的。

为什么说这种方式不好?

Main场景我们认为是启动场景,启动场景只关心启动逻辑,Match3UI 是一个玩法界面,玩法界面为什么要在启动时就创建好呢?它应该是玩家点击,或者是逻辑脚本控制其【动态创建】。

可以通过脚本编辑器VSCode 去定位到逻辑触发的位置。

所以我们需要动态去创建这个 【Match3UI】。因此,我们需要将 Match3UI 节点制作成一个预制体(官方文档-预制体制作)。

在制作预制体前,我们先移除之前脚本 Boost.ts 中绑定的 match3Node

接下来将【Match3UI】节点拖拽到 assets 目录下,制作成一个预制体。
然后把层级管理器中的【Canvas】节点下的 【Match3UI】节点删除。

然后在 Boost.ts 脚本中,将原来的

@property(Node) private match3Node: Node = null;

更改为

@property(Prefab) private match3Prefab: Prefab = null;

记得需要从 ‘cc’ 模块 import 一下 Prefab

同步修改 start 方法中的逻辑:

    start() {
        const WIN_SIZE_W = screen.windowSize.width;
        const WIN_SIZE_H = screen.windowSize.height;
        let isScreenWidthLarger = this.adapterScreen();
        if (isScreenWidthLarger) {
            screen.windowSize = new Size(WIN_SIZE_W + 1, WIN_SIZE_H);
            screen.windowSize = new Size(WIN_SIZE_W, WIN_SIZE_H);
        }
   
        this.scheduleOnce(()=> {
            let match3Node = instantiate(this.match3Prefab);
            this.node.addChild(match3Node);
            match3Node.getComponent(UITransform).setContentSize(G_VIEW_SIZE.clone());
        }, 1)
    }

记得需要从 ‘cc’ 模块 import 一下 instantiate

再将之前制作好的预制体,拖到新增加的属性 match3Prefab 上:

点击运行。就完成了通过 instantiate 实例化游戏界面的功能了。

顺便再补充说明一下上面的脚本逻辑:
instantiate(this.match3Prefab); 是通过预制体创建节点的方法。预制体本质就是一个结构说明(json)文件,它记录了这个节点有哪些属性,属性值是多少,有哪些组件,各个组件的属性又是怎么样的,仅此而以。

this.node.addChild(match3Node);
实例化的节点必须添加到某个节点下,才会被渲染出来。

到这里,我们发现,启动的时候,仍然需要在 Boost.ts 中将预制体提前绑定到组件属性上。这显然也是有问题的。那么预制体 Prefab 究竟要如何动态加载的?这就是下一节的内容了。