Files
mp-xieyingeng/QUICK_REFERENCE.md
richarjiang 69c0986996 feat: 进入关卡时 toast 提示体力消耗,修复 StorageManager 接口位置和 WxSDK 访问级别
- 进入关卡成功后显示 toast 提示消耗体力及剩余体力
- 将 StorageManager 中 UserInfo 接口移至模块顶层,修复嵌套接口语法问题
- WxSDK.getWx() 改为 static 公开方法,便于外部调用
2026-04-10 10:10:19 +08:00

8.6 KiB

UI Components - Quick Reference Guide

Component Overview

Component Purpose Extends Key Responsibilities
main.ts App bootstrap Component Register pages, init ViewManager & ToastManager
PageLoading.ts Splash screen Component Load data, sync progress, detect share code
PageHome.ts Landing page BaseView Navigation hub (game/PK buttons)
PageLevel.ts Game level BaseView Core gameplay (timer, hints, scoring, input)
PagePreviewLevels.ts Level preview BaseView Scrollable list of selected levels
PassModal.ts Completion modal BaseView Next level & share buttons, success sound
Toast.ts Notification Component Display message with fade animation
ToastManager.ts Toast system Singleton Centralized toast creation & display
BaseView.ts Page base class Component Lifecycle interface for all pages
ViewManager.ts Page manager Singleton Navigation, stacking, caching, lifecycle

Lifecycle Stages

Page Lifecycle (BaseView)

onViewLoad()  → onViewShow()  → onViewHide()  → onViewDestroy()
 (once)        (each show)      (each hide)      (on destroy)

App Startup Flow

main.onLoad()
  ↓ (Initialize ViewManager + register pages)
PageLoading.start()
  ↓ (Load auth + levels in parallel, check share code)
PageHome (normal) OR PageLevel (share mode)

Key Data Flows

Level Progression

PageLevel loads config → Displays image + clue1 → User enters answer
    ↓ (correct) → Earn points → Show PassModal → Next level
    ↓ (wrong) → Show toast → Continue playing
    ↓ (timeout) → Play fail sound

Hint Unlocking

User clicks unlock button → Check points available
    ↓ (yes) → Consume point from UserAssetsManager
    ↓ → Hide unlock button, show clue
    ↓ (no) → Show "insufficient points" toast

Share Challenge Mode

