loading...
上次更新: 2023-03-22
以下內容為 PixiJS 版本為 v7
> npm install pixi.js
js 檔案裡面引入pixiimport * as PIXI from 'pixi.js';Pixi Application 的實例。new PIXI.Application 的 arguments 可參考官方文件
(範例中使用 antialias: true 可讓畫面不會有鋸齒狀、寬高設為 window.innerWidth 和 window.innerHeight 來填滿畫面)// 創建 pixi app
const app = new PIXI.Application({
width: window.innerWidth,
height: window.innerHeight,
antialias: true,
background: '0x23395d'
});
// 放到 DOM 裡面
document.body.appendChild(app.view);Graphics畫各種形狀Grahpics 這個 Class 底下,我們創建的形狀無論是方形、圓型、線條...等,都是 Grahpics 的實例。HTML 的 <body>,所有要顯示的東西都要放到這邊。lineStyle的三個參數如下: lineStyle(寬度, 顏色, 透明度)
const line = new PIXI.Graphics();
line.lineStyle(5, 0xDE3249, 1)
line.moveTo(100, 500) // (起始點x座標, 起始點y座標)
line.lineTo(200, 500) // (結束點x座標, 結束點y座標)
// 也可以這麼寫
line
.lineStyle(5, 0xDE3249, 1)
.moveTo(100, 500)
.lineTo(200, 500)
// 呼叫addChild這個方法,把線放到畫面上
app.stage.addChild(line)const rectangle = new PIXI.Graphics();
rectangle
.beginFill(0x2a9d8f); // 開始畫、並設定顏色
.drawRect(50, 50, 150, 100); // drawRect(x座標, y座標, 寬, 高)
.endFill(); // 結束
app.stage.addChild(rectangle)drawCircle 的三個參數如下: drawCircle (圓心的 x 座標, 圓心的 y 座標, 半徑長度)
// 有外框線的圓型
const circleWithStroke = new PIXI.Graphics();
circleWithStroke.lineStyle(2, 0xFEEB77, 1)
.beginFill(0xDE3249, 1)
.drawCircle(100, 400, 50)
.endFill();
// 圓型
const circle = new PIXI.Graphics();
circle.lineStyle(0)
.beginFill(0xDE3249, 1)
.drawCircle(100, 250, 50)
.endFill();
// 放到畫面上
app.stage.addChild(circleWithStroke, circle)Text ClassTextStyle 這個Class// 樣式
const myStyle = new PIXI.TextStyle({
fontFamily: 'Arial',
fontSize: 36,
fontStyle: 'italic',
fontWeight: 'bold',
fill: '#ffffff',
stroke: '#4a1850',
});
// 創建文字
const myText = new PIXI.Text('Hello World!!', myStyle);
app.stage.addChild(myText);text 這個propertymyText.text = 'Text changed!'Texture 和 Spritetexture,再把 textrure 轉成 sprite。texture?
因為 Pixi 使用 WebGL 在 GPU 上渲染圖像,圖像需要轉換為 GPU 可以處理的東西,這個東西被稱為 texturesprite ?
sprite 是 pixi 的物件,我們可以控制它的大小、位置...等,圖片都要轉為 sprite 的形式,才能添加到舞台。步驟
Texture.from() 將圖片轉為 textureSprite() 將 texture 轉為 sprite// 1.轉為 texture
const carTexture = PIXI.Texture.from('./src/images/car.svg');
// 2.再轉為 sprite
const car = new PIXI.Sprite(carTexture);
// 設置位置、寬高
car.position.set(100, 200);
car.width = 50;
car.height = 25;
// 3.加到舞台
app.stage.addChild(car);Containercontainer 裡變成一組,再加到舞台上。Container() 創建 containercontainer 及裡面物件的的大小、位置。container 裡面物件的位置是相對於 container (可以想像成:container 是 css 中的 position: relative,而裡面物件是 position: absolute 的概念)// 創建 container
const container = new PIXI.Container();
// 圖片 sprite
const texture = PIXI.Texture.from('./src/images/banana.svg');
const banana = new PIXI.Sprite(texture);
// 創建文字
const myText = new PIXI.Text('Banana!!');
// 將 sprite, 文字放入 container
container.addChild(banana);
container.addChild(myText);
// 調整位置
container.position.set(100, 100);
myText.position.set(10, 50)
// 將 container 加到舞台
app.stage.addChild(container);Ticker 做動態效果ticker 來創建循環函數ticker 有一個 delta 參數,因使用者裝置的幀數不同,動畫效果會有差異,要用 delta 來修正。先畫一個方形
// 方形
const rectangle = new PIXI.Graphics();
rectangle
.beginFill(0xffaaff) // 顏色
.drawRect(200, 200, 100, 100) // 位置,大小
.endFill()
app.stage.addChild(rectangle);用ticker讓方形移動
ticker.add() 方法來製造動態ticker.remove() 來移除動態// 方形移動function
const move = (delta) => {
// x座標加1 (往右移)
rectangle.x += 1 * delta;
}
// 開始動態
app.ticker.add(move);
// 停止
app.ticker.remove(move);Container, Graphics, Text, Sprite ... 等)都是可以互動的,我們可以用 eventMode = 'dynamic' 來將他們設定為可互動,並綁定事件。先畫一個方形
const rectangle = new PIXI.Graphics();
rectangle
.beginFill(0xaaffaa) // 顏色
.drawRect(300, 400, 100, 100) // 位置,大小
.endFill()
app.stage.addChild(rectangle);寫好一個往右移動的function
function moveRight () {
rectangle.x += 10;
}設定互動
// 設為可互動的
rectangle.eventMode = 'dynamic';
// hover時鼠標為pointer
rectangle.cursor = 'pointer';綁定事件
// 綁定點擊事件
rectangle.on('pointerdown', moveRight);
// 綁定鍵盤事件
window.addEventListener("keydown", (e) => {
const { code } = e;
// 按空白鍵時,往右移
if (code === 'Space') {
moveRight();
}
});AssetAsset 來載入需要的素材,如 json 或是圖片步驟
Assets 來載入圖片,它會回傳一個 promisetexturetexture 轉成 sprite// 1.載入圖片
const texturePromise = PIXI.Assets.load('./src/images/car.png');
// 2.當 promise resolve 時,回傳 texture
texturePromise.then((texture) => {
// 3.將 texture 轉為 sprite
const car = PIXI.Sprite.from(texture);
// 設置位置、寬高
car.position.set(100, 200);
car.width = 50;
car.height = 25;
// 4.加到舞台
app.stage.addChild(car);
});texture,再轉為 sprite,但做遊戲通常會有很多張圖片,一張一張載入不僅不方便,還會影響性能。
我們用下面壽司圖片來做練習 兩個壽司圖案寬高都是96px
![]() | ![]() |
|---|
// 載入壽司圖片
const texturePromise = PIXI.Assets.load('./src/images/sushi.png');
texturePromise.then((texture) => {
// 創建長方形來裁切
// PIXI.Rectangle(裁切的起點x, 裁切的起點y, 寬, 高)
const rect = new PIXI.Rectangle(0, 0, 96, 96);
texture.frame = rect;
// 將 texture 轉為 sprite
const sushi = PIXI.Sprite.from(texture);
// 設置位置
sushi.position.set(300, 200);
// 加到舞台
app.stage.addChild(sushi);
});這樣的結果就會得到上面那個壽司,若想要裁出下面的壽司,要改變裁切的位置。 如下:
const rect = new PIXI.Rectangle(0, 96, 96, 96);我們可以用一些工具來產生 JSON sprite sheet,它會把好幾個圖片集合起來,產出一張 png,和一個 json 檔,這個 json 檔會包含各圖片的大小位置等資訊。
以下的壽司圖片和 json 就是線上工具產生出來的。
壽司圖片

