iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0

為了賦予未來程式碼更高的靈活性和可用性,我們試著釐清和優化某些關鍵環節。今日,將專注於以下三個核心議題進行深入的分析和調整:

  1. 在設計過程中,步驟計數應該是從 0 開始還是從 1 開始?
  2. 如何根據卡片的總數來動態調整其排列順序,而非僅依賴於步驟數?
  3. 程式碼的擴充性如何?是否能方便地增加或減少題數?

各問題分析與解法

  1. 步驟建議從 0 還是從 1 開始
    在程式設計中,陣列的索引通常從 0 開始。這是一個普遍的慣例,特別是在像 JavaScript 這樣的語言中。然而,currentStep 和 totalStep 這樣的變數更多地與業務邏輯和用戶界面有關,而不僅僅是資料結構。

如果這些步驟是用來呈現給最終使用者的(例如,顯示在 UI 上),從 1 開始可能會更直觀。
如果這些步驟主要是用於內部邏輯和數據操作,從 0 開始可能會更符合一般的程式設計慣例。
綜合考慮,如果這是以使用者為導向的設計,從 1 開始可能更直觀。

結論:所以目前不針對步驟開始題調整。

  1. 要依照卡片的張數,去抓取排列的位置,而不是依照步驟。要怎麼調整程式
    你可以使用 clues.length 來動態生成位置,而不是依賴 gameStatus.currentStep。這樣,即使卡片的數量變化,位置也會相應地調整。

  2. 程式擴充性如何,可否增加題數
    程式碼模組化之後,便更容易增加題數。只需在 cluesData JSON 文件中添加更多的數據即可。

實際程式碼調整與修正

依照卡片張數去抓取與調整卡片位置

  1. handleUpdateTimelinePosition 移除傳入參數 currentStep
  2. 更新命名使用卡片張數名稱 totalCards 抓取在 timelineEvents 上面的卡片(包含預設卡片)
const handleUpdateTimelinePosition = () => {
    const totalCards = timelineEvents.value.length;
    // 更新 timelineEvents 的位置
    const updateTimelineEventsPosition = (totalCards, timelineEvents, timelinePositions) => {
        for (let i = 0; i < totalCards; i++) {
            timelineEvents[i].transform = `translate(-50%, ${timelinePositions[i]?.y}px)`;
        }
    };
    currentTimelinePosition.value = clueDefaultPosition.value[totalCards - 1];
    switch (totalCards) {
        case 1:
            timelineEventsStyleRaw.value[0].transform = 'translate(-50%, 160px)';
            break;
        case 2:
            hintPostionTop.value = '75px';
            updateTimelineEventsPosition(totalCards, timelineEventsStyleRaw.value, currentTimelinePosition.value);
            break;
        default:
            if (totalCards >= 3) {
                hintPostionTop.value = '75px';
                updateTimelineEventsPosition(totalCards, timelineEventsStyleRaw.value, currentTimelinePosition.value);
            }
            break;
    }
};

問題卡片擴充性模組化

  1. 針對遊戲狀態固定值,改抓取作答卡片的數量
  2. 利用 IIFE 去產生預設位置資料等

針對遊戲狀態固定值,改抓取作答卡片的數量

const initialGameState = {
    currentStep: 1,
    totalStep: cluesData.length,
    stepCorrect: Array(cluesData.length).fill(null),
    score: 0,
    scoreRecord: Array(cluesData.length).fill(0),
};

說明:stepCorrect、scoreRecord 改使用 Array.fill() 方法去產生預設值

利用 IIFE 去產生預設位置資料等

const totalQuestions = cluesData.length; // 這個數字可以根據你的需要來設定
const initialTransform = 'translate(-50%, 150px)'; // 初始的 transform 值
const zIndexStart = 1; // zIndex 的起始值

const currentTimelinePosition = ref((() => {
  const positions = [];
  let yPosition = 40;
  const yIncrement = 60; // y座標每次增加的數量,你可以根據需要來調整

  for (let i = 0; i < totalQuestions + 1; i++) {
    positions.push({
      x: '50%',
      y: yPosition,
    });
    yPosition += yIncrement;
  }

  return positions;
})());

const timelineEventsStyleRaw = ref((() => {
  const styles = [];
  for (let i = 0; i < totalQuestions + 1; i++) {
    styles.push({
      transform: initialTransform,
    });
  }
  return styles;
})());

const timelineEventsStyleRawAnimationTarget = ref((() => {
  const styles = [];
  for (let i = 0; i < totalQuestions + 1; i++) {
    styles.push({
      transform: initialTransform,
      zIndex: zIndexStart + i,
    });
  }
  return styles;
})());

const clueDefaultPosition = ref((function generateData() {
  const data = [];
  const initialY = 40;
  const step = 60;

  // 第一個子陣列
  data.push([{ "x": "-50%", "y": 150 }]);

  // 第二個子陣列
  data.push([
    { "x": "50%", "y": 150 },
    { "x": "50%", "y": 260 }
  ]);

  // 從第三個子陣列開始
  for (let i = 3; i <= totalQuestions + 1; i++) {
    const subArray = [];
    for (let j = 0; j < i; j++) {
      subArray.push({ "x": "50%", "y": initialY + j * step });
    }
    data.push(subArray);
  }

  return data;
})());

說明:timelineEventsStyleRaw、timelineEventsStyleRawAnimationTarget clueDefaultPosition 改使用 IIFE 的方法初始化,替代寫死的方式

其他微調

步驟改為 currentStep - 1 以顯示答題數目

<div class="mr-2 text-sm font-Libre">
  {{ gameStatus.currentStep - 1 }} / {{ gameStatus.totalStep }} 題
</div>

上一篇
功能製作 計分 分數回饋
下一篇
過場動畫製作設計
系列文
打造紐時風格的時間線小遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言