本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本文围绕一个已发布在4399游戏平台的H5小游戏项目,深入剖析其源码结构与开发技术栈。项目采用Egret框架和TypeScript语言开发,结合HTML5与JavaScript实现浏览器端小游戏运行。文章详细讲解了项目中的关键文件,如配置文件、资源目录、编译输出目录、主入口HTML等内容,帮助开发者理解整个H5游戏的开发、构建与发布流程。通过本源码学习,可掌握Egret框架的项目结构设计与资源管理机制,为H5小游戏开发打下坚实基础。
H5小游戏源码分享

1. H5小游戏开发概述

H5小游戏是以 HTML5 技术为核心,运行在浏览器中的轻量级游戏形式,凭借其跨平台、无需下载安装、即点即玩的特性,迅速在移动端和社交平台中占据一席之地。随着移动互联网的发展,H5小游戏已成为小游戏生态中不可或缺的一部分。

从应用场景来看,H5小游戏广泛应用于社交分享、广告推广、节日活动、品牌营销等多个领域。其开发周期短、部署灵活、传播便捷,使得中小团队和个人开发者也能快速进入市场。

2. Egret框架介绍与使用

Egret 是一款专为 HTML5 游戏开发设计的开源引擎,基于 TypeScript 构建,具备良好的跨平台兼容性和高效的 2D 渲染能力。其模块化架构和丰富的功能组件,使其成为开发 H5 小游戏的理想选择。本章将深入探讨 Egret 引擎的核心组件、开发环境搭建方法、小游戏示例开发流程,并分析其在不同游戏平台中的适用性与优势。

2.1 Egret 引擎的核心组件

Egret 引擎由多个核心模块组成,这些模块共同支撑了引擎的基础架构和运行机制。理解这些组件有助于开发者更好地掌握引擎的底层原理,并在实际开发中灵活运用。

2.1.1 Egret Runtime 与 egret-core

Egret Runtime 是运行时环境,负责将 Egret 应用程序运行在目标平台上。它提供了一套统一的 API 接口,屏蔽了不同平台(如浏览器、微信小游戏、OPPO 小游戏等)之间的差异,使开发者无需关注底层平台细节。

egret-core 是 Egret 引擎的核心库,包含基础类、事件系统、显示对象管理、资源加载等核心功能。其模块化设计使得开发者可以按需引入功能,从而优化项目体积和性能。

以下是一个使用 egret-core 创建基础显示对象的示例代码:

class GameApp {
    public constructor() {
        // 初始化舞台
        egret.runEgret({ renderMode: "webgl", fpsLabel: null, showPaintRect: false });
        // 添加主显示对象
        this.init();
    }

    private init(): void {
        let stage = egret.stage;
        stage.scaleMode = egret.StageScaleMode.FIXED_WIDTH;

        let textField = new egret.TextField();
        textField.text = "Hello Egret!";
        textField.size = 24;
        textField.textColor = 0xFF0000;
        textField.x = 100;
        textField.y = 100;
        stage.addChild(textField);
    }
}

new GameApp();

逐行解析:

  1. egret.runEgret({...}) :启动 Egret 引擎,设置渲染模式为 WebGL,并关闭帧率显示。
  2. egret.stage :获取舞台对象,它是显示对象的根容器。
  3. stage.scaleMode = egret.StageScaleMode.FIXED_WIDTH :设置舞台的缩放模式为固定宽度。
  4. TextField :创建一个文本对象,设置其内容、字体大小、颜色和位置。
  5. stage.addChild(textField) :将文本对象添加到舞台上,使其可见。

参数说明:

  • renderMode : 渲染模式,支持 canvas 和 webgl。
  • fpsLabel : 是否显示帧率信息。
  • showPaintRect : 是否显示绘制区域,用于调试。

2.1.2 Egret Display List 与渲染机制

Egret 使用 Display List(显示列表)机制管理所有可视元素。所有可视对象都必须继承自 DisplayObject ,并添加到显示列表中才能被渲染。

Egret 的显示列表结构类似于树形结构,其中 Stage 是根节点, DisplayObjectContainer 是容器节点,可以包含多个子节点。渲染过程由舞台开始,递归遍历所有子节点,进行绘制。

以下是一个展示显示列表层级结构的流程图:

graph TD
    A[Stage] --> B[DisplayObjectContainer]
    B --> C[Sprite]
    B --> D[Bitmap]
    C --> E[TextField]
    D --> F[MovieClip]

逻辑分析:

  • Stage 是整个显示列表的根节点。
  • DisplayObjectContainer 是容器类,用于组织多个显示对象。
  • Sprite 是轻量级容器,常用于组织图形元素。
  • Bitmap 表示图像资源。
  • TextField 表示文本内容。
  • MovieClip 用于播放帧动画。

渲染机制特点:

  • 层级管理 :通过 addChild/removeChild 方法控制显示对象的层级。
  • 坐标系统 :每个显示对象具有 x/y 坐标,相对于其父容器。
  • 自动更新 :每次帧刷新时,会自动重新渲染整个显示列表。
  • 性能优化 :隐藏或移除不必要的对象可提升渲染效率。

2.2 Egret 开发环境搭建

