PixiJS V5 教學 (29) - treasureHunter (寶藏獵人)

前言

接下來我們差不多要來實作 treasureHunter (寶藏獵人) 的部分,所以這邊會慢慢拆解組合出一個簡易的寶藏獵人。

起手式

起手式不外乎就是建立 PIXI 應用程式,接下來就巴拉巴拉…一大推,就完成了(被揍),反正絕大部分都是放在 JSON 中讀取,但是這邊因為要在 Codepen 上展示,所以我就調整一下將它轉換為變數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// 有點長
const frames = {
"frames": {
"blob.png": {
"frame": {
"x": 55,
"y": 2,
"w": 32,
"h": 24
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 32,
"h": 24
},
"sourceSize": {
"w": 32,
"h": 24
},
"pivot": {
"x": 0.5,
"y": 0.5
}
},
"door.png": {
"frame": {
"x": 89,
"y": 2,
"w": 32,
"h": 32
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 32,
"h": 32
},
"sourceSize": {
"w": 32,
"h": 32
},
"pivot": {
"x": 0.5,
"y": 0.5
}
},
"dungeon.png": {
"frame": {
"x": 2,
"y": 36,
"w": 512,
"h": 512
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 512,
"h": 512
},
"sourceSize": {
"w": 512,
"h": 512
},
"pivot": {
"x": 0.5,
"y": 0.5
}
},
"explorer.png": {
"frame": {
"x": 2,
"y": 2,
"w": 21,
"h": 32
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 21,
"h": 32
},
"sourceSize": {
"w": 21,
"h": 32
},
"pivot": {
"x": 0.5,
"y": 0.5
}
},
"treasure.png": {
"frame": {
"x": 25,
"y": 2,
"w": 28,
"h": 24
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 28,
"h": 24
},
"sourceSize": {
"w": 28,
"h": 24
},
"pivot": {
"x": 0.5,
"y": 0.5
}
}
},
"meta": {
"app": "http://www.codeandweb.com/texturepacker",
"version": "1.0",
"image": "https://i.imgur.com/yxmphGW.png",
"format": "RGBA8888",
"size": {
"w": 512,
"h": 512
},
"antialias": true,
"transparent": false,
"backgroundColor": "0x000000",
"scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:51ede84c7a85e4d6aeb31a6020a20858:3923663e59fb40b578d66a492a2cda2d:9995f8b4db1ac3cb75651b1542df8ee2$"
}
}

PIXI

接下來關於 PIXI 應用建立的部分就都會透過該變數去帶入相關參數,未來若我們需要調整什麼就直接透過該變數調整即可

1
2
3
4
5
6
7
8
const app = new PIXI.Application({
view: document.getElementById('main'),
width: frames.meta.size.w,
height: frames.meta.size.h,
antialias: frames.meta.antialias,
transparent: frames.meta.transparent,
backgroundColor: frames.meta.backgroundColor,
});

接下來我們會建立一個 initfunction 來初始化遊戲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const loader = new PIXI.Loader();
loader
.add('gameimg',frames.meta.image)
.load((loader, resource)=> {
init(resource);
})

function init(resource) {
for(let item in frames.frames) {
let rectangle = new PIXI.Rectangle(frames.frames[item].frame.x, frames.frames[item].frame.y, frames.frames[item].frame.w, frames.frames[item].frame.h);
let newTex = new PIXI.Texture(resource.gameimg.texture, rectangle);
const sprite = new PIXI.Sprite(newTex);
sprite.x = frames.frames[item].position.x;
sprite.y = frames.frames[item].position.y;
app.stage.addChild(sprite);
}
}

這時候你應該可以看到畫面成功出現

遊戲初始化

但是這樣其實是錯誤的,因為我們無法去控制每一個元素,所以必須針對每一個元素做調整

1
2
3
4
5
6
7
8
9
const gameStart = new PIXI.Container();
app.stage.addChild(gameStart);

function init(resource) {
const blob = new PIXI.Rectangle(frames.frames["blob.png"].frame.x, frames.frames["blob.png"].frame.y, frames.frames["blob.png"].frame.w, frames.frames["blob.png"].frame.h);
let blobTex = new PIXI.Texture(resource.gameimg.texture, blob);
const blobSprite = new PIXI.Sprite(blobTex);
gameStart.addChild(blobSprite);
}

由於這樣有點麻煩,所以我就建立一個 new PIXI.Rectanglenew PIXI.Texture 以及 new PIXI.Sprite 處理相關的的 function

1
2
3
4
5
6
function gameSprite(item, resource) {
const pixiRectangle = new PIXI.Rectangle(frames.frames[item].frame.x, frames.frames[item].frame.y, frames.frames[item].frame.w, frames.frames[item].frame.h);
let newTex = new PIXI.Texture(resource.gameimg.texture, pixiRectangle);
const sprite = new PIXI.Sprite(newTex);
return sprite;
}

這樣我們就可以使用非常簡易的使用加載相關遊戲素材,記得素材相關變數要設置在全域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const gameStart = new PIXI.Container();
app.stage.addChild(gameStart);

function gameSprite(item, resource) {
const pixiRectangle = new PIXI.Rectangle(frames.frames[item].frame.x, frames.frames[item].frame.y, frames.frames[item].frame.w, frames.frames[item].frame.h);
let newTex = new PIXI.Texture(resource.gameimg.texture, pixiRectangle);
const sprite = new PIXI.Sprite(newTex);
return sprite;
}

let dungeon, blob, treasure, door, explorer;

function init(resource) {
// 載入地牢
dungeon = gameSprite('dungeon.png', resource);
gameStart.addChild(dungeon);

// 載入怪物
blob = gameSprite('blob.png', resource);
gameStart.addChild(blob);

// 寶箱
treasure = gameSprite('treasure.png', resource);
gameStart.addChild(treasure);

// 逃出門
door = gameSprite('door.png', resource);
gameStart.addChild(door);

// 玩家
explorer = gameSprite('explorer.png', resource);
gameStart.addChild(explorer);
}

最後再把相關函數 contain 加入就差不多了

1
2
contain(explorer, {x: 28, y: 10, width: 488, height: 480})
contain(blob, {x: 28, y: 10, width: 488, height: 480})

參考文獻