- 进入关卡成功后显示 toast 提示消耗体力及剩余体力 - 将 StorageManager 中 UserInfo 接口移至模块顶层,修复嵌套接口语法问题 - WxSDK.getWx() 改为 static 公开方法,便于外部调用
8.6 KiB
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:
- Clue 1 - Always visible (free)
- Clue 2 - Unlock button, costs points
- 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:
- User clicks unLockItem2 or unLockItem3
- Check points:
StorageManager.hasPoints() - Consume:
UserAssetsManager.consumePoint(levelId, index) - 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 stackViewManager.back()- Pop from stack, show previousViewManager.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 answerWxSDK.isWechat()- Check if running in WeChatcheckPrivacySetting()- Check privacy authorizationrequirePrivacyAuthorize()- 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)