搭建一个稳定、高效的开发环境是进行 Egret 开发的第一步。Egret 提供了专用的 IDE —— Egret Wing,同时也支持命令行工具(CLI)进行项目管理。

2.2.1 安装 Egret Wing IDE

Egret Wing 是 Egret 官方提供的集成开发环境,集成了项目创建、代码编辑、调试、资源管理等功能。

安装步骤:

  1. 访问 Egret 官网 下载 Egret Wing。
  2. 解压安装包并运行安装程序。
  3. 安装完成后,启动 Egret Wing,登录 Egret 账号(可选)。

IDE 功能特点:

  • 支持 TypeScript 语法高亮与自动补全。
  • 集成资源管理器,支持拖拽导入图片、音频等资源。
  • 提供项目模板,快速创建 Egret 项目。
  • 内置调试器,支持断点调试、变量查看等。

2.2.2 配置项目运行与调试环境

在 Egret Wing 中创建新项目后,需要配置运行和调试环境:

运行配置:

  1. 在项目属性中设置启动页面为 index.html
  2. 选择运行平台(如浏览器、微信小游戏等)。
  3. 点击“运行”按钮,Egret 会自动编译项目并在浏览器中打开。

调试配置:

  1. 在代码中设置断点(点击行号左侧)。
  2. 点击“调试”按钮启动调试模式。
  3. 使用控制台查看日志输出,使用“变量”窗口查看当前作用域变量。
  4. 支持逐步执行、跳过函数、进入函数等调试操作。

以下是一个简单的调试示例代码:

class DebugExample {
    private count: number = 0;

    public start(): void {
        this.count = this.increment(this.count); // 设置断点于此行
        console.log("Current count: " + this.count);
    }

    private increment(value: number): number {
        return value + 1;
    }
}

调试分析:

  • 设置断点后,程序会在 this.increment(this.count) 处暂停执行。
  • 可以查看 value 参数的值,并逐步执行函数内部逻辑。
  • 控制台输出 Current count: 1 ,验证函数逻辑是否正确。

2.3 基于 Egret 的小游戏示例开发

通过一个简单的小游戏示例,可以更直观地了解如何使用 Egret 进行项目开发。

2.3.1 创建第一个 Egret 项目

使用 Egret CLI 创建项目:

egret create myGame

该命令会创建一个名为 myGame 的 Egret 项目,包含基本的目录结构和入口文件。

项目结构如下:

myGame/
├── egretProperties.json
├── tsconfig.json
├── index.html
├── src/
│   └── Main.ts
└── resource/
    └── assets/
        └── icon.png

关键文件说明:

  • egretProperties.json :Egret 项目配置文件,定义编译目标和资源路径。
  • tsconfig.json :TypeScript 编译配置。
  • src/Main.ts :主程序入口。
  • resource/assets/ :资源目录,存放图片、音频等。

2.3.2 添加图形元素与交互逻辑

修改 Main.ts 文件,添加一个可点击的按钮:

class Main extends egret.DisplayObjectContainer {
    public constructor() {
        super();
        this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
    }

    private onAddToStage(event: egret.Event): void {
        let texture = RES.getRes("icon_png");
        let button = new egret.Bitmap(texture);
        button.x = 100;
        button.y = 100;
        button.touchEnabled = true;
        button.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onClick, this);
        this.addChild(button);
    }

    private onClick(event: egret.TouchEvent): void {
        console.log("Button clicked!");
    }
}

逻辑分析:

  • 使用 RES.getRes() 加载资源,前提是资源已添加到 resource.json
  • 设置 touchEnabled = true 启用触摸交互。
  • 添加 TOUCH_TAP 事件监听器,绑定 onClick 回调函数。
  • 点击按钮时,控制台输出日志。

参数说明:

  • ADDED_TO_STAGE : 当对象被添加到舞台时触发。
  • TOUCH_TAP : 触摸点击事件。
  • touchEnabled : 是否启用触摸交互,默认为 false。

2.4 Egret 引擎的优势与适用场景

Egret 相较于其他主流引擎(如 Unity、Cocos)在 H5 小游戏领域具有独特优势,尤其在跨平台适配方面表现优异。

2.4.1 与 Unity、Cocos 引擎的对比

特性 Egret Unity (WebGL) Cocos Creator
开发语言 TypeScript C# JavaScript / TypeScript
渲染性能 中等
跨平台支持 极佳(浏览器、微信等) 依赖 WebGL 支持微信、浏览器等
学习曲线
工具链集成 自带 Egret Wing IDE Unity Editor Cocos Creator IDE
社区活跃度

结论分析:

  • Egret 更适合 :需要快速上线、跨平台部署、对性能要求中等的小游戏。
  • Unity 更适合 :对性能要求极高、3D 游戏、复杂物理交互。
  • Cocos 更适合 :2D 游戏开发,尤其是中大型项目。

2.4.2 在小游戏平台的适配性分析

Egret 对主流小游戏平台(如微信小游戏、OPPO 小游戏、百度小游戏)有良好的适配支持。通过 Egret CLI 可一键发布到多个平台:

egret build myGame -t wechat

该命令将项目打包为微信小游戏格式,并生成相应的 game.js project.config.json 文件。

