什么是pixi.js
Pixi.js使用WebGL,是一個(gè)超快的HTML5 2D渲染引擎。作為一個(gè)Javascript的2D渲染器,Pixi.js的目標(biāo)是提供一個(gè)快速的、輕量級(jí)而且是兼任所有設(shè)備的2D庫(kù)。提供無(wú)縫 Canvas 回退,支持主流瀏覽器,包括桌面和移動(dòng)。 Pixi渲染器可以開(kāi)發(fā)者享受到硬件加速,但并不需要了解WebGL。
如何引入pixi.js
1.安裝模塊
代碼中引入:import * as PIXI from 'pixi.js';
2.cdn
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.1/pixi.min.js"></script>
創(chuàng)建pixi實(shí)例完整流程
1.創(chuàng)建一個(gè)應(yīng)用(application)(包含舞臺(tái)stage)
2.加載資源(loader)
3.創(chuàng)建游戲場(chǎng)景
4.將場(chǎng)景插入舞臺(tái)(addchild)
5.把畫(huà)布插入dom(append)
6.創(chuàng)建精靈(sprite)
7.把精靈加入畫(huà)布(addchild)
8.刷新舞臺(tái)(ticker)
9.游戲結(jié)束,銷(xiāo)毀應(yīng)用(destroy)
1.創(chuàng)建應(yīng)用
let gameApp = new PIXI.Application({
width: xxxx,
height: xxxx,
antialiasing: true, // 抗鋸齒
transparent: false, // 背景透明
resolution: 2 // 渲染倍數(shù),避免模糊
});
2.加載資源
let loader = new PIXI.Loader();
loader
.add('bg', 'img/bg.jpg')
.....
.load((loader, resources) => {
// 加載完畢回調(diào)
setUp(); //執(zhí)行創(chuàng)建精靈等操作
});
3/4.創(chuàng)建游戲場(chǎng)景并插入舞臺(tái)
let gameScene = new PIXI.Container();
gameScene.width = xxx;
gameScene.height = xxx;
gameApp.stage.addchild(gameScene);
5.把畫(huà)布插入dom
document.getElementById('xxx').appendChild(gameApp.view);
6.創(chuàng)建精靈并插入場(chǎng)景
首先,為了方便的設(shè)定精靈寬高,聲明兩個(gè)方法
function getWidth (precent) {
let w = document.body.clientWidth > 720 ? 720 : document.body.clientWidth;
return (precent / 50) * w / 2;
}
function getHeight (precent) {
let h = document.body.clientHeight;
return (precent / 50) * h / 2;
}
1.背景
let bg = new PIXI.Sprite(resources.bg.texture);
bg.width = xxx;
bg.height = xxx;
bg.x = xxx;
bg.y = xxx;
gameScene.addchild(bg)
2.飛機(jī)
let plane = new PIXI.Sprite(resources.plane.texture);
plane.width = xxx;
plane.height = xxx;
plane.x = xxx;
plane.y = xxx;
gameScene.addchild(plane)
給飛機(jī)添加拖動(dòng)事件,讓飛機(jī)跟著手指移動(dòng)。
給飛機(jī)添加射擊事件,在ticker中調(diào)用,使飛機(jī)一直發(fā)射子彈
3.障礙物
let obstacle = new PIXI.Sprite(resources.obstacle.texture);
obstacle.width = xxx;
obstacle.height = xxx;
obstacle.x = xxx;
obstacle.y = xxx;
gameScene.addchild(obstacle)
這種只是最基礎(chǔ)的做法,如果有稍微多一點(diǎn)的需求,例如,碰撞檢測(cè)的區(qū)域,和紋理圖大小不一樣,就需要
將障礙物紋理、碰撞區(qū)域、爆炸動(dòng)畫(huà),都放入一個(gè)container內(nèi),碰撞區(qū)域push進(jìn)入obstacles數(shù)組,去和子彈飛機(jī)做碰撞檢測(cè)
障礙物的飛行,使用tween.js,初始化時(shí)候,設(shè)置好起點(diǎn)終點(diǎn),在ticker中update就可以像目的地移動(dòng)
let container = new PIXI.Container();
// 圖案
let obstacle = new PIXI.Sprite(texture.obstacle.texture);
obstacle.name = 'obstacle';
obstacle.width = getWidth(30);
obstacle.height = getWidth(30);
obstacle.x = 0;
obstacle.y = 0;
obstacle.anchor.set(0.5, 0.5);
// 碰撞區(qū)域
let circle = new PIXI.Sprite();
circle.width = obstacle.width * 0.5;
circle.height = circle.width;
circle.name = 'circle';
circle.circular = true;
circle.x = -circle.width*0.5;
circle.y = -circle.height*0.5;
container.addChild(circle);
// 文字
let text = new PIXI.Text('哈哈', {
fontSize: obstacle.width * 0.13,
fill: '#fff'
});
text.x = - text.width*0.5;
text.y = - text.height*0.5;
container.addChild(text);
// 爆炸效果
let fireClip = [
];
for (let i = 0; i <= 23; i++) {
fireClip.push(texture.boom.textures['boom' + i + '.png']);
}
let boom = new PIXI.AnimatedSprite(fireClip);
boom.width = obstacle.width * 2.5;
boom.height = obstacle.height * 2.5;
boom.x = -boom.width * 0.5;
boom.y = -boom.height * 0.5;
boom.name = 'boom';
boom.loop = false;
container.addChild(boom);
container.addChild(obstacle);
container.addChild(circle);
container.x = getWidth(Math.random()*100);
container.y = -obstacle.height;
// 位移設(shè)定
let tween = new TWEEN.Tween(container)
.to(
{
x: getWidth(Math.random() * 100),
y: getHeight(100) + obstacle.height,
},
obstacleTime // tween持續(xù)時(shí)間
)
.easing(TWEEN.Easing.Linear.None)
.onComplete(function () {
// 到底
container.destroy();
});
tween.start();
// 旋轉(zhuǎn)設(shè)定
let tween2 = new TWEEN.Tween(obstacle)
.to(
{
rotation: -20
},
obstacleTime // tween持續(xù)時(shí)間
)
.easing(TWEEN.Easing.Linear.None)
.onComplete(function () {
});
tween2.start();
// 插入場(chǎng)景
container.tween = tween;
obstacles.push(circle);
tweens.push(tween);
gameScene.addChild(container);
7.更新舞臺(tái)
創(chuàng)建完游戲內(nèi)所有元素后,開(kāi)啟pixi內(nèi)置定時(shí)器ticker
app.ticker.add(function () {
return gameLoop();
});
在ticker中更新需要調(diào)用的事件,來(lái)實(shí)現(xiàn)游戲的動(dòng)態(tài)效果
function gameLoop(){
// 生成子彈
plane.shut(gameScene, bullets);
// 生成障礙物
createobstacle(gameScene, texture, obstacles, TWEEN, tweens);
// 子彈邏輯處理
bulletsEvents();
// 障礙物邏輯處理
obstaclesEvents();
}
8.子彈飛機(jī)障礙物的碰撞邏輯(重點(diǎn))
function bulletsEvents(){
for(let i = 0; i < bullets.length;){
let hit = false;
for(let o = 0; o < obstacles.length; ) {
// 子彈與障礙物碰撞檢測(cè)
if(hitTest(obstacles[o], bullets[i])) {
hit = true;
// 移除障礙物
obstaclesBoom(o)
continue;
}else if(hitTest(obstacles[o], plane)){
// 飛機(jī)與障礙物碰撞檢測(cè)
let _obstacle = obstacles.splice(o,1)[0];
_obstacle.destroy();
gameOver();
continue;
}else{
o++
}
}
// 根據(jù)碰撞狀態(tài)做處理
if(hit){
// 如果碰撞了
// 移除當(dāng)前子彈
let _bullet = bullets.splice(i,1)[0];
_bullet.destroy();
// 加分
score ++;
scorePanel.text = '得分:' + score;
}else{
// 如果子彈飛出屏幕,則移除;如果沒(méi)有,Y軸位移
if(bullets[i].y < -bullets[i].height){
let _bullet = bullets.splice(i,1)[0];
_bullet.destroy();
}else{
bullets[i].y -= 10;
i++
}
}
}
}
首先遍歷子彈池,內(nèi)部遍歷所有障礙物,通過(guò)hitTest做碰撞檢測(cè)
如果子彈和障礙物碰撞,子彈消失,障礙物消失/爆炸,得分+1;
如果飛機(jī)和障礙物碰撞,障礙物消失/爆炸,游戲結(jié)束
如果都沒(méi)有,檢測(cè)下一個(gè)子彈
如果子彈自下而上,飛出屏幕,則子彈移除,否則影響性能
==============================================================
碰撞檢測(cè)代碼,bump通過(guò)cdn引入
hitTestCircleRectangle只能用于圓形和矩形的碰撞,更多方式查看PIXI官方文檔
// 子彈詞條碰撞
import * as PIXI from 'pixi.js';
export function hitTest (r1, r2) {
let b = new Bump(PIXI);
if (b.hitTestCircleRectangle(r1, r2, true) !== false) {
return true;
} else {
return false;
}
}
9.障礙物爆炸邏輯
碰撞之后,根據(jù)parent屬性,找到container,進(jìn)而找到內(nèi)部的爆炸動(dòng)畫(huà),執(zhí)行play()方法;
爆炸的同時(shí),使紋理隱藏,形成視覺(jué)上的碰撞爆炸效果
部分代碼:
function obstaclesBoom(o){
let container = obstacles[o].parent;
let _obstacle = obstacles.splice(o,1)[0];
_obstacle.destroy();
container.children[1].play();
container.children[0].visible = false;
container.children[2].visible = false;
}
總結(jié)
只是隨便講一下做法的邏輯,具體代碼已上傳github,地址:https://github.com/huangXin1538/pixi-aircrift-wars