用PIXI.JS製作左右橫移小遊戲

Heko
UniMarket
Published in
6 min readDec 26, 2022

我們之前做過了橫向卷軸遊戲背景,也做過了使用SpriteShee做連續動圖,現在,我們來加上鍵盤操作來控制場景與角色吧!

首先,創建一個畫布,並把畫布背景設置成天藍色:

let app = new PIXI.Application({
width: 680,
height: 400,
backgroundColor: 0x78e2ff // 把背景設置成藍色
});

// 把畫布添加到bady上
document.body.appendChild(app.view);

接著依然使用 PIXI.Loader 來載入 SpriteSheet 資源與背景圖片,並準備好SpriteSheet圖片:

let loader = new PIXI.Loader();
loader.baseUrl = 'images'; // 引入元素的路徑
loader
.add('bg_20221226_1.png')
.add('bg_20221226_2.png')
.add('sheet.json')
.load(()=> {
// 之後的code都放在這裡
});
左右移動Sprite Sheet素材
前景地板素材
後景草叢素材

還記得怎麼製作橫向卷軸遊戲背景嗎?

background_1 = new PIXI.TilingSprite(
PIXI.Texture.from('bg_20221226_1.png'), // 放入的Texture
app.screen.width, // 圖片的寬
app.screen.height // 圖片的高
);

background_2 = new PIXI.TilingSprite(
PIXI.Texture.from('bg_20221226_2.png'), // 放入的Texture
app.screen.width, // 圖片的寬
app.screen.height // 圖片的高
);

// 設定前景的位置
background_1.x = 0;
background_1.y = 0;

// 設定後景的位置
background_2.x = 0;
background_2.y = 0;

接著跟之前使用PIXI.AnimatedSprite一樣,製作貼圖格式的陣列並創建一個名為amin 的 AnimatedSprite使用剛才整理好的貼圖格式陣列作為它的紋理,不過這次我們需要做兩份貼圖格式陣列,分別是向左移動與向右移動:

let rightTextureArray= []; // 向右移動貼圖格式的陣列
let leftTextureArray= []; // 向左移動貼圖格式的陣列

for (let i = 1; i < 4; i++) {
let mytexture_1 = PIXI.Texture.from('anim_'+i+'.png');
let mytexture_2 = PIXI.Texture.from('anim_'+(i+3)+'.png');
rightTextureArray.push(mytexture_1);
leftTextureArray.push(mytexture_2);
}

let anim = new PIXI.AnimatedSprite(rightTextureArray); // 創建一個動畫 sprite 預設向右

老樣子,定義連續動畫的尺寸、位置以及播放速度:

// 設置動畫的尺寸
anim.width = 100;
anim.height = 100;

// 設置動畫的中心點置中
anim.anchor.set(0.5)

// 設置動畫的起始位置
anim.x = 290;
anim.y = 248;

// 設置動畫的播放速度
anim.animationSpeed = 0.3;

這次我們要一起把角色連著橫向背景添加到舞台上,注意前後位置,越後面添加到舞台上的物件層級越高:

// 將動畫添加到舞台上
app.stage.addChild(background_2, background_1, anim);

記得綁定鍵盤事件,這邊在keyup時使用 gotoAndStop 可以讓鍵盤彈起時停止撥放連續動圖並回到動圖的第n張:

let keys = []; // keys陣列
let bgSpeed = 0; // 移動的速度

window.addEventListener( "keydown", keysDown);
window.addEventListener("keyup", keysUp);

function keysDown(e){
keys[e.keyCode] = true;
}

function keysUp(e){
bgSpeed = 0;
anim.gotoAndStop(0); //停止撥放動畫並回到陣列第一張
keys[e.keyCode] = false;
}

最後記得在ticker中判斷方向按鈕及更新移動的速度:

app.ticker.add(delta => {
background_1.tilePosition.x -= bgSpeed;
background_2.tilePosition.x -= bgSpeed / 2;
if(keys[37]) { // left
if(!anim.playing) {
anim.textures = leftTextureArray;
anim.play(); // 移動時播放動畫
}
bgSpeed = -5;
}

if(keys[39]) { // right
if(!anim.playing) {
anim.textures = rightTextureArray;
anim.play();
}
bgSpeed = 5;
}
});

這邊特別提醒記得判斷動圖的播放狀態(anim.playing),當不在播放連續動圖時才去更換貼圖格式的陣列,我當時可是卡在這邊很久很久,想說怎麼向左向右移動貼圖會卡住不更換,真的很重要!

最後就可以得到一個具有操控性的作品啦!

--

--