适配特点:

  • 微信小游戏 :支持 Canvas 和 WebGL 模式,兼容性良好。
  • OPPO 小游戏 :支持本地资源加载和平台 SDK 集成。
  • 百度小游戏 :支持热更新和广告接入。

表格:适配平台特性对比

平台 渲染模式支持 广告接入 热更新 资源加载
微信小游戏 Canvas/WebGL
OPPO 小游戏 Canvas
百度小游戏 Canvas

总结:

Egret 凭借其轻量级架构、跨平台能力和对 H5 小游戏生态的深度整合,成为开发者构建多端小游戏的首选引擎。下一章将深入探讨 TypeScript 在 H5 游戏开发中的应用,帮助开发者提升代码质量与维护效率。

3. TypeScript在H5游戏中的应用

TypeScript 是 H5 小游戏开发中不可或缺的语言工具,尤其在 Egret 引擎中,它不仅提供了 JavaScript 的全部功能,还引入了类型系统和面向对象编程的支持,使得代码更易于维护、扩展和调试。本章将从 TypeScript 的基础语法入手,逐步深入到其在 H5 游戏项目中的组织方式与编译配置,帮助开发者构建高质量的游戏逻辑结构。

3.1 TypeScript 基础语法与面向对象编程

TypeScript 最大的优势在于其对面向对象编程(OOP)的良好支持。通过类(class)和接口(interface)等结构,开发者可以更清晰地组织游戏逻辑,提升代码的可读性和复用性。

3.1.1 类与接口的定义

在 TypeScript 中, 用于定义对象的结构和行为,而 接口 则用于定义对象的契约(即形状),常用于参数类型检查和模块间通信。

示例代码:定义一个游戏角色类
// 定义角色接口
interface ICharacter {
    name: string;
    hp: number;
    attack(): void;
}

// 实现角色类
class Player implements ICharacter {
    name: string;
    hp: number;

    constructor(name: string, hp: number) {
        this.name = name;
        this.hp = hp;
    }

    attack(): void {
        console.log(`${this.name} 发动了攻击`);
    }
}

// 使用角色类
const hero = new Player("Hero", 100);
hero.attack();  // 输出:Hero 发动了攻击
代码逻辑分析:
  • interface ICharacter :定义了一个接口,要求实现它的类必须具有 name hp 属性和 attack() 方法。
  • class Player implements ICharacter :声明一个类并实现该接口,确保其结构符合定义。
  • 构造函数 constructor :用于初始化对象属性。
  • 方法 attack() :实现攻击行为,输出角色名称和动作。
参数说明:
参数 类型 说明
name string 角色的名称
hp number 角色的生命值
attack() void 攻击行为函数,无返回值

3.1.2 泛型与装饰器的使用

TypeScript 提供了泛型(Generics)和装饰器(Decorators)功能,极大地增强了代码的灵活性和可复用性。

示例代码:使用泛型定义通用数据容器
// 泛型类
class Container<T> {
    private items: T[] = [];

    add(item: T): void {
        this.items.push(item);
    }

    get(index: number): T {
        return this.items[index];
    }
}

// 使用泛型容器
const playerContainer = new Container<Player>();
playerContainer.add(new Player("Warrior", 80));
const warrior = playerContainer.get(0);
warrior.attack();  // 输出:Warrior 发动了攻击
代码逻辑分析:
  • class Container<T> :定义一个泛型类, T 表示任意类型。
  • add(item: T) :添加一个元素到容器中。
  • get(index: number): T :根据索引获取元素。
示例代码:使用装饰器记录方法执行日志
function LogMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = function (...args: any[]) {
        console.log(`调用方法: ${propertyKey},参数: ${JSON.stringify(args)}`);
        const result = originalMethod.apply(this, args);
        console.log(`方法 ${propertyKey} 执行完毕,返回值: ${result}`);
        return result;
    };

    return descriptor;
}

class GameService {
    @LogMethod
    startGame(playerName: string): string {
        return `${playerName} 开始了游戏`;
    }
}

const service = new GameService();
service.startGame("Alice");
输出结果:
调用方法: startGame,参数: ["Alice"]
方法 startGame 执行完毕,返回值: Alice 开始了游戏
装饰器机制说明:
  • 装饰器函数 LogMethod :在方法调用前后添加日志输出。
  • descriptor.value :重写原始方法,在调用前后插入日志。
  • apply 方法 :确保原始方法在正确的上下文中执行。

3.2 TypeScript 与 JavaScript 的兼容性

TypeScript 是 JavaScript 的超集,这意味着所有合法的 JavaScript 代码都是合法的 TypeScript 代码。这一特性使得开发者可以逐步迁移到 TypeScript,同时保留已有 JavaScript 代码。

3.2.1 类型推断与类型注解

TypeScript 的类型系统支持 类型推断 (Type Inference)和 类型注解 (Type Annotation),帮助开发者在编写代码时避免类型错误。

示例代码:类型推断
let count = 10;  // 类型推断为 number
count = "ten";  // 编译错误:不能将类型 "string" 分配给类型 "number"
示例代码:类型注解
let score: number = 90;
score = "high";  // 编译错误
类型注解的优势:
特性 说明
明确类型 使代码意图更清晰
避免错误 在编译时检测类型不匹配
提高可读性 易于他人理解和维护

