495 lines
22 KiB
Markdown
495 lines
22 KiB
Markdown
# Complete Points/Lives Flow Diagram
|
||
|
||
## 🔴 INITIALIZATION PHASE
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ GAME STARTS │
|
||
│ PageLoading initializes │
|
||
└──────────────┬──────────────────────┘
|
||
│
|
||
↓
|
||
┌──────────────────────────┐
|
||
│ Check localStorage │
|
||
│ "game_lives" key │
|
||
└────┬──────────────┬──────┘
|
||
│ │
|
||
NOT SET EXISTS
|
||
(New User) (Returning)
|
||
│ │
|
||
↓ ↓
|
||
┌────────────┐ ┌────────────┐
|
||
│ 10 Lives │ │Parse Value │
|
||
│(DEFAULT) │ │from Storage│
|
||
└────┬───────┘ └────┬───────┘
|
||
│ │
|
||
└────────┬───────┘
|
||
↓
|
||
┌────────────────────────┐
|
||
│ LOAD LEVEL DATA │
|
||
│ (API fetch) │
|
||
│ https://ilookai.cn ... │
|
||
└────────┬───────────────┘
|
||
│
|
||
↓
|
||
┌────────────────────────┐
|
||
│ Display PageHome │
|
||
│ (with shared config) │
|
||
└────────┬───────────────┘
|
||
│
|
||
↓
|
||
┌────────────────────────┐
|
||
│ READY TO PLAY │
|
||
│ Lives: X | Level: Y │
|
||
└────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 🎮 GAMEPLAY PHASE (Single Level)
|
||
|
||
```
|
||
┌────────────────────────────────────────┐
|
||
│ LEVEL STARTS │
|
||
│ Load level data from cache │
|
||
│ Display image + Clue 1 (FREE) │
|
||
│ Start 60-second countdown │
|
||
└──────────────┬─────────────────────────┘
|
||
│
|
||
├─────────────────────────────────────┐
|
||
│ │
|
||
↓ ↓
|
||
┌──────────────────┐ ┌──────────────────────┐
|
||
│ UNLOCK CLUE 2 │ │ SUBMIT ANSWER │
|
||
│ onUnlockClue(2) │ │ onSubmitAnswer() │
|
||
│ │ │ │
|
||
│ Check: hasLives()├──NO──→ │ Compare: │
|
||
│ │ │ │ input === │
|
||
│ YES │ │ correctAnswer │
|
||
│ │ │ │ │
|
||
│ ↓ │ │ ├──YES──→┐ │
|
||
│ consumeLife() │ │ │ │ │
|
||
│ Lives: -1 │ │ │ │ │
|
||
│ │ │ │ │ │ │
|
||
│ ↓ │ │ │ ┌┴─────────┐
|
||
│ Display Clue 2 │ │ │ │ │
|
||
│ Refresh Label │ │ │ ↓ │
|
||
│ │ │ │ │ SUCCESS! │
|
||
│ ↓ │ │ │ showSuccess() │
|
||
│ Continue Game │ │ │ │ │
|
||
└──────────────────┘ │ │ ↓ │
|
||
│ │ │ Play success │
|
||
│ │ │ sound │
|
||
↓ │ │ Stop timer │
|
||
┌──────────────────┐ │ │ addLife() │
|
||
│ UNLOCK CLUE 3 │ │ │ Lives: +1 │
|
||
│ onUnlockClue(3) │ │ │ │ │
|
||
│ │ │ │ ↓ │
|
||
│ Check: hasLives()├──NO──→ │ │ Show PassModal │
|
||
│ │ │ │ │ │ │
|
||
│ YES │ │ │ ├─►[NEXT] │
|
||
│ │ │ │ │ │ │
|
||
│ ↓ │ │ │ └─►[SHARE] │
|
||
│ consumeLife() │ │ │ │
|
||
│ Lives: -1 │ │ └──NO──────────────┘
|
||
│ │ │ │ │
|
||
│ ↓ │ │ ↓
|
||
│ Display Clue 3 │ │ ERROR!
|
||
│ Refresh Label │ │ showError()
|
||
│ │ │ │ │
|
||
│ ↓ │ │ ↓
|
||
│ Continue Game │ │ Play fail sound
|
||
│ │ │ Vibrate long
|
||
│ │ │ Show toast:
|
||
│ │ │ "答案错误,
|
||
└──────────────────┘ │ 再试试吧!"
|
||
│ │ Lives unchanged
|
||
│ │ │
|
||
│ │ ↓
|
||
│ │ Can retry
|
||
│ │ (same level)
|
||
│ │
|
||
└──────────────────────┘
|
||
│
|
||
↓
|
||
┌──────────────────────┐
|
||
│ TIME UP? │
|
||
└──────────────────────┘
|
||
│
|
||
↓
|
||
┌─────────────────────┐
|
||
│ Play fail sound │
|
||
│ Stop countdown │
|
||
│ Can still retry │
|
||
│ Lives unchanged │
|
||
└─────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 LIVES TRANSACTION FLOW
|
||
|
||
```
|
||
LEVEL START
|
||
│
|
||
┌────────┴─────────┐
|
||
│ │
|
||
OPTIONAL MANDATORY
|
||
(Hints) (Level)
|
||
│ │
|
||
┌───────┴────────┐ │
|
||
│ │ │
|
||
HINT 2 HINT 3 SUBMISSION
|
||
-1 Life -1 Life │
|
||
│ │ │
|
||
└────────┬───────┴─┬───────┤
|
||
│ │ │
|
||
(Spent) (Spent) ANSWER
|
||
│ │ │
|
||
└────┬────┴───┬───┘
|
||
│ │
|
||
0-2 LIVES SPENT
|
||
(Depends on choices)
|
||
│ │
|
||
┌─────────┼────────┼─────────┐
|
||
│ │ │ │
|
||
CORRECT WRONG TIMEOUT ...
|
||
│ │ │
|
||
│ │ │
|
||
+1 LIFE 0 LIVES 0 LIVES
|
||
│ │ │
|
||
↓ ↓ ↓
|
||
┌───────────────────────────────┐
|
||
│ NEW LIVES BALANCE │
|
||
│ │
|
||
│ Formula: │
|
||
│ newLives = │
|
||
│ oldLives │
|
||
│ - (hintsUnlocked × 1) │
|
||
│ + (if levelWon ? 1 : 0) │
|
||
│ │
|
||
│ Examples: │
|
||
│ 10 - 0 + 1 = 11 (no hints) │
|
||
│ 10 - 1 + 1 = 10 (1 hint) │
|
||
│ 10 - 2 + 1 = 9 (2 hints) │
|
||
│ 10 - 0 + 0 = 10 (retry) │
|
||
└───────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 🏆 LEVEL PROGRESSION & PERSISTENCE
|
||
|
||
```
|
||
LEVEL WON
|
||
│
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ StorageManager. │
|
||
│ onLevelCompleted() │
|
||
│ │
|
||
│ Takes: levelIndex (0-based) │
|
||
└────────────┬────────────────┘
|
||
│
|
||
┌────────┴────────┐
|
||
│ │
|
||
↓ ↓
|
||
┌────────────┐ ┌──────────────────┐
|
||
│ currentLevel │ maxUnlocked │
|
||
│ = N + 1 │ = max(N, current)│
|
||
└────────────┘ └──────────────────┘
|
||
│ │
|
||
└────────┬────────┘
|
||
│
|
||
↓
|
||
┌──────────────────────────────┐
|
||
│ Save to localStorage: │
|
||
│ "game_progress" = │
|
||
│ { │
|
||
│ currentLevelIndex: N+1, │
|
||
│ maxUnlockedLevelIndex: N │
|
||
│ } │
|
||
└────────┬─────────────────────┘
|
||
│
|
||
↓
|
||
┌──────────────────────────────┐
|
||
│ NEXT GAME SESSION: │
|
||
│ Restore from localStorage │
|
||
│ Resume at Level N+1 │
|
||
│ Can replay Levels 0 to N │
|
||
└──────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 💾 DATA PERSISTENCE
|
||
|
||
```
|
||
┌─────────────────────────────────────────┐
|
||
│ localStorage (Browser) │
|
||
├─────────────────────────────────────────┤
|
||
│ │
|
||
│ KEY: "game_lives" │
|
||
│ VALUE: "10" (string number) │
|
||
│ Type: String │
|
||
│ Managed by: StorageManager │
|
||
│ Accessed by: PageLevel, PassModal │
|
||
│ │
|
||
├─────────────────────────────────────────┤
|
||
│ │
|
||
│ KEY: "game_progress" │
|
||
│ VALUE: JSON string │
|
||
│ { │
|
||
│ "currentLevelIndex": 2, │
|
||
│ "maxUnlockedLevelIndex": 4 │
|
||
│ } │
|
||
│ Type: String (JSON) │
|
||
│ Managed by: StorageManager │
|
||
│ Accessed by: PageLevel, ViewManager │
|
||
│ │
|
||
└─────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 🌐 API & LEVEL DATA FLOW
|
||
|
||
```
|
||
┌──────────────────────────────────────────┐
|
||
│ Remote API Server │
|
||
│ https://ilookai.cn/api/v1/... │
|
||
│ │
|
||
│ Returns: Array<ApiLevelData> │
|
||
│ Fields: id, level, imageUrl, hint1-3, │
|
||
│ answer, sortOrder │
|
||
└────────────────┬──────────────────────────┘
|
||
│
|
||
↓ (1st app load only)
|
||
HttpUtil.get()
|
||
│
|
||
↓
|
||
┌──────────────────────────┐
|
||
│ LevelDataManager │
|
||
│ _fetchApiData() │
|
||
│ │
|
||
│ Retry: 2 attempts │
|
||
│ Timeout: 8000ms │
|
||
└────────┬─────────────────┘
|
||
│
|
||
┌────┴────┐
|
||
│ │
|
||
FAIL SUCCESS
|
||
│ │
|
||
│ ↓
|
||
│ ┌──────────────────┐
|
||
│ │ Cache all level │
|
||
│ │ metadata in │
|
||
│ │ memory │
|
||
│ │ (_apiData) │
|
||
│ └────┬─────────────┘
|
||
│ │
|
||
│ ↓
|
||
│ ┌──────────────────┐
|
||
│ │ Preload Level 0 │
|
||
│ │ image │
|
||
│ │ (_levelConfigs) │
|
||
│ └────┬─────────────┘
|
||
│ │
|
||
└────┬────┘
|
||
│
|
||
↓
|
||
┌──────────────────────────┐
|
||
│ PageLevel ready │
|
||
│ Display first level │
|
||
└──────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## ⏰ COUNTDOWN TIMER FLOW
|
||
|
||
```
|
||
┌──────────────────┐
|
||
│ startCountdown() │
|
||
│ _countdown = 60 │
|
||
│ _isTimeUp = false│
|
||
└────────┬─────────┘
|
||
│
|
||
↓
|
||
┌─────────────────────────┐
|
||
│ schedule( │
|
||
│ onCountdownTick, 1 │ ← Every 1 second
|
||
│ ) │
|
||
└────────┬────────────────┘
|
||
│
|
||
├─────────────────────────────┐
|
||
│ EVERY SECOND │
|
||
│ (if _isTimeUp = false) │
|
||
│ │
|
||
├─→ _countdown-- │
|
||
├─→ updateClockLabel() │
|
||
│ (display "59s", "58s"...) │
|
||
│ │
|
||
└────────┬────────────────────┘
|
||
│
|
||
├─────────────────────────┐
|
||
│ │
|
||
_countdown > 0 _countdown <= 0
|
||
│ │
|
||
│ ↓
|
||
│ _isTimeUp = true
|
||
│ stopCountdown()
|
||
│ onTimeUp()
|
||
│ playFailSound()
|
||
│ │
|
||
│ ↓
|
||
│ Can still submit!
|
||
│ Lives unchanged
|
||
│ │
|
||
└──────────┬──────────────┘
|
||
│
|
||
↓
|
||
┌────────────────┐
|
||
│ PLAYER ACTION: │
|
||
│ Submit Answer │
|
||
└────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 📱 WECHAT INTEGRATION POINTS
|
||
|
||
```
|
||
┌──────────────────────────────────────┐
|
||
│ GAME START (PageHome) │
|
||
├──────────────────────────────────────┤
|
||
│ WxSDK.initShare({ │
|
||
│ title: "写英语", │
|
||
│ query: "" │
|
||
│ }) │
|
||
│ └─► Enable share menu in header │
|
||
└──────────────────────────────────────┘
|
||
|
||
┌──────────────────────────────────────┐
|
||
│ LEVEL WON (PassModal) │
|
||
├──────────────────────────────────────┤
|
||
│ User clicks "Share" │
|
||
│ WxSDK.shareAppMessage({ │
|
||
│ title: "快来一起玩...", │
|
||
│ query: "level=<levelIndex>" │
|
||
│ }) │
|
||
│ └─► Opens share dialog │
|
||
│ with level param │
|
||
└──────────────────────────────────────┘
|
||
|
||
┌──────────────────────────────────────┐
|
||
│ WRONG ANSWER (PageLevel) │
|
||
├──────────────────────────────────────┤
|
||
│ showError() │
|
||
│ WxSDK.vibrateLong() │
|
||
│ └─► 400ms vibration feedback │
|
||
└──────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 Complete Player Journey
|
||
|
||
```
|
||
START
|
||
↓
|
||
┌─────────────────────┐
|
||
│ Check localStorage │
|
||
│ game_lives: 10 │
|
||
│ game_progress: {0,0}│
|
||
└──────────┬──────────┘
|
||
↓
|
||
┌─────────────────┐
|
||
│ PageHome │
|
||
│ Start Button │
|
||
└──────────┬──────┘
|
||
↓
|
||
┌──────────────────────────┐
|
||
│ PageLevel: LEVEL 1 │
|
||
│ Lives: 10 │ Answer: __ │
|
||
│ Clue 1: ✓ (FREE) │
|
||
│ Clue 2: Unlock? (-1 life)│
|
||
│ Clue 3: Unlock? (-1 life)│
|
||
│ ⏱️ 60s countdown... │
|
||
└──────────┬───────────────┘
|
||
│
|
||
┌──────┴──────┬────────────────┐
|
||
│ │ │
|
||
UNLOCK SUBMIT TIMEOUT
|
||
CLUE 2 ANSWER (still ok)
|
||
-1 Life │
|
||
│ ├─ CORRECT: +1 Life
|
||
│ │ ↓
|
||
│ │ PassModal
|
||
│ │ ├─ NEXT → Level 2
|
||
│ │ └─ SHARE → wx.share
|
||
│ │
|
||
│ └─ WRONG: Lives stay
|
||
│ ↓
|
||
│ Retry same level
|
||
│
|
||
└─ UNLOCK
|
||
CLUE 3
|
||
-1 Life
|
||
│
|
||
↓
|
||
(Try answer)
|
||
│
|
||
├─ CORRECT: +1 Life
|
||
│ ↓
|
||
│ PassModal
|
||
│ └─ NEXT → Level 2
|
||
│
|
||
└─ WRONG: Lives stay
|
||
↓
|
||
Retry
|
||
|
||
PROGRESSION CONTINUES...
|
||
|
||
BEAT ALL LEVELS
|
||
↓
|
||
Return to PageHome
|
||
(Save progress in localStorage)
|
||
↓
|
||
COMPLETE
|
||
```
|
||
|
||
---
|
||
|
||
## 📈 Lives Over Time (Example Scenario)
|
||
|
||
```
|
||
Session 1: No hints used
|
||
━━━━━━━━━━━━━━━━━━━━━
|
||
Level 1: 10 Lives → Correct → 11 Lives
|
||
Level 2: 11 Lives → Correct → 12 Lives
|
||
Level 3: 12 Lives → Correct → 13 Lives
|
||
Session 1 ends: 13 Lives saved
|
||
|
||
Session 2: Some hints used
|
||
━━━━━━━━━━━━━━━━━━━━━
|
||
Start: 13 Lives
|
||
Level 4: 13 - 1 (hint) + 1 (win) = 13 Lives
|
||
Level 5: 13 - 2 (hints) + 1 (win) = 12 Lives
|
||
Level 6: 12 - 0 (no hints) + 1 (win) = 13 Lives
|
||
Level 7: 13 - 0 (no hints) + 1 (win) = 14 Lives
|
||
Session 2 ends: 14 Lives saved
|
||
|
||
Session 3: Struggling with hints
|
||
━━━━━━━━━━━━━━━━━━━━━
|
||
Start: 14 Lives
|
||
Level 8: 14 - 2 (hints) + 1 (win) = 13 Lives
|
||
Level 9: 13 - 2 (hints) + 1 (win) = 12 Lives
|
||
Level 10: 12 - 0 (retry, no hints) + 1 (eventually win) = 13 Lives
|
||
Session 3 ends: 13 Lives saved
|
||
|
||
PATTERN: Lives stay stable or grow over time
|
||
depending on hint usage
|
||
```
|
||
|