WeChat link → PageLoading detects share code
    ↓ → ShareManager.joinShare(code)
    ↓ → Play through shared levels (doesn't save local progress)
    ↓ → Report progress to server
    ↓ → Return to PageHome

Component Properties Summary

PageLevel (Most Complex)

UI Elements:

  • inputLayout, submitButton, inputTemplate, actionNode
  • iconSetting (back button)
  • tipsLayout, tipsItem1/2/3 (clues)
  • unLockItem2/3 (unlock buttons)
  • clockLabel (timer), liveLabel (points)
  • mainImage (level image)

Audio:

  • clickAudio, successAudio, failAudio

Internal State:

  • _countdown (60 sec timer)
  • _isTimeUp (timer expired flag)
  • _currentConfig (level data)
  • _isTransitioning (prevent double-submit)
  • _isUnlocking (prevent double-click unlock)
  • _passModalNode (modal reference)
  • _isShareMode (shared vs normal)

Key Methods:

  • onViewLoad/Show/Hide/Destroy (lifecycle)
  • initLevel() (async load config)
  • createSingleInput(length) (input box)
  • onUnlockClue(index) (consume points for hints)
  • onSubmitAnswer() (check answer)
  • showSuccess() (correct: earn points, show modal)
  • showError() (wrong: toast + vibration)
  • nextLevel() (progress to next)
  • startCountdown() / onCountdownTick() (60s timer)

Points & Scoring System

Earning Points:

  • UserAssetsManager.earnPoint(levelId, timeSpent)
  • Called in PageLevel.showSuccess()
  • Time spent = 60 - countdown

Consuming Points:

  • UserAssetsManager.consumePoint(levelId, hintIndex)
  • Called in PageLevel.onUnlockClue()
  • Check StorageManager.hasPoints() before consuming

Displaying Points:

  • StorageManager.getPoints() → Display as "x {points}"
  • Called in PageLevel.updatePointsLabel()

Timer System

60-Second Countdown:

  • Starts when level loads: startCountdown()
  • Ticks every 1 second: onCountdownTick()
  • Displayed as: "60s", "59s", ..., "0s"
  • On timeout: plays fail sound, doesn't end game

Stop Timer:

  • stopCountdown() called when:
    • Answer submitted (correct)
    • Page destroyed
    • All levels completed

Hint/Clue System

3 Clues Per Level:

  1. Clue 1 - Always visible (free)
  2. Clue 2 - Unlock button, costs points
  3. Clue 3 - Unlock button, costs points

Display:

  • Text in tipsItem1/2/3 nodes
  • Hidden if locked (tipsItem.active = false)
  • Unlock button visible if locked

Unlock Flow:

  1. User clicks unLockItem2 or unLockItem3
  2. Check points: StorageManager.hasPoints()
  3. Consume: UserAssetsManager.consumePoint(levelId, index)
  4. Hide button, show clue, update UI

Navigation Stack

Structure:

  • LIFO stack managed by ViewManager
  • Each open() adds to stack
  • back() pops from stack
  • replace() swaps top

Example Session:

[PageHome]
    ↓ open PageLevel
[PageHome, PageLevel]
    ↓ open PassModal (or inline)
[PageHome, PageLevel, PassModal?]
    ↓ close/back
[PageHome]

Methods:

  • ViewManager.open(viewId, options?) - Push to stack
  • ViewManager.back() - Pop from stack, show previous
  • ViewManager.replace(viewId, options?) - Pop current, push new

Caching Strategy

Cached Views (default):

  • Instance reused on re-open
  • onViewLoad() called once
  • onViewShow() called each time
  • Memory persists

Non-Cached Views:

  • New instance each time
  • onViewLoad() called each time
  • Memory released on close

Configuration:

// In main.ts registration
ViewManager.instance.register('PageHome', {
  prefab: pageHomePrefab,
  cache: true,    // ← Reuse instance
  zIndex: 0       // ← Layer depth
});

Toast System

Show Toast:

ToastManager.show("消息内容", 2000);  // duration in ms

Initialization (main.ts):

ToastManager.instance.init(toastPrefab, canvasNode);

Toast Behavior:

  • Creates Toast instance from prefab
  • Displays for duration (default 2000ms)
  • Fades out over 300ms
  • Auto-destroys

WeChat Integration

Share Initialization (PageHome):

WxSDK.initShare({
  title: '写英语',
  imageUrl: '',
  query: ''
});

Share in Challenge (PassModal):

WxSDK.shareAppMessage({
  title: '快来一起玩这款游戏吧',
  query: `level={levelIndex}`
});

Share Code Detection (PageLoading):

const shareCode = WxSDK.getShareCodeFromLaunch();
if (shareCode) {
  const joined = await ShareManager.instance.joinShare(shareCode);
  // Launch PageLevel in share mode
}

Other WeChat Features:

  • WxSDK.vibrateLong() - Haptic feedback on wrong answer
  • WxSDK.isWechat() - Check if running in WeChat
  • checkPrivacySetting() - Check privacy authorization
  • requirePrivacyAuthorize() - Prompt for privacy consent

Error Handling & Edge Cases

Level Loading:

  • Try cache first, then async load
  • Preload next level without blocking
  • Handle missing config gracefully

Point Consumption:

  • Check availability before consuming
  • Show toast if insufficient
  • Prevent double-click with flag

Answer Submission:

  • Prevent multiple submissions with transition flag
  • Trim whitespace from answer
  • Case-sensitive comparison

Page Navigation:

  • Share mode: clears share state before returning home
  • Normal mode: simple back() navigation
  • Modal: stays on top (z-index 999)

Common Tasks

Add Toast

ToastManager.show('提示信息');

Navigate to Page

ViewManager.instance.open('PageLevel');  // Push
ViewManager.instance.back();             // Pop
ViewManager.instance.replace('PageHome');// Swap

Get Current Level

const index = StorageManager.getCurrentLevelIndex();

Check/Consume Points

if (StorageManager.hasPoints()) {
  await UserAssetsManager.consumePoint(levelId, hintIndex);
}

Start Game

// From PageHome
ViewManager.instance.open('PageLevel');

Create & Share Challenge

// User flow:
PageHome  [PK Button]  PageWriteLevels [Select 6]
   PagePreviewLevels [Verify]
   PassModal [Share Button]
   WxSDK.shareAppMessage()

File Size & Complexity

File Lines Complexity
main.ts 92 Simple (init only)
PageLoading.ts 141 Medium (parallel loading, sync)
PageHome.ts 119 Simple (two buttons)
PageLevel.ts 823 Very High (core game logic)
PagePreviewLevels.ts 247 Medium (scroll list)
PassModal.ts 155 Simple (two buttons)
Toast.ts 50 Simple (fade animation)
ToastManager.ts 59 Simple (factory pattern)
BaseView.ts 132 Medium (lifecycle)
ViewManager.ts 320 High (stack navigation)

Total: ~2,138 lines | Focal Point: PageLevel.ts (38% of code)