Cocos Creator的Hello World

0、文档

Cocos官网文档

1、下载

访问cocos官网下载Cocos Dashboard
安装时选项安装 Visual Studio 2017可以不勾选
注意:Cocos Dashboard的快捷方式文件名为CocosDashboard.exe,不要误认为是安装文件

2、注册、登录

注册/登录cocos网址

3、Cocos Dashboard设置语言

Cocos Dashboard,点击右上角点击齿轮图标在这里插入图片描述打开设置界面
Language(Choose a display anguage.),修改为简体中文
点击右下角返回按钮退出设置界面。

4、安装编辑器

Cocos Dashboard(Cocos仪表板),版本管理软件。类似node.js的nvm,python的conda
它可以管理Cocos Creator游戏项目,无论项目基于的引擎版本是多少


Cocos Dashboard,点击右上角点击齿轮图标
自行决定修改编辑器目录,该设置会修改编辑器的存放位置

左侧边栏,点击编辑器,右下角点击下载编辑器按钮
选择一个版本点击右侧的下载图标在这里插入图片描述即可,本文选择下载CocosCreator 3.7.2
服务协议界面,点击同意按钮
等待下载
系统提示Cocos Creator 3.7.2 下载成功 正在解压中
(闲得无聊可以打开任务管理器查看CPU占用和磁盘占用,反正也没啥用)
系统提示Cocos Creator 3.7.2 安装成功 欢迎使用Cocos Creator 3.7.2
此时编辑器安装成功

5、新建项目

左侧边栏,点击项目,右下角点击新建按钮
编辑器版本默认选择刚安装的3.7.2
模板选择Empty(2D)
项目名称输入HiCocos(项目名称不能有特殊字符、空格,且不能以.结尾)
位置默认或自行修改
右下角点击创建按钮
等待加载

6、Cocos Creator设置语言

菜单栏 - File - Preferences,打开Preferences窗口
General分类,Language修改为中文
关闭Preferences窗口

7、配置代码编辑器

安装插件Prettier用于格式化ts脚本
格式化快捷键Shift+Alt+F,第一次格式化ts脚本时,配置默认格式化程序选择Prettier
VSCode左下角齿轮图标,设置,搜索Prettier: Tab Width,可以将其设置为4


如果安装了VSCode,默认情况下Cocos Creator可以找到VSCode,双击脚本文件自动就打开了,一般不用设置
(虽然它还是假装找不到,在控制台里提示如下(提示还是过时的):为更好地打开脚本,请在 偏好设置 -> 外部程序 -> 默认脚本编辑器 里配置打开脚本的应用程序)


如果双击脚本提示未关联脚本编辑器,按照以下步骤设置
VSCode下载教程,安装
安装完运行where.exe code得到路径C:\Program Files\Microsoft VS Code\bin\code
然后找到VSCode安装文件夹,C:\Program Files\Microsoft VS Code\Code.exe
Cocos Creator,菜单栏,文件,偏好设置,程序管理器,默认脚本编辑器,点击右侧的放大镜图标在这里插入图片描述
设置为Code.exe即可

8、扩大场景编辑器窗口

一般情况下,场景编辑器窗口大些比较容易查看,其他窗口可以随时拖拽回来
鼠标放到窗口边框,鼠标指针变为双向箭头时,拖拽窗口,使场景编辑器更大
请添加图片描述

9、如何重命名节点

层级管理器,选中要修改的节点
点击F2Enter、右键选择重命名或者在属性检查器的第一行修改名称

10、添加一个玩家

左上角层级管理器,右键Canvas,创建,空节点,重命名为玩家

11、添加一个玩家子节点精灵

左上角层级管理器,右键玩家,创建,2D对象,Sprite(精灵),重命名为身体
选中身体,查看右侧属性检查器,倒数第5项Sprite Frame,点击旁边的鼠标图标在这里插入图片描述修改精灵帧
选个按钮当身体用,选择default_btn_normal

