feat: 支持登录、个人信息存储
This commit is contained in:
416
SUMMARY.md
Normal file
416
SUMMARY.md
Normal file
@@ -0,0 +1,416 @@
|
||||
# Game System Summary - Points/Score/Lives Analysis
|
||||
|
||||
**Project:** Cocos Creator WeChat Mini-Game ("写英语" - Write English)
|
||||
**Date Analyzed:** April 5, 2026
|
||||
**Analysis Scope:** Complete TypeScript codebase (21 source files)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This game uses a **LIVES-based economy** rather than traditional points/coins:
|
||||
|
||||
- **Currency:** Lives (renewable resource)
|
||||
- **Starting Value:** 10 lives per new player
|
||||
- **Earning Mechanic:** +1 life per completed level
|
||||
- **Spending Mechanic:** -1 life per hint unlock (optional, 2 hints available)
|
||||
- **Net Effect:** Players naturally gain lives if they solve without hints, stay stable with 1 hint/level, or lose lives if using both hints
|
||||
|
||||
The system is **fully persistent** (saved to localStorage) and **progression-aware** (can replay earlier levels while advancing).
|
||||
|
||||
---
|
||||
|
||||
## Files Analyzed (21 total)
|
||||
|
||||
### Core Game Logic (4 files)
|
||||
1. **PageLevel.ts** (786 lines) - Main gameplay, hint system, answer validation
|
||||
2. **LevelDataManager.ts** (312 lines) - API calls, level caching, image loading
|
||||
3. **StorageManager.ts** (240 lines) - Lives & progress persistence
|
||||
4. **PageLoading.ts** (88 lines) - App initialization, preloading
|
||||
|
||||
### UI/Navigation (3 files)
|
||||
5. **ViewManager.ts** (320 lines) - Page stack management
|
||||
6. **BaseView.ts** (132 lines) - View lifecycle
|
||||
7. **PassModal.ts** (155 lines) - Victory screen with rewards
|
||||
|
||||
### Utilities (5 files)
|
||||
8. **ToastManager.ts** (59 lines) - Toast notifications
|
||||
9. **WxSDK.ts** (188 lines) - WeChat API wrapper
|
||||
10. **HttpUtil.ts** (76 lines) - HTTP requests
|
||||
11. **Toast.ts** (50 lines) - Toast display component
|
||||
12. **LevelTypes.ts** (59 lines) - TypeScript interfaces
|
||||
|
||||
### Prefabs & Entry Points (3 files)
|
||||
13. **PageHome.ts** (78 lines) - Home page
|
||||
14. **main.ts** (59 lines) - App entry point
|
||||
15. Plus UI utilities (BackgroundScaler, RoundedRectMask)
|
||||
|
||||
---
|
||||
|
||||
## The Complete Points/Lives Flow
|
||||
|
||||
### 🟢 EARNING Lives
|
||||
| Event | Amount | Condition |
|
||||
|-------|--------|-----------|
|
||||
| Correct Answer | +1 | Submitted answer matches API answer exactly (case-sensitive, trimmed) |
|
||||
| New Game | +10 | First time players only (default) |
|
||||
| **Cannot Earn** | 0 | Wrong answers, timeouts, hint unlocks, returning players don't reset |
|
||||
|
||||
### 🔴 SPENDING Lives
|
||||
| Event | Amount | Condition |
|
||||
|--------|--------|-----------|
|
||||
| Unlock Hint 2 | -1 | Player clicks unlock, must have lives > 0 |
|
||||
| Unlock Hint 3 | -1 | Player clicks unlock, must have lives > 0 |
|
||||
| No Other Costs | - | No penalties for wrong answers or timeouts |
|
||||
|
||||
### 📊 Net Economy Per Level
|
||||
```
|
||||
Best Case (No Hints): +1 life/level → Infinite scaling
|
||||
Average Case (1 Hint): 0 lives/level → Stable indefinitely
|
||||
Hard Case (2 Hints): -1 life/level → Runs out after 10-20 levels
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Persistence
|
||||
|
||||
### localStorage Keys
|
||||
```javascript
|
||||
{
|
||||
"game_lives": "10", // Current lives count
|
||||
"game_progress": "{ // Player progression
|
||||
\"currentLevelIndex\": 0,
|
||||
\"maxUnlockedLevelIndex\": 0
|
||||
}"
|
||||
}
|
||||
```
|
||||
|
||||
### Lifespan
|
||||
- **Initial:** Set when first loading game
|
||||
- **Updates:** Every level completion or hint unlock
|
||||
- **Persistence:** Survives app close/reopen (native browser storage)
|
||||
- **Manual Reset:** Available via `StorageManager.resetAll()`
|
||||
|
||||
---
|
||||
|
||||
## Level Progression System
|
||||
|
||||
### Mechanics
|
||||
1. **Level 1 Always Unlocked** - New players start here
|
||||
2. **Sequential Unlocking** - Beat level N to unlock level N+1
|
||||
3. **Non-Linear Progress** - Can replay earlier levels anytime
|
||||
4. **Max Tracking** - Tracks highest level reached for achievements
|
||||
|
||||
### Data Structure
|
||||
```typescript
|
||||
{
|
||||
currentLevelIndex: number, // Which level to play next (0-based)
|
||||
maxUnlockedLevelIndex: number // Highest level player has beaten
|
||||
}
|
||||
```
|
||||
|
||||
### Example Progression
|
||||
```
|
||||
User beats Level 3 (index 2)
|
||||
↓
|
||||
currentLevelIndex → 2+1 = 3 (level 4)
|
||||
maxUnlockedLevelIndex → max(2, previous) = 2
|
||||
↓
|
||||
Can now play levels 0-3
|
||||
Must complete level 3 to unlock level 4
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hint System
|
||||
|
||||
### Mechanics
|
||||
- **Hint 1:** Always visible, completely free
|
||||
- **Hint 2:** Hidden by default, costs 1 life to unlock
|
||||
- **Hint 3:** Hidden by default, costs 1 life to unlock
|
||||
|
||||
### Implementation
|
||||
```typescript
|
||||
onUnlockClue(index: 2|3) {
|
||||
if (!hasLives()) return; // Must have >= 1 life
|
||||
consumeLife(); // Deduct 1 life
|
||||
showClue(index); // Reveal the clue content
|
||||
}
|
||||
```
|
||||
|
||||
### Strategic Element
|
||||
Players must decide if they want to spend lives for hints or solve blindly to accumulate more lives for future levels.
|
||||
|
||||
---
|
||||
|
||||
## Gameplay Loop
|
||||
|
||||
### Per-Level Sequence
|
||||
1. Load level image from API cache
|
||||
2. Display Hint 1 (free) + two "Unlock" buttons
|
||||
3. Start 60-second countdown
|
||||
4. Player can:
|
||||
- Unlock hints by spending lives (optional, repeatable)
|
||||
- Type their answer in single text box
|
||||
- Submit answer
|
||||
5. Outcome:
|
||||
- **Correct:** Reward +1 life, show victory modal
|
||||
- **Wrong:** No penalty, show error toast, can retry
|
||||
- **Timeout:** Play fail sound, can still submit
|
||||
|
||||
### Victory Rewards
|
||||
```
|
||||
onSubmitAnswer(userAnswer) {
|
||||
if (userAnswer.trim() === correctAnswer) {
|
||||
playSuccessSound();
|
||||
addLife(); // +1 life
|
||||
StorageManager.onLevelCompleted(currentLevel);
|
||||
showPassModal(); // Next/Share buttons
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Integration
|
||||
|
||||
### Endpoint
|
||||
```
|
||||
GET https://ilookai.cn/api/v1/wechat-game/levels
|
||||
```
|
||||
|
||||
### Response Format
|
||||
```typescript
|
||||
{
|
||||
success: boolean,
|
||||
message: string | null,
|
||||
data: {
|
||||
levels: [
|
||||
{
|
||||
id: "uuid",
|
||||
level: 1,
|
||||
imageUrl: "https://...",
|
||||
hint1: "Free clue",
|
||||
hint2: "Paid clue",
|
||||
hint3: "Paid clue",
|
||||
answer: "CORRECT_ANSWER",
|
||||
sortOrder: 1
|
||||
},
|
||||
// ... more levels
|
||||
],
|
||||
total: number
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Reliability Features
|
||||
- **Retry Logic:** 2 attempts on failure
|
||||
- **Timeout:** 8 seconds per request
|
||||
- **Fallback:** Shows error message if all retries fail
|
||||
- **Caching:** All levels cached in memory after first load
|
||||
|
||||
---
|
||||
|
||||
## WeChat Integration
|
||||
|
||||
### Features Implemented
|
||||
1. **Sharing** - Share game to friends with level parameter
|
||||
2. **Vibration** - Haptic feedback on errors
|
||||
3. **Platform Detection** - Gracefully degrade on non-WeChat platforms
|
||||
|
||||
### Share Implementation
|
||||
```typescript
|
||||
// On victory, user can click "Share"
|
||||
WxSDK.shareAppMessage({
|
||||
title: "快来一起玩这款游戏吧",
|
||||
query: `level=${victoryLevelIndex}`
|
||||
});
|
||||
// Opens WeChat share dialog with referral link
|
||||
```
|
||||
|
||||
### Not Implemented
|
||||
- ❌ User authentication (wx.login)
|
||||
- ❌ Backend progress sync
|
||||
- ❌ Analytics
|
||||
- ❌ Ads/Monetization
|
||||
- ❌ Leaderboards
|
||||
|
||||
---
|
||||
|
||||
## User Journey Example
|
||||
|
||||
```
|
||||
New User Opens Game
|
||||
↓
|
||||
[Initialize: 10 lives, Level 1]
|
||||
↓
|
||||
Attempt Level 1
|
||||
├─ Unlocks Hint 2 (-1 life) → 9 lives
|
||||
├─ Unlocks Hint 3 (-1 life) → 8 lives
|
||||
├─ Submits Answer
|
||||
│
|
||||
├─ CORRECT
|
||||
│ ├─ Awards +1 life → 9 lives
|
||||
│ ├─ Saves progress (level → 2)
|
||||
│ └─ Shows PassModal
|
||||
│ ├─ Can click "Next Level" → Level 2
|
||||
│ └─ Can click "Share" → wx.share
|
||||
│
|
||||
└─ WRONG
|
||||
├─ No penalty → 9 lives unchanged
|
||||
├─ Shows error toast
|
||||
└─ Can retry immediately
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Loading & Initialization
|
||||
|
||||
### On App Start
|
||||
1. **Detect New vs. Returning User**
|
||||
- Check localStorage "game_lives" key
|
||||
- New: Initialize to 10
|
||||
- Returning: Restore value
|
||||
|
||||
2. **Load Level Metadata**
|
||||
- API call to fetch all levels
|
||||
- Retry up to 2 times on failure
|
||||
- Cache all level data in memory
|
||||
|
||||
3. **Preload First Level**
|
||||
- Download image for level 1
|
||||
- Cache in memory for instant display
|
||||
|
||||
4. **Show Home Screen**
|
||||
- Display "Start Game" button
|
||||
- Initialize WeChat sharing
|
||||
|
||||
### On Subsequent Game Sessions
|
||||
1. Restore lives from localStorage
|
||||
2. Restore progress from localStorage
|
||||
3. Resume at saved level
|
||||
4. API already cached (no refetch unless app restarted)
|
||||
|
||||
---
|
||||
|
||||
## Key Constants
|
||||
|
||||
| Constant | Value | Usage |
|
||||
|----------|-------|-------|
|
||||
| DEFAULT_LIVES | 10 | New player starting amount |
|
||||
| MIN_LIVES | 0 | Cannot go negative |
|
||||
| LEVEL_TIME_LIMIT | 60 seconds | Countdown timer |
|
||||
| API_TIMEOUT | 8000ms | HTTP request timeout |
|
||||
| API_RETRY_COUNT | 2 | Attempts on failure |
|
||||
| HINT_COST | 1 life each | Unlock clue 2 or 3 |
|
||||
| WIN_REWARD | 1 life | Completion bonus |
|
||||
| MODAL_Z_INDEX | 999 | Victory modal layer |
|
||||
|
||||
---
|
||||
|
||||
## Business Logic Highlights
|
||||
|
||||
### Win Condition
|
||||
```typescript
|
||||
userAnswer.trim() === correctAnswer
|
||||
```
|
||||
- Case-sensitive
|
||||
- Whitespace trimmed
|
||||
- Must match exactly
|
||||
|
||||
### No Lose Condition
|
||||
- Wrong answers: No penalty
|
||||
- Time up: No penalty
|
||||
- Can retry infinitely on same level
|
||||
|
||||
### Safety Checks
|
||||
- Can't unlock hints if lives ≤ 0
|
||||
- Can't go below 0 lives
|
||||
- Can't exceed total levels
|
||||
- Invalid data resets to defaults
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimizations
|
||||
|
||||
1. **Image Caching** - Downloaded images cached in memory
|
||||
2. **Level Metadata Caching** - API data cached to avoid re-fetching
|
||||
3. **Progress Caching** - localStorage data cached to reduce reads
|
||||
4. **Async Preloading** - Next level preloaded silently
|
||||
5. **Efficient UI** - Single EditBox (not per-character)
|
||||
6. **Lazy Loading** - Pages cached after first load
|
||||
|
||||
---
|
||||
|
||||
## Missing Features / Gaps
|
||||
|
||||
| Feature | Status | Impact |
|
||||
|---------|--------|--------|
|
||||
| User Authentication | ❌ | No way to sync across devices |
|
||||
| Backend Progress Save | ❌ | Progress lost if localStorage clears |
|
||||
| Monetization | ❌ | No revenue stream |
|
||||
| Ads | ❌ | No ad integration |
|
||||
| Analytics | ❌ | Can't track player behavior |
|
||||
| Leaderboards | ❌ | No competition mechanics |
|
||||
| Sound Toggle | ❌ | Always plays sounds |
|
||||
| Difficulty Levels | ❌ | All players see same levels |
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
### Test Case 1: Lives Economy
|
||||
```
|
||||
1. New game → 10 lives
|
||||
2. Beat level without hints → 11 lives
|
||||
3. Beat level with 1 hint → 11 lives (net 0)
|
||||
4. Beat level with 2 hints → 10 lives (net -1)
|
||||
→ Verify localStorage updated after each
|
||||
```
|
||||
|
||||
### Test Case 2: Progression
|
||||
```
|
||||
1. Complete level 1
|
||||
2. Verify currentLevel → 2
|
||||
3. Verify maxUnlocked → 1
|
||||
4. Restart app
|
||||
5. Verify levels still saved
|
||||
6. Replay level 1
|
||||
7. Verify no duplicate progress
|
||||
```
|
||||
|
||||
### Test Case 3: Hint Cost
|
||||
```
|
||||
1. Start with 10 lives
|
||||
2. Unlock hint 2 → 9 lives displayed
|
||||
3. Unlock hint 3 → 8 lives displayed
|
||||
4. Can't unlock again (button inactive)
|
||||
5. Wrong answer → 8 lives still
|
||||
6. Correct answer → 9 lives (net -1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
This is a **well-architected mini-game** with:
|
||||
- ✅ Clear lives-based economy
|
||||
- ✅ Persistent progress tracking
|
||||
- ✅ Strategic hint system
|
||||
- ✅ Reliable API integration
|
||||
- ✅ Good error handling
|
||||
- ✅ WeChat platform integration
|
||||
|
||||
The point system is **intentionally forgiving** - players who solve puzzles smartly gain lives indefinitely, while those using hints maintain stability. This encourages skill development without hard progress walls.
|
||||
|
||||
---
|
||||
|
||||
## Documentation Files Generated
|
||||
|
||||
1. **GAME_ANALYSIS.md** - Comprehensive 17-section analysis (13KB)
|
||||
2. **QUICK_REFERENCE.md** - Quick lookup guide (5.6KB)
|
||||
3. **POINTS_FLOW_DIAGRAM.md** - Visual flow diagrams (15KB)
|
||||
4. **SUMMARY.md** - This executive summary (8KB)
|
||||
|
||||
**Total:** 42KB of detailed documentation covering every aspect of the points/score/lives system.
|
||||
|
||||
Reference in New Issue
Block a user