3.2.2 模块化编程与命名空间管理

TypeScript 支持模块化编程,通过 import export 来组织代码结构,避免命名冲突。

示例代码:使用模块导出和导入
// gameModule.ts
export class Game {
    start() {
        console.log("游戏开始");
    }
}
// main.ts
import { Game } from "./gameModule";

const game = new Game();
game.start();  // 输出:游戏开始
使用命名空间防止冲突
namespace GameUtils {
    export function formatTime(seconds: number): string {
        return `${seconds}s`;
    }
}

console.log(GameUtils.formatTime(60));  // 输出:60s

3.3 在 Egret 项目中组织 TypeScript 代码

良好的代码组织结构对于大型 H5 小游戏项目至关重要。Egret 推荐使用模块化与类结构来管理游戏逻辑。

3.3.1 使用模块组织游戏逻辑

建议将游戏逻辑划分为多个模块,例如: PlayerModule SceneModule UIManager 等。

示例代码:组织模块结构
src/
├── modules/
│   ├── player/
│   │   └── Player.ts
│   ├── scene/
│   │   └── SceneManager.ts
│   └── ui/
│       └── UIManager.ts
└── main.ts
模块调用示例
// main.ts
import { Player } from "./modules/player/Player";
import { SceneManager } from "./modules/scene/SceneManager";

const player = new Player("Knight", 100);
SceneManager.loadScene("mainMenu");

3.3.2 管理游戏状态与场景切换

H5 游戏通常包含多个状态(如主菜单、战斗、设置等),可以通过状态机(State Machine)来管理。

使用枚举定义游戏状态
enum GameState {
    MainMenu,
    Playing,
    Paused,
    GameOver
}
实现状态切换逻辑
class GameManager {
    private currentState: GameState = GameState.MainMenu;

    changeState(newState: GameState): void {
        this.currentState = newState;
        this.onStateChanged();
    }

    private onStateChanged(): void {
        switch (this.currentState) {
            case GameState.MainMenu:
                console.log("进入主菜单");
                break;
            case GameState.Playing:
                console.log("开始游戏");
                break;
            case GameState.Paused:
                console.log("游戏暂停");
                break;
            case GameState.GameOver:
                console.log("游戏结束");
                break;
        }
    }
}

const gameManager = new GameManager();
gameManager.changeState(GameState.Playing);  // 输出:开始游戏
状态机流程图(Mermaid)
stateDiagram-v2
    [*] --> MainMenu
    MainMenu --> Playing : 开始游戏
    Playing --> Paused : 暂停
    Paused --> Playing : 恢复
    Playing --> GameOver : 游戏结束
    GameOver --> MainMenu : 返回主菜单

3.4 TypeScript 的编译配置与调试技巧

TypeScript 通过 tsconfig.json 文件进行编译配置,同时支持源码调试功能,提升开发效率。

3.4.1 使用 tsconfig.json 配置编译选项

tsconfig.json 是 TypeScript 项目的配置文件,控制编译器的行为。

示例 tsconfig.json 文件
{
    "compilerOptions": {
        "target": "ES2015",
        "module": "ESNext",
        "lib": ["DOM", "ES2015"],
        "outDir": "./bin",
        "rootDir": "./src",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "outFile": "./bin/game.js"
    },
    "include": ["src/**/*"]
}
配置说明:
配置项 说明
target ES2015 编译目标为 ES2015 版本
module ESNext 使用现代模块系统
lib DOM, ES2015 支持 DOM 操作和 ES2015 特性
outDir ./bin 编译输出目录
rootDir ./src 源码目录
strict true 启用严格类型检查
esModuleInterop true 支持 ES 模块互操作
skipLibCheck true 忽略库类型检查

3.4.2 浏览器调试与断点设置

TypeScript 支持生成 source map,使得在浏览器中可以直接调试源码。

调试流程:
  1. tsconfig.json 中启用 source map:
"sourceMap": true,
"outFile": "./bin/game.js"
  1. 编译 TypeScript 项目:
tsc
  1. 在浏览器中打开 index.html ,打开开发者工具(F12),在 Sources 面板中找到 .ts 源文件,设置断点。
断点调试示例:
function calculateScore(killCount: number): number {
    let score = 0;
    for (let i = 0; i < killCount; i++) {
        score += 10;  // 设置断点在此行
    }
    return score;
}

console.log(calculateScore(5));  // 应输出 50

小结(非总结性语句)

通过本章内容可以看出,TypeScript 为 H5 小游戏开发提供了强大的语言支持与开发工具链。从基础语法到高级特性,再到项目结构组织与调试配置,开发者可以借助 TypeScript 构建出结构清晰、维护性强、性能优越的游戏项目。下一章将深入解析 H5 小游戏中的核心配置文件,进一步提升项目管理能力。

4. H5小游戏核心配置文件解析

在H5小游戏开发中,合理配置和管理项目文件结构是确保项目可维护性、构建效率和运行性能的关键。Egret引擎通过多个核心配置文件对项目的结构、资源加载、编译流程和开发工具进行控制。深入理解这些配置文件,有助于开发者优化项目组织方式、提升调试效率,并在多平台部署中保持良好的兼容性。