层级如图,如果层级不对可以参考gif进行拖拽
在这里插入图片描述请添加图片描述

12、添加脚本

左下角资源管理器,右键assets,创建,文件夹,命名为脚本
右键脚本,创建,脚本(TypeScript),NewComponent,命名为PlayerController

13、玩家加载脚本

左上角层级管理器,选中玩家
右侧属性检查器,点击添加组件按钮
展开自定义脚本,点击PlayerController
加载完成

14、制作一个预制体

左下角资源管理器,右键assets,创建,文件夹,命名为预制体

左上角层级管理器,右键Canvas,创建,2D对象,Sprite(精灵),重命名为浮岛
右侧属性检查器,Sprite Frame,设置为default_btn_disabled

将创建好的浮岛拖拽进预制体文件夹
删除层级管理器里创建的浮岛

15、保存场景

左下角资源管理器,右键assets,创建,文件夹,命名为场景

快捷键Ctrl+S(或点击菜单栏 - 文件 - 保存场景(CTRL+S)),弹出保存场景窗口
进入场景文件夹,文件名scene.scene改为游戏.scene,保存

16、编辑脚本

左下角资源管理器,assets,脚本,PlayerController,双击文件打开 VSCode编辑器 编辑代码

16.1 改模板

查看默认代码.\HiCocos\assets\脚本\PlayerController.ts

import {
    
     _decorator, Component, Node } from 'cc';
const {
    
     ccclass, property } = _decorator;

@ccclass('PlayerController')
export class PlayerController extends Component {
    
    
    start() {
    
    

    }

    update(deltaTime: number) {
    
    
        
    }
}

将其改为本教程的模板

// import 导入位置1
import {
    
     _decorator, Component, Node } from "cc";
const {
    
     ccclass, property } = _decorator;

// export 常量位置1

@ccclass("PlayerController")
export class PlayerController extends Component {
    
    
    // Animation 动画属性1

    // private 私有属性1
    // private 私有属性2

    // 组件第一次激活时调用的方法
    start() {
    
    }

    // 激活后关闭鼠标监听的方法

    // 重置方法

    // 监听鼠标输入方法

    // 根据步数跳跃方法

    // 监听跳跃结束的方法

    // 根据每次的更新来计算角色最新的位置方法
    update(deltaTime: number) {
    
    }

    // 直到教程结束, 此处的"}"符号一直作为脚本最后一个字符
    // ↙
} 
// ↖
// 它的配对符号必须为"export class PlayerController extends Component {"中的"{"
// VSCode会把这对花括号对"{}"显示为相同的颜色表明它们的配对关系, 点击其中一个, 两个符号会同时显示一个小边框

16.2 添加 PlayerController 在本教程的所有导入

    // import 导入位置1

改为

    // import 导入位置1
    import {
    
     Vec3, EventMouse, input, Input, AnimationComponent } from "cc";

16.3 添加监听鼠标输入方法

    // private 私有属性1

改为

    // private 私有属性1
    private _startJump: boolean = false;
    private _jumpStep: number = 0;
    private _curJumpTime: number = 0;
    private _jumpTime: number = 0.3;
    private _curJumpSpeed: number = 0;
    private _curPos: Vec3 = new Vec3();
    private _deltaPos: Vec3 = new Vec3(0, 0, 0);
    private _targetPos: Vec3 = new Vec3();

16.4 计算角色移动

    // 根据步数跳跃方法

改为

    // 根据步数跳跃方法
    jumpByStep(step: number) {
    
    
        if (this._startJump) {
    
    
            return;
        }

        // 动态计算_jumpTime

        this._startJump = true; // 标记开始跳跃
        this._jumpStep = step; // 跳跃的步数 1 或者 2
        this._curJumpTime = 0; // 重置开始跳跃的时间

        this._curJumpSpeed = this._jumpStep / this._jumpTime; // 根据时间计算出速度

        this.node.getPosition(this._curPos); // 获取角色当前的位置
        Vec3.add(
            this._targetPos,
            this._curPos,
            new Vec3(this._jumpStep, 0, 0)
        ); // 计算出目标位置

        // 播放动画

        // 增加步数
    }

