Skip to content

启动页 ​

启动页在入口场景的资源加载期间显示,比如 logo 加进度条。它就是一个实现了 LoadingScreen 的普通 Scene,通过启动参数 loading 传入。

ts
import { ColorRect, Scene, Sprite2D, tex, v, type LoadingScreen } from 'sapling2d'

/** 启动页:logo + 进度条,至少显示 1 秒。资源放在 public/assets/boot/(微信小游戏里留在主包)。 */
export class Splash extends Scene implements LoadingScreen {
  static override assets = { logo: tex('boot/logo.png') }
  fill!: ColorRect

  override ready() {
    this.add(new Sprite2D({ texture: Splash.assets.logo, position: v(375, 560) }))
    const track = this.add(new ColorRect({ position: v(175, 760), size: v(400, 12), color: 0x333333 }))
    this.fill = track.add(new ColorRect({ size: v(400, 12), color: 0xffcc33 }))
  }

  override process() {
    this.fill.scale = v(this.tree.assets.progress, 1) // 0..1,微信上包括下载资源分包
  }

  // 可选:资源都加载完后调用,返回的 Promise 完成后才切到入口场景
  async loaded() {
    await this.tree.createTimer(1).timeout
  }
}

export class Menu extends Scene {
  static override assets = { bg: tex('bg.png') }
}

// main.ts:startGame({ main: Menu, loading: Splash })

启动流程 ​

  1. 加载启动页自己的 static assets
  2. 启动页进入场景树,开始帧循环
  3. 准备资源包:微信小游戏在这一步下载资源分包,占进度的前 70%
  4. 加载入口场景的资源
  5. 如果启动页有 loaded(),等它返回的 Promise 完成
  6. 切到入口场景;启动页被销毁,它独有的资源被卸载

要点 ​

  • 启动页的资源要少:它们在任何画面出现之前加载。
  • 在微信小游戏里,启动页的资源必须放在 public/assets/boot/(主包),否则启动时报错。见 微信小游戏。
  • 不传 loading 时用内置的 DefaultLoadingScene:屏幕中间一条进度条,不用资源;loading: null 不显示启动页。
  • tree.assets.progress 在每次 changeScene 期间也会从 0 走到 1。

测试 ​

ts
// 测试里启动页直接被跳过(不经过帧,不等 loaded());测启动页本身就把它当作 main
const g = await createTestGame({ main: Menu, loading: Splash })
expect(g.scene).toBeInstanceOf(Menu)
const splash = await createTestGame({ main: Splash })
splash.step()
expect(splash.scene.fill.scale.x).toBe(1) // 没在加载时 assets.progress 是 1

MIT 许可证