本章将从四个核心配置文件入手: egretProperties.json tsconfig.json wingProperties.json README.md 。我们将逐个解析其结构与作用,展示实际配置示例,并结合代码片段与流程图说明其对项目构建和运行的影响。

4.1 egretProperties.json 配置详解

egretProperties.json 是 Egret 项目的核心配置文件之一,它定义了项目的编译目标、资源路径、运行时类型等关键参数。

4.1.1 runtimeType 与编译目标设定

runtimeType 指定了项目运行的目标环境。例如,设置为 "web" 表示游戏将运行在浏览器中,而设置为 "native" 则用于 Egret Native 打包的原生应用。

{
    "runtimeType": "web"
}
  • 参数说明
  • "web" :适用于浏览器环境,适用于H5小游戏。
  • "native" :适用于使用 Egret Native 构建的原生应用。
  • "miniGame" :用于微信小游戏等平台。

该配置影响后续构建命令的执行逻辑。例如,在构建微信小游戏时,Egret CLI 会根据此参数选择不同的打包流程。

4.1.2 资源路径与加载策略配置

资源路径通过 resourcePath 指定,Egret 默认使用 resource 文件夹作为资源目录。你也可以自定义路径,如:

{
    "resourcePath": "assets"
}

此外,资源加载策略通过 resourceLoadType 设置,支持以下几种模式:

加载策略 说明
"merge" 合并所有资源为一个文件,适合资源较少的小游戏
"version" 使用版本号控制资源缓存,适合资源更新频繁的项目
"default" 默认策略,资源按需加载
{
    "resourceLoadType": "version"
}

配置流程图

graph TD
    A[egretProperties.json] --> B{runtimeType}
    B -->|web| C[编译为H5项目]
    B -->|native| D[构建为原生应用]
    B -->|miniGame| E[适配微信小游戏平台]
    A --> F{resourceLoadType}
    F -->|merge| G[资源合并加载]
    F -->|version| H[带版本号缓存策略]
    F -->|default| I[按需加载资源]

4.2 tsconfig.json 编译配置说明

tsconfig.json 是 TypeScript 项目的标准配置文件,用于控制 TypeScript 编译器的行为。Egret 引擎默认使用该文件进行代码编译。

4.2.1 target、module 与 lib 的设置

这三个字段决定了编译后的 JavaScript 版本和模块格式。

{
    "compilerOptions": {
        "target": "ES5",
        "module": "ESNext",
        "lib": ["ES2017", "DOM"]
    }
}
  • target :指定编译目标版本。 ES5 保证兼容性较好,适合广泛浏览器支持。
  • module :指定模块打包方式。 ESNext 支持现代模块加载方式。
  • lib :定义 TypeScript 编译时引入的库类型。 DOM 支持浏览器API。

4.2.2 outDir 与 rootDir 的作用

  • outDir :指定编译输出目录,默认为 bin-debug
  • rootDir :指定 TypeScript 源代码目录,默认为 src

示例配置:

{
    "compilerOptions": {
        "outDir": "./bin-debug",
        "rootDir": "./src"
    }
}

这两个配置直接影响编译后的目录结构和资源组织方式。如果项目结构复杂,建议明确指定路径,避免编译混乱。

代码示例解析

// src/Main.ts
class Main extends egret.DisplayObjectContainer {
    public constructor() {
        super();
        this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
    }

    private onAddToStage(event: egret.Event): void {
        let label = new egret.TextField();
        label.text = "Hello, Egret!";
        label.x = 100;
        label.y = 100;
        this.addChild(label);
    }
}

该代码定义了一个基础的 Egret 场景,编译时将被转换为 JS 文件,并输出到 bin-debug 目录中。

4.3 wingProperties.json 与开发工具配置

wingProperties.json 是 Egret Wing IDE 的配置文件,用于控制开发工具的行为,如默认启动页面、插件配置等。

4.3.1 默认启动页面与调试设置

{
    "startPage": "index.html",
    "debugger": {
        "enabled": true,
        "port": 9999
    }
}
  • startPage :指定默认启动的 HTML 页面,通常是 index.html
  • debugger :启用调试模式,并设置调试端口。

该配置影响开发者在 IDE 中运行项目时的加载流程和调试方式。

4.3.2 项目构建参数与插件配置

Egret 插件如资源管理器、代码模板等可以通过 plugins 字段进行配置:

{
    "plugins": {
        "resourcemanager": {
            "enabled": true
        },
        "template": {
            "type": "game"
        }
    }
}
  • resourcemanager.enabled :是否启用资源管理插件。
  • template.type :项目模板类型, game 表示小游戏项目。

插件配置流程图

graph TD
    A[wingProperties.json] --> B[启动页面配置]
    B --> C[startPage=index.html]
    A --> D[调试器配置]
    D --> E[启用调试端口9999]
    A --> F[插件配置]
    F --> G[resourcemanager: 启用]
    F --> H[template: game]

4.4 README.md 项目说明文档规范

README.md 是项目根目录下的说明文档,用于描述项目结构、安装步骤、开发规范等内容,尤其在团队协作中至关重要。

4.4.1 项目结构说明与依赖安装指南

一个典型的 README 内容如下:

# My Egret Game

## 项目结构