16.5 判断鼠标是左键还是右键被按下

    // 监听鼠标输入方法

改为

    // 监听鼠标输入方法
    onMouseUp(event: EventMouse) {
    
    
        if (event.getButton() === 0) {
    
    
            this.jumpByStep(1);
        } else if (event.getButton() === 2) {
    
    
            this.jumpByStep(2);
        }
    }

16.6 使用input监听输入

    // 组件第一次激活时调用的方法
    start() {
    
    }

改为

    // 组件第一次激活时调用的方法
    start() {
    
    
        input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);
    }

16.7 使用input监听输入

    // 根据每次的更新来计算角色最新的位置方法
    update(deltaTime: number) {
    
    }

改为

    // 根据每次的更新来计算角色最新的位置方法
    update(deltaTime: number) {
    
    
        if (this._startJump) {
    
    
            this._curJumpTime += deltaTime; // 累计总的跳跃时间
            if (this._curJumpTime > this._jumpTime) {
    
    
                // 当跳跃时间是否结束
                // end
                this.node.setPosition(this._targetPos); // 强制位置到终点
                this._startJump = false; // 清理跳跃标记
                // 调用监听跳跃结束的方法
                
            } else {
    
    
                // tween
                this.node.getPosition(this._curPos);
                this._deltaPos.x = this._curJumpSpeed * deltaTime; //每一帧根据速度和时间计算位移
                Vec3.add(this._curPos, this._curPos, this._deltaPos); // 应用这个位移
                this.node.setPosition(this._curPos); // 将位移设置给角色
            }
        }
    }

16.8 运行试试,移动的不明显

请添加图片描述

16.9 放大移动动作

    // export 常量位置1

改为

    // export 常量位置1
    export const BLOCK_SIZE = 40; // 添加一个放大比

再将// 根据步数跳跃方法jumpByStep中的

this._curJumpSpeed = this._jumpStep / this._jumpTime; // 根据时间计算出速度

改为

this._curJumpSpeed = this._jumpStep * BLOCK_SIZE/ this._jumpTime; // 根据时间计算出速度并放大

再再将// 根据步数跳跃方法jumpByStep中的

        Vec3.add(
            this._targetPos,
            this._curPos,
            new Vec3(this._jumpStep, 0, 0)
        ); // 计算出目标位置

改为

        Vec3.add(
            this._targetPos,
            this._curPos,
            new Vec3(this._jumpStep * BLOCK_SIZE, 0, 0)
        ); // 计算出目标位置

17、运行

回到Cocos Creator
抬头位置,点击三角运行按钮在这里插入图片描述
请添加图片描述

18、动画

左下角资源管理器,右键assets,创建,文件夹,命名为动画
右键动画文件夹,创建,动画剪辑(Animation Clip)
将新建的Animation重命名为oneStep

选中身体,查看右侧属性检查器,点击添加组件
选择Animation - Animation
oneStep拖拽到身体Clips属性上,Clips将由0变为1

选中身体
快捷键Ctrl+6(或将控制台切换为动画编辑器)
动画编辑器提示进入动画编辑模式(Ctrl/Cmd+E)(拖拽动画剪辑资源到面板上)
oneStep拖拽到动画编辑器
(鼠标放到动画编辑器的上边框,鼠标变为⬍上下箭头,拖拽变大)
在这里插入图片描述
动画编辑器
左下角 属性列表,点击旁边的+加号添加属性轨道,选择position
点击新建的position
(Y坐标必须删除默认值手动输入后才会记录该帧的属性)
设置为0,属性检查器修改身体Position,Y坐标为0
设置为10,属性检查器修改身体Position,Y坐标为80
设置为20,属性检查器修改身体Position,Y坐标为0

动画编辑器使用状态下,按Ctrl+S保存

