PixiJS 連連看遊戲完成倒數計時、生命值與 FB 按鈕後的畫面

← INSIGHTS & PERSPECTIVES | 前端開發

PixiJS 連連看完整功能實作:倒數計時、生命值與 FB 按鈕

說明 PixiJS 連連看遊戲如何補上倒數計時、重整生命值、FB 按鈕,並把 Clock、Stars、FBBtn 掛進 GameScene。

PixiJS 連連看遊戲要從可玩原型變成完整畫面,至少要補上倒數計時、重整次數限制與外部連結按鈕。這篇延續前面的連連看實作,把 ClockStarsFBBtn 三個 UI 元件分別拆成 TypeScript 類別,最後掛到 GameScene 的 stage。

完整遊戲畫面還缺哪些功能?

PixiJS 連連看遊戲在盤面、消除、提示與重整完成後,還需要時間、生命值與社群按鈕。這三個元件都屬於遊戲 UI,適合獨立成類別再放進場景。

前一版成果和 mockup 相比,主要缺口是左上角的時間倒數、重整可用次數,以及左下角的 FB 按鈕。

PixiJS 連連看 mockup 中尚未完成的時間、生命值與 FB 按鈕

拆成元件後,GameScene 不必知道每個 UI 的內部狀態。Clock 負責時間,Stars 負責重整次數,FBBtn 負責外部連結與音效;場景只處理「把元件放進遊戲」。

Clock 如何實作 PixiJS 倒數計時?

PixiJS 倒數計時可以用 setInterval 每秒更新 PIXI.Text,時間歸零時送出遊戲結束事件。重新開局時,Clock 需要把秒數與畫面文字重設。

新增 Clock.ts,內容如下:

import Container = PIXI.Container;
import { Loader } from "../core/Loader";
import { reloadTimes } from "./GameBoard";
import { eventEmitter } from "../Main";
import { GameFlowEvent } from "../core/Event";

export class Clock extends Container {
    private starList = [];
    private remainTimes:number = 480;
    private remainText:PIXI.Text;
    private clockInterval:any;
    constructor() {
        super();
        this.x = 18;
        this.y = 17;

        this.addChild(PIXI.Sprite.from(Loader.resources['Button'].textures['Clock']));

        eventEmitter.on(GameFlowEvent.CreateNewGameRequest, ()=>{
            this.remainTimes = 480;
            this.remainText.text = "8:00";
        });
        this.remainText = new PIXI.Text("8:00", {
            fontWeight: 'bold',
            fontSize: 20,
            fontFamily: 'Arial',
            fill: '#75C6ED',
            align: 'center',
            stroke: '#FFFFFF',
            strokeThickness: 6
        });
        this.remainText.x = 36;
        this.addChild(this.remainText);
        this.clockInterval = setInterval(this.updateTime.bind(this), 1000);
    }

    public updateTime(){
        this.remainTimes --;
        if(this.remainTimes == 0){
            clearInterval(this.clockInterval);
            eventEmitter.emit(GameFlowEvent.GameEndWithTimeout);
        }
        this.remainText.text = Math.floor(this.remainTimes/60)+':'+((this.remainTimes%60 < 10) ? "0":"")+this.remainTimes%60;
    }
}

這段實作把初始時間設為 480 秒,也就是 8 分鐘。remainTextPIXI.Text 顯示在時鐘圖片旁邊,updateTime() 每秒扣一秒,並用 Math.floor(this.remainTimes / 60)this.remainTimes % 60 組出 分:秒

實作時有一個小地方可以補強:Clock.ts 匯入了 reloadTimes,但倒數計時沒有使用這個變數。整理程式碼時可以刪掉這個 import,避免之後誤以為時間元件和重整次數有耦合。

Stars 如何顯示重整次數限制?

PixiJS 重整次數限制可以用星星圖示呈現。Stars 讀取 reloadTimes,依剩餘次數顯示 Star_FullStar_Empty,並在重整或重新開局事件後更新畫面。

新增 Stars.ts,內容如下:

import Container = PIXI.Container;
import { Loader } from "../core/Loader";
import { reloadTimes } from "./GameBoard";
import { eventEmitter } from "../Main";
import { GameFlowEvent } from "../core/Event";

export class Stars extends Container {
    private starList = [];
    constructor() {
        super();
        this.x = 20;
        this.y = 78;
        this.updateStarStatus();
        eventEmitter.on(GameFlowEvent.ReloadBoardRequest, this.updateStarStatus.bind(this));
        eventEmitter.on(GameFlowEvent.BoardNeedReload, this.updateStarStatus.bind(this));
        eventEmitter.on(GameFlowEvent.CreateNewGameRequest, this.updateStarStatus.bind(this));
    }

    updateStarStatus = ()=>{
        this.removeChildren();
        for(var i =0;i<3;i++){
            let star:any;
            if(i<reloadTimes){
                star = PIXI.Sprite.from(Loader.resources['Button'].textures['Star_Full']);
            }else{
                star = PIXI.Sprite.from(Loader.resources['Button'].textures['Star_Empty']);
            }
            star.x = i*33;
            this.starList.push(star);
            this.addChild(star);
        }
    }
}