- `src/`:TypeScript 源代码
- `resource/`:游戏资源文件
- `bin-debug/`:编译输出目录
- `index.html`:游戏入口页面

## 安装依赖

1. 安装 Egret CLI:`npm install -g egret`
2. 初始化项目:`egret init`
3. 安装资源插件:`egret install resourcemanager`

4.4.2 开发与部署流程文档编写规范

建议在 README 中加入开发流程说明:

## 开发流程

1. 编写 TypeScript 代码至 `src/`
2. 添加资源文件至 `resource/`
3. 使用 `egret run` 启动本地服务器调试
4. 使用 `egret build` 构建发布版本

## 部署流程

1. 发布到微信小游戏:
   - 安装微信开发者工具
   - 导出为小程序格式
   - 提交审核

2. 发布到 H5 平台:
   - 使用 `egret publish` 生成优化版本
   - 上传至游戏平台

总结

本章深入解析了 Egret 项目中四个关键配置文件的作用与配置方式:

  • egretProperties.json 控制项目运行环境和资源加载策略;
  • tsconfig.json 决定 TypeScript 编译行为;
  • wingProperties.json 管理 IDE 行为与插件;
  • README.md 提供项目结构说明与开发部署流程。

通过合理配置这些文件,开发者可以优化项目结构、提升构建效率,并在多平台部署中保持一致性。下一章我们将继续探讨 H5 小游戏的目录结构与资源管理机制,进一步提升项目组织能力。

5. H5小游戏目录结构与资源管理

良好的项目结构是 H5 小游戏长期维护与扩展的基础,同时资源管理机制直接影响游戏性能和加载效率。本章将围绕 H5 小游戏的典型目录结构展开,深入解析 src resource bin-debug index.html 等关键目录和文件的作用与配置方式,帮助开发者构建清晰、高效的项目结构。

5.1 src 目录结构与核心逻辑分析

src 是 H5 小游戏的核心代码目录,包含所有 TypeScript 编写的逻辑代码。其结构设计直接影响项目的可维护性、可扩展性以及团队协作效率。

5.1.1 核心类结构设计与模块划分

在 Egret 项目中, src 目录通常包含如下结构:

src/
├── Main.ts
├── modules/
│   ├── game/
│   │   ├── GameScene.ts
│   │   └── Player.ts
│   ├── ui/
│   │   ├── UIManager.ts
│   │   └── MenuView.ts
│   └── utils/
│       └── TimerUtils.ts
└── config/
    └── GameConfig.ts
  • Main.ts :程序入口文件,负责初始化游戏主舞台、加载资源并启动主场景。
  • modules/ :按功能模块划分的游戏逻辑,例如 game 模块负责核心游戏逻辑, ui 模块处理界面交互, utils 存放通用工具类。
  • config/ :游戏配置文件,如分辨率适配、关卡数据、资源路径等。

代码示例:GameScene.ts

class GameScene extends egret.DisplayObjectContainer {
    private player: Player;

    constructor() {
        super();
        this.init();
    }

    private init(): void {
        this.player = new Player();
        this.addChild(this.player);
    }
}

逐行解读:
1. class GameScene extends egret.DisplayObjectContainer :定义游戏主场景类,继承自 Egret 的容器类。
2. private player: Player; :声明一个 Player 类型的私有变量。
3. constructor() :构造函数,执行初始化逻辑。
4. init() :初始化方法,创建玩家对象并添加到场景中。

5.1.2 主程序入口与游戏初始化流程

主程序入口通常为 Main.ts 文件,负责启动整个游戏流程。

代码示例:Main.ts

class Main extends egret.DisplayObjectContainer {
    public constructor() {
        super();
        this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
    }

    private onAddToStage(event: egret.Event): void {
        this.removeEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);

        // 设置舞台尺寸
        this.stage.scaleMode = egret.StageScaleMode.FIXED_WIDTH;

        // 加载资源配置文件
        RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
        RES.loadConfig("resource/default.res.json", "resource/");
    }

    private onConfigComplete(event: RES.ResourceEvent): void {
        RES.removeEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);

        // 加载资源组
        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onGroupComplete, this);
        RES.loadGroup("preload");
    }

    private onGroupComplete(event: RES.ResourceEvent): void {
        if (event.groupName === "preload") {
            RES.removeEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onGroupComplete, this);

            // 启动主场景
            const gameScene = new GameScene();
            this.addChild(gameScene);
        }
    }
}

逻辑分析:
- onAddToStage :监听舞台加载完成事件,设置舞台缩放模式并加载资源配置。
- onConfigComplete :资源配置加载完成后,开始加载资源组。
- onGroupComplete :资源组加载完成后,创建并添加主场景。

5.2 resource 资源目录管理机制

资源目录 resource 是 H5 小游戏中存储所有静态资源的地方,包括图片、音频、字体、纹理集等。合理的资源管理能够提升加载效率,降低内存占用。

5.2.1 图片、音频与纹理集配置

资源目录结构通常如下:

resource/
├── assets/
│   ├── images/
│   ├── audios/
│   └── fonts/
├── config/
│   └── default.res.json
└── texture/
    └── atlas/
        └── main_atlas.json
  • assets/ :存放原始资源文件,如 PNG 图片、MP3 音频、TTF 字体等。
  • config/ :资源配置文件,定义资源组与加载策略。
  • texture/ :纹理集资源,用于优化图片加载与渲染性能。

