iT邦幫忙

2025 iThome 鐵人賽

DAY 3
1

昨天,我們成功的在 CG 上創建了一個 PixiJS 的專案,並寫出了第一個測試程式。今天,就讓我們正式踏入 PixiJS 的世界,來認識最核心的顯示物件——Sprite

Pixi 顯示多個女巫動畫

在 PixiJS 中,Sprite 是最基本的顯示物件,用於在畫面中顯示圖像,像是玩家角色、敵人、子彈,甚至是背景中的一顆樹、背景本身,它們絕大多數都是由 Sprite 構成的。簡單來說,只要是你看得到的圖像,通常都是一個 Sprite

▸ 載入圖片資源到專案中

CG 資源管理

首先,我們需要將圖片載入到專案中。點擊專案右側欄上,如圖示的按鈕,即可打開 資源管理 頁面。這裡會顯示你專案內所有已載入的資源,並且按照分類顯示。接著點擊上方的「加載資源」。

CG 搜尋女巫圖片資源

開啟資源頁面後,你必須先給這個資源一個代理名字,前綴的專案代碼是固定的,後面是我們可以自己取的別名,我個人的習慣是會先加上資源的類型,然後再寫上資源的名稱,例如 圖片.女巫

有了名字之後,在 搜尋關鍵字 欄位輸入 hag-broom 並點選「圖片」分類,應該會找到由 Haskasu 上傳,一個騎著掃帚的女巫圖片,點擊資源的勾選框後,再點擊下方的「加載資源」即可將該圖片載入至專案中。

CG 加載資源後 + 程式碼預覽

載入完成後,該圖片就會顯示在剛剛打開的資源管理頁面中,點擊即可顯示該資源的詳細資訊。

▸ 利用 Pixi 將圖片顯示於畫面中

接著讓我們來更新 app.ts 裡面的程式碼,先將昨天寫的程式碼全部清空,並貼上下方的程式碼。這段程式碼將會載入我們剛剛加入的圖片,並在畫面中央顯示出來。

import pixi = CG.Pixi.pixi;

async function start() {

	// 將專案資源載入至遊戲中,並等待載入完成。
    // (記得將資源別名修改成你自己專案的資源別名喔!)
	await pixi.assets
		.add("ironman2025_cook.圖片.女巫")
		.load();

	// 初始化 Pixi。
	await pixi.initialize({
		stageWidth: 960,
		stageHeight: 540
	});

	// 使用資源別名創建 Sprite 物件,並設定物件縮放、錨點、位置。
	const sprite = pixi.assets.createSprite("ironman2025_cook.圖片.女巫");
	sprite.scale.set(3);
	sprite.anchor.set(0.5);
	sprite.position.set(pixi.stageWidth * 0.5, pixi.stageHeight * 0.5);

	// 將 Sprite 物件加入到舞台中。
	pixi.root.addChild(sprite);
}

start();

完成後,點擊上方的「試玩遊戲」按鈕,你就會看到女巫圖片出現在遊戲畫面中央了!

CG 測試程式碼

如圖所示,你可以看到女巫被正確的加入到了舞台的中央,接下來我們來一一拆解程式碼到底做了哪些事情吧!

▸ 拆解程式碼

如果你還不會 TypeScript 或 JavaScript 也沒關係,我會簡單的帶過一些基礎的語法,讓妳也能夠大概了解各個程式碼的用途!

1. import 函式庫

import pixi = CG.Pixi.pixi;

這行程式碼是將 CG.Pixi.pixi 這一長串縮寫成 pixi,因為我們會常常需要用到 CG.Pixi.pixi 裡面的功能,例如範例中使用的 assetsinitializeroot 等,要是每次使用前面都得寫這麼長,是我就累了。

讓我們用實際的範例來示範一下,有沒有 import 的差別在哪裡。

// 沒有使用 import 的時候
sprite.position.set(CG.Pixi.pixi.stageWidth * 0.5, CG.Pixi.pixi.stageHeight * 0.5);
// 使用 import 的時候
sprite.position.set(pixi.stageWidth * 0.5, pixi.stageHeight * 0.5);

是不是縮短很多,怎麼樣,知道 import 的美好了吧!而且更讚的是,當你輸入 pixi 後,CG 會自動跳出提示,選擇後 CG 就會幫你在檔案最上方補上那一段 import,也就是說其實那一段其實是 CG 幫我寫的,我們其實不需要去管要不要 import 的事情。

不過實際上 import 的功能其實是「引用」才對,一般來說想要使用函示庫或模組的功能,第一件事情就是先引用到當前的檔案中。只是在 CG,所有的模組都會被包裝在 CG 這個全域物件內,所以才能直接利用 CG.Pixi.pixi 這樣的方式來使用。

2. async 函數 & awiat

function start() {
    // ... 暫時省略 ...
}

這是一般用來創建 function(函數)的方法,你可以把函數想像成是一道食譜,上面寫好了各種步驟,用來讓我們可以跟著食譜一步步的做。

但它終究是一道食譜,只是定義好步驟而已,要執行這些步驟,我們需要實際動手。

start();

這樣就是告訴電腦,開始執行名叫 start 的函數,電腦就會從頭到尾,一步步地執行裡面的程式碼。

async function start() {
    // 將專案資源載入至遊戲中,並等待載入完成。
    await pixi.assets.add("ironman2025_cook.圖片.女巫").load();
    // ... 暫時省略 ...
}

function 前面加個 async 是什麼意思?也就是告訴電腦,這個函數裡面有需要等待的步驟,這個步驟執行需要一段時間,必須等它執行完成以後,才可以繼續往下走。