Stars 的畫面邏輯很單純:先 removeChildren() 清空舊星星,再依固定 3 顆星重新畫一次。當 reloadTimes 變少,前面的星星維持滿星,後面的星星改成空星。

事件設計上,ReloadBoardRequestBoardNeedReloadCreateNewGameRequest 都會觸發 updateStarStatus()。這代表玩家手動重整、系統判斷盤面需要重整、玩家重新開局時,生命值顯示都能跟著同步。

FBBtn 如何做成可點擊按鈕?

PixiJS FB 按鈕可以繼承既有 ButtonBase,把貼圖、座標與點擊行為集中在 FBBtn。按鈕被觸發時開啟外部連結,並播放一段音效。

新增 FBBtn.ts,內容如下:

import { ButtonBase } from "./ButtonBase";
import { SoundMgr } from "../core/SoundMgr";

export class FBBtn extends ButtonBase {
    constructor() {
        super('Button','FB',50,410);
    }
    public trigger(){
        window.open(' https://www.facebook.com/claire0318 ', 'Claire Chang');
        SoundMgr.play("About");
    }
}

FBBtn 只需要覆寫 trigger(),互動事件與按鈕動畫都沿用 ButtonBase。這種繼承方式適合連連看 UI,因為靜音、提示、重整、復原與 FB 按鈕都可以共用同一套點擊回饋。

實務上,window.open() 裡的網址前後空白建議移除,避免瀏覽器或靜態檢查工具判定為不乾淨的 URL。若要防止新視窗取得來源頁面的控制權,也可以改用明確的 noopener 開啟策略。

GameScene 要怎麼掛上三個新元件?

PixiJS 場景只需要把 FBBtnStarsClock 加到 application.stage。當 UI 元件自己監聽事件並更新狀態,GameScene 可以維持乾淨。

GameScene.ts 新增下面程式碼:

application.stage.addChild(new FBBtn());
application.stage.addChild(new Stars());
application.stage.addChild(new Clock());

這三行放進場景後,遊戲畫面就會出現左下角 FB 按鈕、左側星星生命值與左上角倒數計時。元件順序也會影響顯示層級:後加入的 Clock 會在前兩個元件之上,若 UI 有重疊,應用程式需要確認 z-order 是否符合設計。

完成後的 PixiJS 連連看畫面是什麼樣子?

完成後的 PixiJS 連連看畫面會同時包含盤面、倒數計時、重整生命值與 FB 按鈕。這代表核心遊戲流程與基本 UI 已能串成一個完整可玩的版本。

最終遊戲畫面如下:

PixiJS 連連看遊戲完成所有基本 UI 後的畫面

完整 commit 紀錄可以參考 GitHub 專案:cochiachang/ironman2018。這篇對應的重點不是新增複雜演算法,而是把遊戲體驗缺少的最後幾個 UI 元件接起來。

這次實作的元件分工怎麼看?

PixiJS 連連看完整功能實作可以用「場景負責組裝,元件負責狀態」來整理。這個分工讓 UI 行為集中在各自類別裡,後續維護比較不容易把遊戲流程寫散。

元件負責功能主要狀態觸發事件
Clock倒數計時remainTimesremainTextCreateNewGameRequestGameEndWithTimeout
Stars重整次數顯示reloadTimes 對應的星星貼圖ReloadBoardRequestBoardNeedReloadCreateNewGameRequest
FBBtn外部連結按鈕按鈕貼圖與座標trigger()
GameScene場景組裝stage childrenaddChild()

這個版本最值得保留的設計是事件驅動。ClockStars 不必被 GameScene 每一秒或每一次重整主動呼叫,而是自己訂閱遊戲流程事件,畫面狀態就能跟著流程變動。

常見問題

QPixiJS 倒數計時一定要用 ticker 嗎?

PixiJS 倒數計時不一定要用 ticker。這份實作用 setInterval 每秒更新一次文字,對單純倒數很直覺;如果遊戲暫停、速度調整或背景切換要更精準,才建議改用 PIXI.Ticker 搭配 delta time。

QClock 歸零後要怎麼通知遊戲結束?

Clock 歸零後會發出 GameFlowEvent.GameEndWithTimeout。遊戲流程管理器或其他場景元件只要監聽這個事件,就可以切換到失敗畫面或停止玩家操作。

QStars 為什麼要在每次更新時重畫星星?

Stars 重畫星星可以讓 UI 狀態和 reloadTimes 保持一致。因為只有 3 顆星,清空後重建的成本很低,程式也比逐一追蹤每顆星目前貼圖更容易讀。

QFBBtn 可以改成其他社群或外部連結嗎?

FBBtn 可以改成任何外部連結按鈕。只要繼承 ButtonBase,替換 texture id、座標、window.open() 網址與音效名稱,就能沿用相同按鈕互動。

Q這篇適合接在哪些 PixiJS 連連看功能後面?

這篇適合接在盤面消除、按鈕基底、提示重整與復原功能之後。當核心玩法已經可以運作,倒數計時與生命值才有足夠的遊戲流程可以連動。

參考資料

延伸閱讀

最後更新

2026-08-28

關於作者

Claire Chang | 企業 AI 導入與流程轉型顧問。專注於 AI Agent 架構設計、ERP 系統整合與企業 AI 治理。

首次發布:2018-11-10