图片资源加载示例:

let texture: egret.Texture = RES.getRes("bg_jpg");
let bitmap: egret.Bitmap = new egret.Bitmap(texture);
this.addChild(bitmap);

参数说明:
- "bg_jpg" :为资源配置中定义的资源 ID,通常在 default.res.json 中配置。

5.2.2 resource.json 资源加载清单解析

default.res.json 是资源配置的核心文件,用于定义资源组、路径与类型。

示例配置:

{
  "groups": [
    {
      "keys": "bg_jpg,btn_play_png,btn_exit_png",
      "name": "preload"
    }
  ],
  "resources": [
    {
      "type": "image",
      "url": "assets/images/bg.jpg",
      "name": "bg_jpg"
    },
    {
      "type": "image",
      "url": "assets/images/btn_play.png",
      "name": "btn_play_png"
    },
    {
      "type": "image",
      "url": "assets/images/btn_exit.png",
      "name": "btn_exit_png"
    }
  ]
}

参数说明:
- "groups" :资源组定义, preload 表示预加载资源组。
- "resources" :资源项列表,每个资源包含类型、URL 和唯一标识名。

流程图:

graph TD
    A[开始加载资源配置] --> B[读取 default.res.json]
    B --> C[解析资源组 preload]
    C --> D[加载资源组中的资源]
    D --> E[资源加载完成事件触发]
    E --> F[进入主游戏场景]

5.3 bin-debug 目录作用与编译流程

bin-debug 是 Egret 编译后的输出目录,主要用于调试和本地测试。该目录包含完整的 HTML5 项目结构,适合在浏览器中直接运行。

5.3.1 编译输出目录结构说明

编译后 bin-debug 目录结构如下:

bin-debug/
├── index.html
├── resource/
│   └── ...(资源文件)
├── egret/
│   └── egret.js
├── main.js
└── assets/
    └── ...(编译后的资源)
  • main.js :编译后的 JavaScript 入口文件。
  • egret/ :Egret 引擎的核心 JS 文件。
  • resource/ :资源文件复制目录,与 src 中的 resource 对应。

5.3.2 Debug 模式下的资源加载与性能分析

Debug 模式下,资源加载路径为原始资源,便于调试和查看资源加载过程。开发者可使用浏览器开发者工具(如 Chrome DevTools)分析加载性能。

浏览器调试技巧:
- 打开 DevTools → Network 面板,查看资源加载耗时。
- 使用 Performance 面板记录并分析帧率、CPU 占用情况。

5.4 index.html 主入口文件解析

index.html 是 H5 小游戏的主入口文件,负责初始化 HTML 页面并加载 Egret 引擎与游戏逻辑。

5.4.1 Canvas 与 DOM 元素初始化

标准 index.html 示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My Egret Game</title>
    <style>
        html, body { margin: 0; padding: 0; overflow: hidden; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="egret/egret.js"></script>
    <script src="egret/egret-game.js"></script>
    <script src="main.js"></script>
</body>
</html>

分析:
- <canvas> :Egret 渲染的目标容器。
- <script src="egret/egret.js"> :引入 Egret 引擎核心库。
- <script src="egret/egret-game.js"> :引入 Egret 游戏框架。
- <script src="main.js"> :游戏逻辑主入口。

5.4.2 加载进度条与错误提示处理

为了提升用户体验, index.html 可集成加载进度条与错误提示功能。

实现方式:

<div id="loading" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #000; color: #fff; text-align: center; padding-top: 200px;">
    Loading... <span id="progress">0%</span>
</div>

JavaScript 控制加载进度:

RES.addEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, () => {
    document.getElementById("loading").style.display = "none";
    alert("资源加载失败,请刷新重试!");
});

RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS, (e: RES.ResourceEvent) => {
    const percent = Math.floor(e.itemsLoaded / e.itemsTotal * 100);
    document.getElementById("progress").innerText = percent + "%";
});

表格:加载状态与处理方式

加载状态 事件类型 处理方式
资源加载失败 ITEM_LOAD_ERROR 显示错误提示
资源组加载进度 GROUP_PROGRESS 更新进度条
资源组加载完成 GROUP_COMPLETE 隐藏加载界面并启动游戏

通过本章内容的学习,读者应能掌握 H5 小游戏的目录结构设计、资源管理机制以及入口文件配置,从而为开发高性能、易维护的游戏项目打下坚实基础。

6. H5小游戏项目构建与发布实践

完成开发与调试后,构建和发布是将 H5 小游戏推向用户的关键步骤。本章将详细介绍从项目打包到多平台发布、性能优化的全流程,帮助开发者顺利完成上线部署。

6.1 项目打包流程详解

在完成 Egret 项目开发后,使用 Egret CLI 工具可以将项目打包为适用于不同平台的可发布版本。打包流程主要包含资源合并、代码压缩和平台适配等步骤。

6.1.1 使用 Egret CLI 进行项目构建

Egret 提供了命令行工具 egret build 来构建项目。以下是构建命令示例:

egret build myGameProject --runtime html5
  • myGameProject :项目目录名。
  • --runtime html5 :指定目标平台为 HTML5。