动画编辑器,点击三角图标按钮播放,玩家在场景编辑器窗口中跳跃

同样方式再创建一个twoStep
twoStep拖拽到身体Clips属性上,Clips将由1变为2
编辑twoStep
帧设置为0,Y坐标为0
帧设置为20,Y坐标改为80
帧设置为40,Y坐标改为0

动画编辑器使用状态下,按Ctrl+S保存
Ctrl+Q退出动画编辑器模式

19、编辑脚本(播放动画代码)

左下角资源管理器,assets,脚本,PlayerController,双击文件打开 VSCode编辑器 编辑代码

// Animation 动画属性1

改为

// Animation 动画属性1
@property(AnimationComponent)
BodyAnim: AnimationComponent = null;

新建完BodyAnim:Animation = null;之后,保存,回到Cocos Creator设置玩家Body Anim
左上角层级管理器,选中玩家
身体拖拽到右侧属性检查器的Body Anim
Ctrl+S

回到VSCode
将 jumpByStep 中的 // 播放动画

        // 播放动画

改为

        // 播放动画
        if (this.BodyAnim) {
    
    
            if (step === 1) {
    
    
                this.BodyAnim.play("oneStep");
            } else if (step === 2) {
    
    
                this.BodyAnim.play("twoStep");
            }
        }

回到Cocos Creator运行游戏,左键小跳,右键大跳(但是回落很诡异,因为还没有修改_jumpTime)

修改_jumpTime
将 jumpByStep 中的 // 动态计算_jumpTime

        // 动态计算_jumpTime

改为

        // 动态计算_jumpTime
        if (step === 1) {
    
    
            const oneStep = "oneStep";
            const state = this.BodyAnim.getState(oneStep);
            this._jumpTime = state.duration;
        } else if (step === 2) {
    
    
            const twoStep = "twoStep";
            const state = this.BodyAnim.getState(twoStep);
            this._jumpTime = state.duration;
        }

再次运行游戏,左键小跳,右键大跳,回落正常

20、游戏管理器

左下角资源管理器
右键脚本,创建,脚本(TypeScript),NewComponent,命名为GameManager

左上角层级管理器,右键Canvas,创建,空节点,重命名为游戏管理层级
选中游戏管理层级,属性检查器点击添加组件
展开自定义脚本,点击GameManager,加载完成

双击GameManager编辑它

20.1 改模板

查看默认代码.\HiCocos\assets\脚本\GameManager.ts

import {
    
     _decorator, Component, Node } from 'cc';
const {
    
     ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
    
    
    start() {
    
    

    }

    update(deltaTime: number) {
    
    
        
    }
}

将其改为模板

// import 导入位置1
// import 导入位置2
import {
    
     _decorator, Component, Node } from "cc";
const {
    
     ccclass, property } = _decorator;

// enum 枚举1

// enum 枚举2

@ccclass("GameManager")
export class GameManager extends Component {
    
    
    // 预制体

    // 道路长度

    // 地图数据

    // 属性2

    // 组件第一次激活时调用的方法
    start() {
    
    }

    // 初始化的方法

    // 控制游戏状态的读取器

    // 生成地图的方法

    // 根据所需的数量和前1个位置来生成方块

    // 根据 BlockType 生成方块

    // 响应 开始游戏 按钮按下的事件

    // 判断跳坑失败或游戏完成的方法

    // 更新计步器的显示并判断"跳坑失败或游戏完成"

    // 没有用到update,注释掉
    // update(deltaTime: number) {}

    // 直到教程结束, 此处的"}"符号一直作为脚本最后一个字符
    // ↙
} 
// ↖
// 它的配对符号必须为"export class PlayerController extends Component {"中的"{"
// VSCode会把这对花括号对"{}"显示为相同的颜色表明它们的配对关系, 点击其中一个, 两个符号会同时显示一个小边框

20.2 添加 GameManager 在本教程的所有导入

// import 导入位置1
// import 导入位置2

改为

