iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
Modern Web

TypeScript 啟動!系列 第 11

[Day 11] TypeScript 對話小專案

  • 分享至 

  • xImage
  •  

前面十天已經學習了不少應用基礎,今天剛好看到一部有趣的短影片,steven he 有一句話 emotional damage 實在是魔音環繞。因此今天就來寫一個簡單的網頁互動吧,主要預計完成兩個人在對話,並且會用到一點點前端(先從 HTML 開始,之後帶入前端語言)。

Step1. 前端簡易開發環境

為了能夠順利運行前端的部分,因此會用到一個很好用的外掛套件(live server),它可以直接在 VSCode 內直接運行一個小小的 Server ,然後運行 index.html。

首先我們點選 VSCode 的外掛套件模組,然候搜尋 live server → 點選圖示 → 右邊可以點選 install(完成安裝會如下圖,有可能需要重開 reload一下)。

https://ithelp.ithome.com.tw/upload/images/20230925/20163107iFS5QjJEpp.png

順利安裝完成後,畫面右下角就會出現一個 Go Live 的圖案。

https://ithelp.ithome.com.tw/upload/images/20230925/20163107k7eQB7AuIT.png

建立一個名叫 index.html 的檔案,程式碼如下。

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dialogue Game</title>
</head>
<body>
    <h1>Dialogue Game</h1>
    <div id="dialogueBox">
        <p id="dialogueText"></p>
    </div>
    <button onclick="test()">Next</button>
</body>
</html>

一個前端網頁的呈現,通常會有一個 index.html 做為初始的進入點,接下來才會引用各式各樣的前端套件語言。html 內大概會包含 → → ,之後大概會著重在 body 內引用進來的 .js 檔案。

接下來就能按下 GoLive 了,會自動跳出瀏覽器並顯示一個類似這樣簡易畫面。

https://ithelp.ithome.com.tw/upload/images/20230925/20163107Qai78oBRbw.png

至此我們就完成第一步了,有了簡易的前端伺服器來幫我們確認寫得對不對~

Step2. 設計對話

接下來我們回到主題 TypeScript 中,主要預計完成兩個人在對話,並且最後用上 Emotional damage 的有趣對話。我大概會先透過介面( interface )來進行設計人、可能以亞洲人跟歐洲人好了。

介面 - Person

interface Person {
    name: string; // 姓名
    dialogue: string[]; // 對話內容
    damage?: number; // hp 或 傷害
}

定好 interface 之後就能來擴展他們(亞洲人與歐洲人)了。

類別 - Class

class European implements Person {
    name = "歐洲人";
    dialogue = [
        "歐洲的天氣很好。",
        "我們文化有豐富歷史。",
        "我們一天只要上五小時班。"
    ];
}

class Asian implements Person {
    name = "亞洲人";
    dialogue = [
        "亞洲的食物真的很好吃。",
        "我們節日很多,充滿了風土民情。",
        "Emotional damage 造成一百萬點傷害!"
    ];
    damage = 1000000;
}

繼承 Person 並實際將內容物給實作出來之後,就能加上一點操控 html 的語法了。大概會用上 document.getElementById 來獲取要操控的 dom 元素和, innerText 改變文字吧。

Step3. 實作

// game.ts
interface Person {
    name: string;
    dialogue: string[];
    damage?: number;
}

class European implements Person {
    name = "歐洲人";
    dialogue = [
        "歐洲的天氣很好。",
        "我們的文化有很多歷史。",
        "我們一天只要上三小時班。"
    ];
}

class Asian implements Person {
    name = "亞洲人";
    dialogue = [
        "亞洲的食物真的很好吃。",
        "我們的節日很多,充滿了色彩。",
        "Emotional damage 造成一百萬點傷害!"
    ];
    damage = 1000000;
}

type CurrentSpeaker = "European" | "Asian";

let currentDialogueIndex = 0;
let currentSpeaker: CurrentSpeaker = "European";

function showNextDialogue() {
    const european = new European();
    const asian = new Asian();
    const dialogueTextElement = document.getElementById("dialogueText");

    if (currentSpeaker === "European") {
        dialogueTextElement.innerText = `${european.name}: ${european.dialogue[currentDialogueIndex]}`;
        currentSpeaker = "Asian";
    } else {
        dialogueTextElement.innerText = `${asian.name}: ${asian.dialogue[currentDialogueIndex]}`;
        currentDialogueIndex++;
        currentSpeaker = "European";
    }

    if (currentDialogueIndex === european.dialogue.length) {
        document.querySelector("button").disabled = true;
    }
}

window.showNextDialogue = showNextDialogue;

建立一個叫做 game.ts 的檔案,其中 document.getElementById 之類的可能會出現警告,畢竟原本 TypeScript 沒有這一類東西。

最後也把 index.html 稍微修改一下,引入我們的 game.js (tsc game.ts 編譯後的檔案)。

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dialogue Game</title>
</head>
<body>
    <h1>Dialogue Game</h1>
    <div id="dialogueBox">
        <p id="dialogueText"></p>
    </div>
    <button onclick="showNextDialogue()">Next</button>

    <script src="./game.js"></script>
</body>
</html>

最後運行起來結果就會像是,被外國人的工作時間給嚇到死亡了QQ
https://ithelp.ithome.com.tw/upload/images/20230925/20163107B115I8tVsc.png
https://ithelp.ithome.com.tw/upload/images/20230925/20163107Gdcw1qy1ih.png

完成了一個小小小專案後,可能之後會先在繼續補充一點語法上的問題,在盡可能想一個好一點的專案。後續也可能搭配一些常見的 react.js 來做新的小專案。


上一篇
[Day 10] TypeScript 類別與介面
下一篇
[Day 12] TypeScript 初見 React.js
系列文
TypeScript 啟動!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言