Lashtw commited on
Commit
58b15a2
·
verified ·
1 Parent(s): e9fe3c1

Upload 42 files

Browse files
Files changed (2) hide show
  1. achievements.html +91 -0
  2. achievements.js +15 -2
achievements.html CHANGED
@@ -301,5 +301,96 @@
301
  </div>
302
 
303
  <script src="achievements.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  </body>
305
  </html>
 
301
  </div>
302
 
303
  <script src="achievements.js"></script>
304
+ <script>
305
+ // 等待成就系統載入完成後再顯示成就
306
+ document.addEventListener('DOMContentLoaded', function() {
307
+ // 等待成就系統初始化
308
+ const waitForAchievementSystem = () => {
309
+ if (window.achievementSystem && window.achievementSystem.achievements.length > 0) {
310
+ displayAchievements();
311
+ } else {
312
+ setTimeout(waitForAchievementSystem, 100);
313
+ }
314
+ };
315
+
316
+ setTimeout(waitForAchievementSystem, 500);
317
+ });
318
+
319
+ function displayAchievements() {
320
+ const achievementSystem = window.achievementSystem;
321
+ if (!achievementSystem) {
322
+ console.error('成就系統未載入');
323
+ return;
324
+ }
325
+
326
+ const achievementsContainer = document.getElementById('achievements-container');
327
+ if (!achievementsContainer) {
328
+ console.error('找不到成就容器');
329
+ return;
330
+ }
331
+
332
+ // 清空容器
333
+ achievementsContainer.innerHTML = '';
334
+
335
+ // 顯示成就
336
+ achievementSystem.achievements.forEach(achievement => {
337
+ const isUnlocked = achievementSystem.isAchievementUnlocked(achievement.id);
338
+ const achievementCard = createAchievementCard(achievement, isUnlocked);
339
+ achievementsContainer.appendChild(achievementCard);
340
+ });
341
+
342
+ // 更新統計
343
+ updateAchievementStats();
344
+ }
345
+
346
+ function createAchievementCard(achievement, isUnlocked) {
347
+ const card = document.createElement('div');
348
+ card.className = `achievement-card ${achievement.type || achievement.category} ${isUnlocked ? 'unlocked' : 'locked'}`;
349
+
350
+ const icon = getAchievementIcon(achievement.type || achievement.category);
351
+ const title = isUnlocked ? achievement.title : '???';
352
+ const description = isUnlocked ? achievement.description : '尚未解鎖';
353
+
354
+ card.innerHTML = `
355
+ <div class="achievement-icon">${icon}</div>
356
+ <div class="achievement-content">
357
+ <h3 class="achievement-title">${title}</h3>
358
+ <p class="achievement-description">${description}</p>
359
+ ${isUnlocked ? `<div class="achievement-date">解鎖時間:${formatDate(window.achievementSystem.userAchievements[achievement.id]?.unlockedAt)}</div>` : ''}
360
+ </div>
361
+ <div class="achievement-status">
362
+ ${isUnlocked ? '<span class="status-unlocked">✓</span>' : '<span class="status-locked">🔒</span>'}
363
+ </div>
364
+ `;
365
+
366
+ return card;
367
+ }
368
+
369
+ function getAchievementIcon(type) {
370
+ switch (type) {
371
+ case 'journey': return '🌟';
372
+ case 'trial': return '⚔️';
373
+ case 'secret': return '🔮';
374
+ default: return '🏆';
375
+ }
376
+ }
377
+
378
+ function formatDate(dateString) {
379
+ if (!dateString) return '未知';
380
+ const date = new Date(dateString);
381
+ return date.toLocaleDateString('zh-TW');
382
+ }
383
+
384
+ function updateAchievementStats() {
385
+ const achievementSystem = window.achievementSystem;
386
+ const unlockedCount = achievementSystem.getUnlockedCount();
387
+ const totalCount = achievementSystem.getTotalCount();
388
+
389
+ const statsElement = document.querySelector('.achievement-stats');
390
+ if (statsElement) {
391
+ statsElement.textContent = `已解鎖:${unlockedCount}/${totalCount}`;
392
+ }
393
+ }
394
+ </script>
395
  </body>
396
  </html>
achievements.js CHANGED
@@ -1,7 +1,7 @@
1
  // 成就系統類
2
  class AchievementSystem {
3
  constructor() {
4
- this.achievements = [];
5
  this.userAchievements = {};
6
  this.toastContainer = null;
7
  this.toastQueue = [];
@@ -21,13 +21,26 @@ class AchievementSystem {
21
  async loadAchievements() {
22
  try {
23
  const response = await fetch('achievements.json');
 
 
 
24
  const data = await response.json();
25
- this.achievements = data.achievements;
 
 
 
 
 
 
 
 
 
26
  console.log('成就資料載入成功:', this.achievements.length, '個成就');
27
  } catch (error) {
28
  console.error('載入成就資料失敗:', error);
29
  // 使用預設成就資料
30
  this.achievements = this.getDefaultAchievements();
 
31
  }
32
  }
33
 
 
1
  // 成就系統類
2
  class AchievementSystem {
3
  constructor() {
4
+ this.achievements = []; // 初始化為空陣列
5
  this.userAchievements = {};
6
  this.toastContainer = null;
7
  this.toastQueue = [];
 
21
  async loadAchievements() {
22
  try {
23
  const response = await fetch('achievements.json');
24
+ if (!response.ok) {
25
+ throw new Error(`HTTP error! status: ${response.status}`);
26
+ }
27
  const data = await response.json();
28
+
29
+ // achievements.json 直接是陣列格式,不是 {achievements: [...]}
30
+ if (Array.isArray(data)) {
31
+ this.achievements = data;
32
+ } else if (data.achievements && Array.isArray(data.achievements)) {
33
+ this.achievements = data.achievements;
34
+ } else {
35
+ throw new Error('成就資料格式不正確');
36
+ }
37
+
38
  console.log('成就資料載入成功:', this.achievements.length, '個成就');
39
  } catch (error) {
40
  console.error('載入成就資料失敗:', error);
41
  // 使用預設成就資料
42
  this.achievements = this.getDefaultAchievements();
43
+ console.log('使用預設成就資料:', this.achievements.length, '個成就');
44
  }
45
  }
46