// import 导入位置1
import {
    
     CCInteger, instantiate, Label, Prefab, Vec3 } from "cc";
// import 导入位置2
import {
    
     BLOCK_SIZE, PlayerController } from "./PlayerController";

20.3 添加一个boxPrefab

    // 预制体

改为

    // 预制体
    @property({
    
     type: Prefab })
    public boxPrefab: Prefab | null = null;

返回Cocos Creator
选中游戏管理层级
浮岛拖拽属性检查器到Box Prefab
Ctrl+S保存

20.4 添加枚举BlockType

// enum 枚举1

改为

// enum 枚举1
enum BlockType {
    
    
    BT_NONE,
    BT_STONE,
}

20.5 spawnBlockByType

    // 根据 BlockType 生成方块

改为

    // 根据 BlockType 生成方块
    spawnBlockByType(type: BlockType) {
    
    
        if (!this.boxPrefab) {
    
    
            return null;
        }

        let block: Node | null = null;
        switch (type) {
    
    
            case BlockType.BT_STONE:
                block = instantiate(this.boxPrefab);
                break;
        }

        return block;
    }

20.6 spawnBlockByCount

    // 根据所需的数量和前1个位置来生成方块

改为

    // 根据所需的数量和前1个位置来生成方块
    spawnBlockByCount(lastPos: number, count: number) {
    
    
        let block: Node | null = this.spawnBlockByType(BlockType.BT_STONE);
        if (block) {
    
    
            this.node.addChild(block);
            block?.setScale(count, 1, 1);
            block?.setPosition(
                (lastPos - (count - 1) * 0.5) * BLOCK_SIZE,
                -(BLOCK_SIZE + 1.5),
                0
            );
        }
    }

20.7 roadLength 和 _road

    // 道路长度

    // 地图数据

改为

    // 道路长度
    public roadLength: number = 50;
    // 地图数据
    private _road: BlockType[] = [];

20.8 生成地图

    // 生成地图的方法

改为

    // 生成地图的方法
    generateRoad() {
    
    
        // 清理上次的结果
        this.node.removeAllChildren();

        this._road = [];
        // startPos 开始位置必须是方块
        this._road.push(BlockType.BT_STONE);

        // 随机的方法生成地图
        for (let i = 1; i < this.roadLength; i++) {
    
    
            if (this._road[i - 1] === BlockType.BT_NONE) {
    
    
                this._road.push(BlockType.BT_STONE);
            } else {
    
    
                this._road.push(Math.floor(Math.random() * 2));
            }
        }

        let linkedBlocks = 0;
        for (let j = 0; j < this._road.length; j++) {
    
    
            if (this._road[j]) {
    
    
                ++linkedBlocks;
            }
            if (this._road[j] == 0) {
    
    
                if (linkedBlocks > 0) {
    
    
                    this.spawnBlockByCount(j - 1, linkedBlocks);
                    linkedBlocks = 0;
                }
            }
            if (this._road.length == j + 1) {
    
    
                if (linkedBlocks > 0) {
    
    
                    this.spawnBlockByCount(j, linkedBlocks);
                    linkedBlocks = 0;
                }
            }
        }
    }

20.9 在 start 中调用 generateRoad 创建地图

    // 组件第一次激活时调用的方法
    start() {
    
    }

改为

    // 组件第一次激活时调用的方法
    start() {
    
    
        this.generateRoad();
    }

20.10 运行

运行游戏,生成了浮岛
在这里插入图片描述

21、相机跟随玩家

层级管理器,将CameraCanvas层级下拖拽到玩家层级下
运行游戏,相机跟随玩家

22、提前规划摄相机的显示内容,避免后续的双摄相机重叠显示同一物体

  1. 层级管理器,选中Canvas
    属性检查器,将Layer改为DEFAULT,显示如图的提示
    在这里插入图片描述
    点击连同修改子节点
    Ctrl+S 保存

  2. 资源管理器,预制体,双击浮岛
    属性检查器,将Layer改为DEFAULT
    Ctrl+S 保存,Ctrl+Q退出编辑预制体模式

  3. 层级管理器,Canvas - 玩家 - Camera,选中Camera
    属性检查器,取消勾选VisibilityUI_2D,保持勾选VisibilityDEFAULT