执行该命令后,Egret 会将 TypeScript 编译为 JavaScript,并将资源文件打包至 bin-release 目录下。

构建完成后,目录结构如下:

文件/目录 说明
index.html 游戏主入口页面
egret.js 引擎核心库
main.js 编译后的游戏主程序
resource/ 所有资源文件(图片、音频等)

6.1.2 多平台资源适配与优化

不同平台对资源格式、分辨率和加载方式有不同要求。例如,微信小游戏支持 canvas 和 WebGL 渲染模式,而 OPPO 小游戏则要求特定的 SDK 集成。

优化策略包括:
- 使用纹理集(Texture Atlas)减少加载请求;
- 图片使用 webp 格式以减小体积;
- 音频文件进行压缩(如使用 ogg 格式);
- 设置资源加载优先级(resource.json 中配置);

6.2 发布到微信小游戏平台

微信小游戏是 H5 小游戏的重要发布渠道之一。开发者需要使用微信开发者工具进行打包与调试。

6.2.1 微信小游戏开发工具配置

  1. 打开 微信开发者工具
  2. 创建新项目,选择“小游戏”模板;
  3. 将 Egret 构建后的 bin-release 文件夹内容复制到微信项目根目录;
  4. 修改 game.js 入口文件,确保引擎正确加载;
  5. 启动调试,查看控制台日志。

微信小游戏支持如下关键配置项:

配置项 说明
platform wechatgame 指定平台
customUpdate true 自定义资源加载逻辑
showFPS false 隐藏帧率显示

6.2.2 小程序包结构与审核注意事项

微信小游戏的包结构需符合以下规范:

  • game.js :游戏主程序;
  • engine/ :引擎库文件;
  • res/ :资源文件;
  • project.config.json :项目配置文件;

审核注意事项:
- 不得使用网络请求加载外部脚本;
- 图片、音频等资源需上传至平台审核;
- 不能包含敏感词汇或非法内容;
- 游戏启动后需在30秒内加载完成;

6.3 发布到其他 H5 游戏平台

除了微信平台,OPPO、百度等平台也提供了丰富的小游戏分发渠道。

6.3.1 OPPO、百度小游戏平台接入

OPPO 和百度小游戏平台通常基于 HTML5 技术,接入流程如下:

  1. 在平台开发者后台创建应用;
  2. 上传构建后的 bin-release 文件夹;
  3. 配置启动页面为 index.html
  4. 集成平台 SDK 实现登录、支付、广告等功能;
  5. 测试并提交审核。

不同平台的接入文档如下:

平台 接入文档链接
OPPO小游戏 OPPO小游戏开发者文档
百度小游戏 百度小游戏开发文档

6.3.2 平台 SDK 集成与广告接入

以百度小游戏为例,集成广告的代码如下:

if (window['swan']) {
    const bannerAd = swan.createBannerAd({
        adUnitId: '你的广告位ID',
        style: {
            top: 10,
            left: 0,
            width: 300
        }
    });
    bannerAd.show();
}

该代码检测是否在百度小游戏运行环境,若存在则创建并展示广告条。

6.4 H5 小游戏上线后的性能监控与优化

上线后,开发者应持续监控游戏性能,及时发现并解决卡顿、加载慢等问题。

6.4.1 使用 Chrome DevTools 分析性能瓶颈

Chrome DevTools 提供了丰富的性能分析功能。使用步骤如下:

  1. 打开游戏页面;
  2. F12 打开开发者工具;
  3. 切换到 Performance 标签;
  4. 点击 “Record” 开始录制,操作游戏后停止;
  5. 查看火焰图,分析主线程耗时函数。

关键性能指标包括:
- FPS:帧率应保持在 30 以上;
- Main Thread Time:主线程耗时不宜过高;
- Paint Flashing:减少不必要的重绘区域;

6.4.2 网络请求与资源加载优化策略

优化资源加载是提升用户体验的关键。以下是常用策略:

  • 合并资源 :使用 Texture Atlas 减少 HTTP 请求;
  • 预加载资源 :在游戏启动前加载关键资源;
  • 使用 CDN :将资源部署到 CDN 加速加载;
  • 延迟加载 :非核心资源在游戏运行时按需加载;
  • 缓存策略 :设置合适的缓存头,减少重复下载;

示例:使用 Egret 的资源加载器进行预加载:

RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, () => {
    RES.loadGroup("preload");
}, this);

RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, (e) => {
    if (e.groupName === "preload") {
        console.log("预加载完成");
    }
}, this);

RES.loadConfig("resource/resource.json", "resource/");

该代码在配置加载完成后,自动加载名为 preload 的资源组,确保关键资源在游戏开始前已就绪。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本文围绕一个已发布在4399游戏平台的H5小游戏项目,深入剖析其源码结构与开发技术栈。项目采用Egret框架和TypeScript语言开发,结合HTML5与JavaScript实现浏览器端小游戏运行。文章详细讲解了项目中的关键文件,如配置文件、资源目录、编译输出目录、主入口HTML等内容,帮助开发者理解整个H5游戏的开发、构建与发布流程。通过本源码学习,可掌握Egret框架的项目结构设计与资源管理机制,为H5小游戏开发打下坚实基础。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