iT邦幫忙

2024 iThome 鐵人賽

DAY 23
0
生成式 AI

人人都是工程師的時代來臨了嗎?!系列 第 23

D23 關卡內容設置 aka 爆改架構

  • 分享至 

  • xImage
  •  

要開始新增關卡內容了!
原本只要試做個選擇題,結果比我想的還複雜。

試做一個選擇題
https://ithelp.ithome.com.tw/upload/images/20240924/20111174YqetpqPNs6.png

然後他更改了一堆看起來很不對的東西,我不敢直接用

<div id="quizDialog" class="dialog-box" style="display:none;">
    <p>選擇正確的答案:</p>
    <button id="optionA">A. 正確答案</button>
    <button id="optionB">B. 錯誤答案</button>
    <button id="optionC">C. 錯誤答案</button>
</div>
function checkCollisionWithPoint(x, y, pointX, pointY, level, missionIndex) {
    const distance = Math.sqrt((x - pointX) ** 2 + (y - pointY) ** 2);

    // 如果碰撞距離小於 40px,表示碰到任務點
    if (distance < 40) {
        if (level === 3) {  // 如果是第三關
            showQuizDialog(); // 顯示選擇題對話框
        } else {
            showDialogueForLevel(level, missionIndex); // 根據其他關卡顯示對應的對話框
            hasCompletedMission = true; // 其他關卡直接完成任務
        }
    }
}

繼續問
https://ithelp.ithome.com.tw/upload/images/20240924/20111174IGmOU3yxKD.png

結果他給我生了這些東東

// 假設進入第一個任務點
checkCollisionWithPoint(x, y, pointX, pointY, level, missionIndex) {
    const distance = Math.sqrt((x - pointX) ** 2 + (y - pointY) ** 2);

    if (distance < 40) {
        const question = "選擇正確的答案:";
        const options = ["A. 正確答案", "B. 錯誤答案", "C. 錯誤答案"];
        const correctAnswerIndex = 0;

        showQuizDialog(question, options, correctAnswerIndex, (isCorrect) => {
            if (isCorrect) {
                hasCompletedMission = true;  // 任務完成
            }
        });
    }
}

尷尬了,每個任務點都變成選擇題了
但我不打算只做選擇題

只好直接開始加碼
https://ithelp.ithome.com.tw/upload/images/20240924/20111174zSkemgMRcZ.png

在詢問的過程中,慢慢意識到這是一個爆改所有既有邏輯的過程,其實沒有我想像的簡單。
因此我也詢問了整個架構整裡的建議

const levelConfig = {
    1: {
        missions: [
            { point: { x: 100, y: 200 }, type: 'quiz', question: "選擇正確的答案:", options: ["A", "B", "C"], correctAnswerIndex: 0 }
        ],
        message: '這是第一關的提示信息。',
        type: 'quiz-mission'  // 第一關是選擇題
    },
    2: {
        missions: [
            { point: { x: 150, y: 300 }, isCorrect: false },
            { point: { x: 200, y: 400 }, isCorrect: true },
            { point: { x: 350, y: 250 }, isCorrect: false }
        ],
        message: '找到正確的任務點以通關!',
        type: 'find-correct-point'  // 第二關是找到正確點的任務
    },
    3: {
        missions: [
            { point: { x: 300, y: 150 }, type: 'quiz', question: "這是第三關的問題:", options: ["A", "B", "C"], correctAnswerIndex: 0 }
        ],
        message: '第三關的提示。',
        type: 'quiz-mission'
    }
};

嗯...算了,先跳過

目前的策略是繼續塞各種闖關方式給他生,看他能不能給我一個最大公因數來
所以剛又想了一個
https://ithelp.ithome.com.tw/upload/images/20240924/20111174DFvP9Qhlg7.png

終於,在塞了三種不同邏輯之後,chatGPT 總算幫我生出了個最大公因數
新架構誕生!
他生了兩種形式,差異只有直接觸發關卡內容 or 把每個關卡內容寫成function再觸發function
後者會整齊一點

function checkCollisionWithMissions(x, y, level) {
    const levelData = levelConfig[level];

    if (levelData) {
        levelData.missions.forEach((mission, index) => {
            const { point, type } = mission;
            const distance = Math.sqrt((x - point.x) ** 2 + (y - point.y) ** 2);

            if (distance < 40) {
                switch (type) {
                    case 'quiz':
                        handleQuizMission(mission);
                        break;
                    case 'find-correct-point':
                        handleFindCorrectPointMission(mission);
                        break;
                    case 'provide-password':
                        handleProvidePasswordMission(mission);
                        break;
                    case 'input-password':
                        handleInputPasswordMission(mission);
                        break;
                    case 'default':
                    default:
                        alert(mission.message || '你碰到了任務點!');
                        hasCompletedMission = true;  // 預設行為,直接通關
                        break;
                }
            }
        });
    }
}


function handleQuizMission(mission) {
    showQuizDialog(mission.question, mission.options, mission.correctAnswerIndex, (isCorrect) => {
        if (isCorrect) {
            hasCompletedMission = true;
        }
    });
}
function handleFindCorrectPointMission(mission) {
    if (mission.isCorrect) {
        alert('你找到正確的任務點!');
        hasCompletedMission = true;
    } else {
        alert('這不是正確的任務點,請繼續尋找!');
    }
}

前者直接觸發長這樣

function checkCollisionWithMissions(x, y, level) {
    const levelData = levelConfig[level];

    if (levelData) {
        levelData.missions.forEach((mission) => {
            const { point, type, isCorrect, password, correctPassword } = mission;
            const distance = Math.sqrt((x - point.x) ** 2 + (y - point.y) ** 2);

            if (distance < 40) {
                switch (type) {
                    case 'touch-win':  // 碰到即通關
                        alert('你已完成此關!');
                        hasCompletedMission = true;
                        break;
                    case 'find-correct':  // 找到正確的任務點
                        if (isCorrect) {
                            alert('你找到正確的任務點!');
                            hasCompletedMission = true;
                        } else {
                            alert('這不是正確的任務點,請繼續尋找!');
                        }
                        break;
                    case 'quiz':  // 選擇題邏輯
                        showQuizDialog(mission.question, mission.options, mission.correctAnswerIndex, (isCorrect) => {
                            if (isCorrect) {
                                alert('你答對了!');
                                hasCompletedMission = true;
                            } else {
                                alert('答案錯誤,請重試!');
                            }
                        });
                        break;
                    case 'show-password':  // 顯示密語
                        alert(`通關密語是:${password}`);
                        break;
                    case 'input-password':  // 輸入密語
                        const userInput = prompt('請輸入通關密語:');
                        if (userInput === correctPassword) {
                            alert('密語正確,通關成功!');
                            hasCompletedMission = true;
                        } else {
                            alert('密語錯誤,請重試!');
                        }
                        break;
                    case 'invalid-point':  // 無效的任務點
                        alert('這個任務點無效,請選擇其他任務點!');
                        break;
                    default:
                        console.log('未知的任務點類型');
                }
            }
        });
    }
}

最後應該會照這個形式寫下去,畢竟我也想不到每關分開編輯還能有什麼更簡便的方法。
至於最後兩種型態要用誰,就取決於我的關卡內容到底要多長了。

附註:目前為止的實際製作時間約為2週,給大家一個參考


上一篇
D22 碰到才可以過 & 記憶混亂的chatGPT?
下一篇
D24 關卡架構調整
系列文
人人都是工程師的時代來臨了嗎?!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言