23、游戏菜单

层级管理器,右键顶级层级游戏
创建,UI 组件,Canvas(画布)
将其命名为UICanvas

右键UICanvas,创建,空节点,将其命名为开始菜单

右键UICanvas,创建,2D对象,Label(文本),将其命名为步数
Position属性改为-440280
清空String属性


右键开始菜单,创建,2D对象,Sprite(精灵),将其命名为背景
Content Size属性改为400250
Sprite Frame属性由default_sprite改为default_panel
Type属性由SIMPLE改为SLICED

右键开始菜单,创建,UI 组件,Button(按钮),将其命名为开始菜单按钮
开始菜单按钮Position属性改为0-80
展开开始菜单按钮,将LabelString属性改为开始游戏


右键开始菜单,创建,2D对象,Label(文本),将其命名为开始菜单标题
Position属性改为080
Color属性改为#000000
String属性改为跳跳乐 2D
Font Size属性改为40

右键开始菜单,创建,2D对象,Label(文本),将其命名为开始菜单提示
Position属性改为040
Color属性改为#000000
String属性改为操作:左键小跳,右键大跳

24、修改UICanvas的Camera可见的层

层级管理器,UICancas下,选中Camera
属性检查器,取消勾选VisibilityDEFAULT,保持勾选VisibilityUI_2D

UICanvas默认层就是UI_2D,不用修改

25、游戏状态

25.1 返回去修改 PlayerController

25.1.1 修改start PlayerController

    // 组件第一次激活时调用的方法
    start() {
    
    
        input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);
    }

改为

    // 组件第一次激活时调用的方法
    start() {
    
    
        // input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);
    }

25.1.2 修改setInputActive PlayerController

    // 激活后关闭鼠标监听的方法
    // 激活后关闭鼠标监听的方法
    setInputActive(active: boolean) {
    
    
        if (active) {
    
    
            input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);
        } else {
    
    
            input.off(Input.EventType.MOUSE_UP, this.onMouseUp, this);
        }
    }

25.1.3 添加reset PlayerController

    // 重置方法

改为

    // 重置方法
    reset() {
    
    }

25.2 添加枚举 GameManager

// enum 枚举2

改为

// enum 枚举2
enum GameState {
    
    
    GS_INIT,
    GS_PLAYING,
    GS_END,
}

25.3 添加属性 GameManager

    // 属性2

改为

    // 属性2
    @property({
    
     type: Node })
    public startMenu: Node | null = null; // 开始的 UI
    @property({
    
     type: PlayerController })
    public playerCtrl: PlayerController | null = null; // 角色控制器
    @property({
    
     type: Label })
    public stepsLabel: Label | null = null; // 计步器

25.4 添加init GameManager

    // 初始化的方法

改为

    // 初始化的方法
    init() {
    
    
        if (this.startMenu) {
    
    
            this.startMenu.active = true;
        }

        this.generateRoad();

        if (this.playerCtrl) {
    
    
            this.playerCtrl.setInputActive(false);
            this.playerCtrl.node.setPosition(Vec3.ZERO);
            this.playerCtrl.reset();
        }
    }

25.5 添加curState GameManager

    // 控制游戏状态的读取器

改为

    // 控制游戏状态的读取器
    set curState(value: GameState) {
    
    
        switch (value) {
    
    
            case GameState.GS_INIT:
                this.init();
                break;
            case GameState.GS_PLAYING:
                if (this.startMenu) {
    
    
                    this.startMenu.active = false;
                }

                if (this.stepsLabel) {
    
    
                    this.stepsLabel.string = "0"; // 将步数重置为0
                }

                setTimeout(() => {
    
    
                    //直接设置active会直接开始监听鼠标事件,做了一下延迟处理
                    if (this.playerCtrl) {
    
    
                        this.playerCtrl.setInputActive(true);
                    }
                }, 0.1);
                break;
            case GameState.GS_END:
                break;
        }
    }