await 就是告訴電腦,這裡就是要等待的步驟,當函數執行到這裡的時候,就會開始等待,直到後面的程式碼告訴電腦說「我執行完了!」,這個函數才會繼續往下執行其他程式碼。

需要特別注意的是,await 只能在 async 函數裡面使用,而想要使用 await,就必須將函數標記成 async 函數喔!

3. 載入資源與初始化

// 將專案資源載入至遊戲中,並等待載入完成。
await pixi.assets
	.add("ironman2025_cook.圖片.女巫")
	.load();

PixiJS 提供了載入資源的功能,而 CG 又幫我們把這個功能包裝成更簡單的函數。

  • pixi.assets.add():在 () 內輸入專案的資源別稱,就可以將資源加入到準備載入的行列中,資源的別稱可以在資源管理內查看,每個資源上方都會有我們載入資源時所填寫的別稱,旁邊還會有個「複製」按鈕,點擊後就可以直接填在括號內。

記得字串一定要在前後使用 " 雙引號包起來喔!

  • pixi.assets.load():使用 add() 加入要載入的資源後,就要使用 load() 開始載入資源,這個步驟需要花點時間,因此需要在前面加上 await 來等待載入完成。

由於 add() 執行後會回傳 pixi.assets,因此我們才可以繼續使用 pixi.assets 的功能,而不需要重複撰寫 pixi.assets 開頭。

// 初始化 Pixi。
await pixi.initialize({
	stageWidth: 960,
	stageHeight: 540
});

想要利用 Pixi 在畫面上顯示東西,就必須先初始化。

pixi.initialize() 用於初始化 Pixi 的舞台設定,它會接收一個物件作為參數,在物件內我們可以設定 stageWidthstageHeight,也就是舞台寬度舞台高度。其餘還有像是 resolutionstageMask 等屬性,不過這些等之後遇到了再來介紹!

這個步驟同樣需要一點時間,因此我們也要在前面加上 await 告訴電腦請等它執行完畢。

4. 創建物件與設定屬性

// 使用資源別名創建 Sprite 物件,並設定物件縮放、錨點、位置。
const sprite = pixi.assets.createSprite("ironman2025_cook.圖片.女巫");
sprite.scale.set(3);
sprite.anchor.set(0.5);
sprite.position.set(pixi.stageWidth * 0.5, pixi.stageHeight * 0.5);

pixi.assets.createSprite() 用於快速的幫我們創建一個 Sprite 物件,創建完成後我們會用 sprite 這個名字把物件保存起來。

如果你習慣使用 Texture 來創建物件,也可以這樣做。
const texture = pixi.assets.getTexture("ironman2025_cook.圖片.女巫");
const sprite = new PIXI.Sprite(texture);

接著我們對這個物件做了三件事情:

  • scale.set():用於設定物件的縮放,預設為 1set(3) 表示將這個物件放大 3 倍。
  • anchor.set():用於設定物件的錨點(中心點),預設為 0,也就是物件的錨點預設是在左上角,set(0.5) 表示將物件的錨點設定在正中間。當然如果設定為 1,就是將錨點設定在物件的右下角。
  • position.set():用於設定物件的位置,預設為 (0, 0),也就是舞台畫面的左上角,x 越大物件越靠右邊,y 越大物件越靠下方,pixi.stageWidthpixi.stageHeight 分別代表我們在初始化舞台時所設定的寬高,* 0.5 則代表各自取一半(寬的一半與高的一半),因此就會是畫面的正中央。

其實這些具有 xy 的屬性,完整的 set 寫法應該會是 sprite.anchor.set(0.5, 0.5) 這樣,表示 x 設為 0.5y 也設為 0.5,只是 PixiJS 在我們省略第二個參數的時候,就會自動認為我們要將 xy 都設定成那一個參數,因此在設定 scaleanchor 中,我省略了第二個參數。

5. 加入舞台

// 將 Sprite 物件加入到舞台中。
pixi.root.addChild(sprite);

這是最關鍵的一步。在 PixiJS 中,所有要顯示在畫面上的物件,都必須被「加入到舞台」上。pixi.root 就是我們的主舞台,addChild() 則是用來將物件放上去。如果你忘記寫這行,就算你前面做了再多設定,也無法在畫面上看到任何東西喔!

在原生 PixiJS 中,根節點通常是 app.stage,如果是在寫原生的 PixiJS,上面看起來會像是 app.stage.addChild(sprite)pixi.root 是站長為了模擬以前在 Flash 上開發遊戲的習慣,所以將根節點取名為 root

點我查看範例程式碼

▸ 總結

今天的內容比昨天豐富了許多,我們不僅認識了遊戲的核心物件 Sprite,更手把手地將一個完整的 Sprite 物件顯示在畫面上,並且拆解了程式碼的每個部分。

如果你是曾接觸過 PixiJS 的人,你可能會發現有許多部分與原生的 PixiJS 有所不同,因為我們的 PixiJS 是建立在 CG 平台上的,這裡的 Pixi 模組幫我們把一些本應該自己設定的部分,包裝成了更簡潔的函數供我們使用,這也是我為什麼選擇在這個平台上介紹的原因,這降低了許多新手的門檻,我認為等大家真的了解了 PixiJS 的運作流程後,再去接觸原生的 PixiJS 語法也不遲。

從明天開始,我們將會真正讓這個 Sprite 動起來,介紹如何控制它的位置、縮放與旋轉!


上一篇
Day 02:創建你的第一個 PixiJS 專案
下一篇
Day 04:讓你的 Sprite 動起來 - 位置、縮放與旋轉
系列文
用 PixiJS 寫遊戲!告別繁瑣設定,在 Code.Gamelet 打造你的第一個遊戲4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言