壽司 json 檔
可以看到 json 檔產出時,它自動把上面那張壽司的檔名叫 sushi0.png,下面那張壽司叫 sushi1.png。
{
"frames": {
"sushi0.png": {
"frame": {
"x": 0,
"y": 0,
"w": 96,
"h": 96
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 96,
"h": 96
},
"sourceSize": {
"w": 96,
"h": 96
}
},
"sushi1.png": {
"frame": {
"x": 0,
"y": 96,
"w": 96,
"h": 96
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 96,
"h": 96
},
"sourceSize": {
"w": 96,
"h": 96
}
}
},
"meta": {
"app": "https://github.com/piskelapp/piskel/",
"version": "1.0",
"image": "sushi.png",
"format": "RGBA8888",
"size": {
"w": 96,
"h": 192
}
}
}練習:
用 json 的方式來產生 sprite
// 載入 json
const promise = PIXI.Assets.load('./src/images/sushi.json');
promise.then(() => {
// 轉為 texture
const sushi0Texture = PIXI.Texture.from('sushi0.png');
const sushi1Texture = PIXI.Texture.from('sushi1.png');
// 轉為 sprite
const sushi0 = PIXI.Sprite.from(sushi0Texture);
const sushi1 = PIXI.Sprite.from(sushi1Texture);
// 加到舞台
app.stage.addChild(sushi0, sushi1)
})AnimatedSprite 來製作 sprite 動畫AnimatedSprite 來作

import app from "./index.js";
const promise = PIXI.Assets.load('./src/images/sushi.json');
promise.then(() => {
// 創建一個 array 來存放 texture
const sushiTextureArray = [];
for (let i = 0; i < 2; i++) {
// 轉為 texture 並放入 array
sushiTextureArray.push(PIXI.Texture.from(`sushi${i}.png`));
}
// 轉為 AnimatedSprite
const sushi = new PIXI.AnimatedSprite(sushiTextureArray);
// 設置位置, 動畫速度
sushi.position.set(500, 300);
sushi.animationSpeed = 0.05;
// 動畫開始
sushi.play();
// 加到舞台
app.stage.addChild(sushi)
})