25.6 修改游戏管理层级的属性

回到Cocos Creator编辑器
修改游戏管理层级的属性
开始菜单拖拽到Start Menu
玩家拖拽到Player Ctrl
步数拖拽到Steps Label
Ctrl+S保存

26、绑定按钮事件

    // 响应 开始游戏 按钮按下的事件

改为

    // 响应 开始游戏 按钮按下的事件
    onStartButtonClicked() {
    
    
        this.curState = GameState.GS_PLAYING;
    }

保存

回到Cocos Creator编辑器
修改开始菜单按钮的属性
Click Events(在cc.Button分类下),将0设置为1
游戏管理层级拖拽到第[0]项上,旁边选择GameManageronStartButtonClicked

运行游戏,正常运行
发现玩家踩在坑上没有反应,添加踩坑失败的游戏逻辑

27、监听跳跃结束 修改PlayerController.ts

1.添加属性

    // private 私有属性2

改为

    // private 私有属性2
    private _curMoveIndex: number = 0;



2.修改重置

    // 重置方法
    reset() {
    
    }

改为

    // 重置方法
    reset() {
    
    
        this._curMoveIndex = 0;
    }



3.添加jumpByStep中的// 增加步数

        // 增加步数

改为

        // 增加步数
        this._curMoveIndex += step;



4.监听跳跃结束

    // 监听跳跃结束的方法

改为

    // 监听跳跃结束的方法
    onOnceJumpEnd() {
    
    
        this.node.emit('JumpEnd', this._curMoveIndex);
    }



5.在update中调用监听跳跃结束

                // 调用监听跳跃结束的方法

改为

                // 调用监听跳跃结束的方法
                this.onOnceJumpEnd();

28、监听跳跃结束 修改GameManager.ts

1.添加一个空的onPlayerJumpEnd

    // 更新计步器的显示并判断"跳坑失败或游戏完成"

改为

    // 更新计步器的显示并判断"跳坑失败或游戏完成"
    onPlayerJumpEnd(moveIndex: number) {
    
    }

2.start

    // 组件第一次激活时调用的方法
    start() {
    
    
        this.generateRoad();
    }

改为

    // 组件第一次激活时调用的方法
    start() {
    
    
        this.curState = GameState.GS_INIT;
        this.playerCtrl?.node.on("JumpEnd", this.onPlayerJumpEnd, this);
    }

3.checkResult

    // 判断跳坑失败或游戏完成的方法

改为

    // 判断跳坑失败或游戏完成的方法
    checkResult(moveIndex: number) {
    
    
        if (moveIndex < this.roadLength) {
    
    
            if (this._road[moveIndex] == BlockType.BT_NONE) {
    
    
                //跳到了空方块上
                this.curState = GameState.GS_INIT;
            }
        } else {
    
    
            // 跳过了最大长度
            this.curState = GameState.GS_INIT;
        }
    }

4.填充onPlayerJumpEnd

    // 更新计步器的显示并判断"跳坑失败或游戏完成"
    onPlayerJumpEnd(moveIndex: number) {
    
    }

改为

    // 更新计步器的显示并判断"跳坑失败或游戏完成"
    onPlayerJumpEnd(moveIndex: number) {
    
    
        if (this.stepsLabel) {
    
    
            this.stepsLabel.string =
                "" +
                (moveIndex >= this.roadLength ? this.roadLength : moveIndex);
        }
        this.checkResult(moveIndex);
    }

29、基本成品

官方教程就教到这里
1.通关
请添加图片描述
2.直接失败
请添加图片描述

其他

Cocos Creator3相比Cocos Creator2缺少控件库,在层级窗口右键创建即可



请添加图片描述

猜你喜欢

转载自blog.csdn.net/qq_39124701/article/details/129936289