PixiJS是一個(gè)2D渲染引擎,能自動(dòng)偵測(cè)并使用WebGL或Canvas稽寒。
PixiJS使用JavaScript或HTML5基礎(chǔ)來(lái)顯示媒體扮碧,創(chuàng)建動(dòng)畫或管理交互式圖像,從而制作游戲或應(yīng)用。
PixiJS適合制作游戲但并非是游戲引擎慎王,其核心本質(zhì)是盡可能快速有效地在屏幕上移動(dòng)物體蚓土。
PixiJS作為JavaScript的2D渲染器,目標(biāo)是提供快速輕量且兼容所有設(shè)備的2D庫(kù)赖淤。提供無(wú)縫Canvas回退蜀漆、支持主流瀏覽器,包括桌面和移動(dòng)設(shè)備咱旱。
PIXI只做三件事
- Loading and displaying of assets
- interactivity
- game loop
安裝測(cè)試
$ npm i pixi.js
引入
import * as PIXI from "pixi.js";
- 開(kāi)發(fā)工具 Vistual Code
- Web服務(wù)器插件 Live Server
- Chrome調(diào)試工具 PixiJS devtools
測(cè)試
判斷當(dāng)前瀏覽器渲染引擎類型
$ vim index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcss.com/pixi.js/5.2.1/pixi.min.js"></script>
</head>
<body>
<script>
//判斷瀏覽器渲染引擎
const type = PIXI.utils.isWebGLSupported() ? "WebGL" : "canvas";
//console.log(type);//WebGL
PIXI.utils.sayHello(type);//PixiJS 5.2.1 - WebGL - http://www.pixijs.com/
</script>
</body>
</html>
判斷代碼
//判斷瀏覽器渲染引擎
const type = PIXI.utils.isWebGLSupported() ? "WebGL" : "canvas";
//console.log(type);//WebGL
PIXI.utils.sayHello(type);//PixiJS 5.2.1 - WebGL - http://www.pixijs.com/
概念
使用PIXI的基本流程通常分為以下幾步
- 創(chuàng)建舞臺(tái)
- 創(chuàng)建畫布
- 將畫布添加到DOM
- 創(chuàng)建精靈
- 將精靈添加到畫布
- 將畫布添加舞臺(tái)
- 定時(shí)刷新舞臺(tái)
PIXI常用模塊包括
- Application 應(yīng)用
- Container 容器
- Stage 舞臺(tái)
- Renderer 渲染器
- Ticker 計(jì)時(shí)器
- Loader 加載器
舞臺(tái)stage
- 所有需要渲染的對(duì)象都必須添加到舞臺(tái)中才能被顯示出來(lái)
- 舞臺(tái)處于整個(gè)樹(shù)形展示結(jié)構(gòu)的對(duì)底層可理解為背景
畫布renderer
畫布是指使用WebGL或Canvas繪圖引擎進(jìn)行渲染的一塊區(qū)域
紋理texture
紋理可理解為承載圖片的結(jié)構(gòu)确丢,紋理本身不能直接用于顯示,需要通過(guò)精靈才能顯示莽龟,類似DOM中的臨時(shí)碎片蠕嫁。
精靈sprite
精靈是可以直接用于舞臺(tái)顯示的對(duì)象锨天,可理解為DOM中的元素毯盈。精靈可直接食用圖片創(chuàng)建,也可以先創(chuàng)建紋理在使用紋理創(chuàng)建精靈病袄。
事件event
事件用于交互
應(yīng)用PIXI.Application
PIXI擁有一個(gè)Pixi應(yīng)用對(duì)象PIXI.Application
搂赋,可自動(dòng)創(chuàng)建一個(gè)canvas
標(biāo)簽,用于計(jì)算圖片在其中的顯示益缠。PIXI.Application
會(huì)自動(dòng)創(chuàng)建渲染器脑奠、計(jì)時(shí)器和根容器。
const app = new PIXI.Application(options);
PIXI.Application建立的同時(shí)會(huì)自動(dòng)建立render幅慌、ticker宋欺、root container。
const app = new PIXI.Application({width:400, height:300, view:document.querySelector("canvas")});
- app.renderer 渲染器胰伍,優(yōu)先使用WebGL渲染若不支持則使用Canvas渲染齿诞。
- app.ticker 渲染的更新頻率,計(jì)時(shí)器骂租。
- app.stage 根容器
例如:創(chuàng)建可顯示圖片的矩形顯示區(qū)域
//創(chuàng)建一個(gè)Pixi應(yīng)用
const app = new PIXI.Application({width:400, height:300});
//pixi自動(dòng)創(chuàng)建canvas標(biāo)簽并添加到document文檔中
document.body.appendChild(app.view);
自動(dòng)創(chuàng)建canvas
標(biāo)簽
<canvas width="400" height="300" style="touch-action: none; cursor: inherit;"></canvas>
使用PIXI.Application
創(chuàng)建的pixi應(yīng)用計(jì)算并選擇渲染引擎祷杈,這取決于瀏覽器自身所支持的渲染引擎的類型。創(chuàng)建pixi應(yīng)用時(shí)需傳入options選項(xiàng)對(duì)象參數(shù)渗饮,options對(duì)象中可設(shè)置pixi應(yīng)用的寬高但汞、透明等屬性。若options對(duì)象中未設(shè)置view屬性互站,則會(huì)自動(dòng)創(chuàng)建一個(gè)canvas元素私蕾,創(chuàng)建出來(lái)的canvas元素就在pixi應(yīng)用的view屬性中。也可以使用view屬性手動(dòng)指定胡桃。
const app = new PIXI.Application({width:400, height:300, view:document.querySelector("canvas")});
document.body.appendChild(app.view);
選項(xiàng) | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
width | number | 800 | 渲染器視寬度 |
height | number | 600 | 渲染視圖高度 |
view | HTMLCanvasElement | - | 使用canvas作為視圖 |
transparent | boolean | false | 視圖是否透明 |
resolution | number | 1 | 分辨率踩叭,渲染器設(shè)備像素比,R屏默認(rèn)為2. |
antialias | boolean | false | 是否平滑抗鋸齒标捺,取消字體平滑懊纳,抗混疊揉抵。 |
forceCanvas | boolean | false | 是否強(qiáng)制使用canvas渲染模式,默認(rèn)使用WebGL嗤疯。 |
- antialias可使字體的邊界和集合界面更為圓滑冤今,WebGL的anti-aliasing在所有平臺(tái)都不可用。
- transparent會(huì)將整個(gè)canvas標(biāo)簽的透明度進(jìn)行設(shè)置
- resolution會(huì)使pixi在不同分辨率和像素密度的設(shè)備上顯示正常
- pixi的canvas畫布對(duì)象將會(huì)默認(rèn)選擇WebGL引擎渲染模式茂缚,若需使用canvas引擎繪制可設(shè)置 forceCanvas饮怯。
適配分辨率
pixi會(huì)自動(dòng)調(diào)整像素密度以匹配運(yùn)行內(nèi)容的設(shè)備的分辨率,開(kāi)發(fā)人員所要做的是為高分辨率和低分辨率提供不同的圖像靖诗。pixi將幫助你根據(jù)當(dāng)前的設(shè)備像素比devicePixelRatio
選擇對(duì)應(yīng)的圖像芦拿。當(dāng)創(chuàng)建高分辨率圖像時(shí),可以將@2x
添加到圖像文件名稱后悔耘,以說(shuō)明圖像是支持高分辨率的屏幕讲岁,例如Retina屏幕。
獲取當(dāng)前設(shè)備設(shè)備像素比衬以,dpr是一個(gè)描述設(shè)備像素比的數(shù)字缓艳,由運(yùn)行應(yīng)用程序的設(shè)備自動(dòng)提供,其中1表示為標(biāo)準(zhǔn)分辨率看峻,2表示高密度分辨率阶淘,3表示超高密度顯示器。
const dpr= window.devicePixelRatio;
const width = window.innerWidth;
const height = window.innerHeight;
const resolution = window.devicePixelRatio;
let app = new Application({width:width, height:height, resolution:resolution, transparent:true, antialias:true});
document.body.appendChild(app.view);
pixi應(yīng)用對(duì)象的成員
成員 | 類型 | 描述 |
---|---|---|
app.loader | PIXI.Loader | 加載器實(shí)例用于資源加載互妓,用于加載靜態(tài)資源溪窒。 |
app.renderer | PIXI.Renderer|PIXI.CanvasRenderer | WebGL渲染器,可使用CanvasRenderer冯勉。 |
app.resizeTo | Window|HTMLElement | 元素或窗口尺寸更改 |
app.screen | PIXI.Rentangle | 渲染器的屏幕矩形對(duì)象 |
app.stage | PIXI.Container | 根顯示容器澈蚌,舞臺(tái),pixi創(chuàng)建的根容器珠闰。游戲中的精靈或容器都要添加到舞臺(tái)上才能顯示惜浅。 |
app.ticker | PIXI.Ticker | 計(jì)時(shí)器,可理解為每次渲染一幀前執(zhí)行伏嗜。 |
app.view | HTMLCanvasElement | 渲染器的canvas元素坛悉,pixi創(chuàng)建的DOM元素即用于渲染游戲的canvas。 |
修改canvas標(biāo)簽背景色
app.renderer.backgroundColor = 0xff0000;
獲取畫布的寬度和高度
console.log(app.renderer.view.width);//400
console.log(app.renderer.view.height);//300
重新設(shè)置畫布的canvas寬高尺寸
app.renderer.autoResize = true;
app.renderer.resize(512, 512);
console.log(app.renderer.view.width);//512
console.log(app.renderer.view.height);//512
設(shè)置canvas占滿整個(gè)窗口承绸,需配置CSS重置padding和margin為0裸影。
*{padding:0;margin:0;}
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
渲染器app.renderer
獲取當(dāng)前應(yīng)用渲染器的類型
const rendererType = app.renderer.type;
const rendererType = PIXI.RENDERER_TYPE;
渲染模式 | 取值 |
---|---|
UNKNOWN | 0 |
WEBGL | 1 |
CANVAS | 2 |
渲染器選項(xiàng)參數(shù)
名稱 | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
width | number | 800 | 屏幕寬度 |
height | number | 600 | 屏幕長(zhǎng)度 |
view | HTMLCanvasElement | - | canvas渲染模式需使用的視圖與選項(xiàng) |
transparent | boolean | false | 渲染器視圖是否透明 |
容器 PIXI.Container()
容器是用來(lái)轉(zhuǎn)載多個(gè)顯示對(duì)象的,創(chuàng)建的Pixi應(yīng)用的stage屬性本質(zhì)上就是一個(gè)容器對(duì)象军熏,stage對(duì)象被當(dāng)作根容器使用轩猩,它將包裹所有想用Pixi顯示的元素。
let container = new PIXI.Container();
container.addChild(sprite);
自定義的Container通常用來(lái)做分組使用,分組的好處在于修改Container的屬性均践,位于其中的子節(jié)點(diǎn)都會(huì)受到影響晤锹。
常見(jiàn)的作法是創(chuàng)建一個(gè)最頂層的rootContainer,之后所有的內(nèi)容都添加到rootContainer中彤委,rootContainer作為頂級(jí)元素可進(jìn)行縮放來(lái)適配不同的分辨率鞭铆。
Container與Sprite有何異同
- Container表示顯示對(duì)象的集合,是作為其他對(duì)象的容器焦影,是所有顯示對(duì)象的基類车遂。
- Container是用來(lái)轉(zhuǎn)載多個(gè)顯示對(duì)象,也包括自身Container斯辰。
- Sprite表示基于紋理對(duì)象存在舶担,是能將紋理顯示到舞臺(tái)的顯示對(duì)象。
- Container和Sprite的繼承關(guān)系是PIXI.Sprite繼承自PIXI.Container彬呻。
Sprite是繼承自Container的衣陶,Container又是繼承自什么對(duì)象呢?
Container繼承自DisplayObject废岂,DisplayObject是最基本的顯示對(duì)象祖搓。
PIXI.Sprite -> PIXI.Container -> PIXI.DisplayObject
Sprite和Container共享DisplayObject的函數(shù)和方法
顯示對(duì)象 PIXI.DisplayObject
- DisplayObject是所有渲染到屏幕上的對(duì)象的基類
- DisplayObject是一個(gè)抽象類
成員屬性 | 類型 | 描述 |
---|---|---|
x | number | X軸坐標(biāo)值 |
y | number | Y軸坐標(biāo)值 |
position | PIXI.Point / PIXI.ObservablePoint | 位移坐標(biāo) |
alpha | number | 透明度 |
visible | boolean | 顯示隱藏 |
rotation | number | 旋轉(zhuǎn)角度 |
angle | number | 旋轉(zhuǎn)角度 |
scale | PIXI.Point / PIXI.ObservablePoint | 縮放值 |
skew | PIXI.ObsevablePoint | 斜切值 |
transform | PIXI.TransformBase | 矩陣對(duì)象 |
cacheAsBitmap | boolean | 是否將顯示對(duì)象轉(zhuǎn)換為位圖 |
renderable | boolean | 是否能被渲染到舞臺(tái) |
舞臺(tái)app.stage
創(chuàng)建pixi應(yīng)用對(duì)象并添加到document中后就有了一個(gè)畫布狱意,要在畫布上顯示東西就必須加入到一個(gè)稱為舞臺(tái)的pixi對(duì)象pixi.stage
湖苞。
app.stage是一個(gè)Container的實(shí)例,作為最底層的舞臺(tái)详囤,所有需要渲染的圖形都應(yīng)放到stage的內(nèi)部财骨。
pixi.stage
舞臺(tái)是一個(gè)pixi容器對(duì)象,可理解為將放入的東西分組并存儲(chǔ)的空箱子藏姐。stage舞臺(tái)對(duì)象是在場(chǎng)景總所有可見(jiàn)對(duì)象的根容器隆箩。所有放入到舞臺(tái)的東西都會(huì)被渲染到canvas中。
stage對(duì)象是Container容器羔杨,是所有Sprite精靈的根容器捌臊。
stage舞臺(tái)對(duì)象是pixi容器對(duì)象,所有的容器對(duì)象都具有相同的屬性和方法兜材。盡管stage舞臺(tái)擁有width和height屬性理澎,但不能查看畫圖窗口的大小。stage舞臺(tái)的width和height屬性僅僅告訴放入東西占用的大小曙寡。
舞臺(tái)內(nèi)科放入什么東西呢糠爬?是稱作精靈的特殊圖像對(duì)象。精靈是能夠使用代碼控制的圖像举庶,可以控制它的位置执隧、大小等屬性來(lái)產(chǎn)生交互和動(dòng)畫。
坐標(biāo)
- 絕對(duì)坐標(biāo)
global
是以舞臺(tái)stage
為基準(zhǔn)的坐標(biāo)系,精靈相對(duì)于舞臺(tái)的位置和方向镀琉。 - 相對(duì)坐標(biāo)
local
是以舞臺(tái)stage
中某個(gè)容器container
為基準(zhǔn)的坐標(biāo)系峦嗤,一般是精靈的父容器。
Pixi提供了兩個(gè)函數(shù)用于坐標(biāo)變換
-
toGlobal
相對(duì)坐標(biāo)轉(zhuǎn)換為絕對(duì)坐標(biāo) -
toLocal
絕對(duì)坐標(biāo)轉(zhuǎn)換為相對(duì)坐標(biāo)
無(wú)論是容器還是精靈的坐標(biāo)以及方向都是相對(duì)于父容器的坐標(biāo)系的屋摔,坐標(biāo)原點(diǎn)默認(rèn)是容器的左上角寻仗,可改變?nèi)萜鞯淖鴺?biāo)原點(diǎn)anchor
。
加載 PIXI.Loader
將圖片加載到紋理緩存凡壤,因?yàn)閜ixi使用WebGL和GPU渲染圖像署尤,所以圖像需轉(zhuǎn)化成GPU可以處理的格式⊙窍溃可以被GPU處理的圖像稱為紋理Texture曹体。使用精靈顯示圖片之前,需將圖片轉(zhuǎn)化成WebGL紋理硝烂,pixi使用紋理緩存存儲(chǔ)和應(yīng)用精靈所需的紋理箕别。紋理的名字是圖像的地址。
從紋理緩存中獲取圖片
PIXI.utils.TextureCache["images/cat.png"];
紋理被以WebGL兼容的格式存儲(chǔ)起來(lái)滞谢,可使Pixi渲染更加高效串稀。
例如:從紋理緩存中獲取圖片并轉(zhuǎn)化為紋理
//將圖像加載到紋理緩存
let texture = PIXI.utils.TextureCache["images/avatar.jpg"];
//使用紋理創(chuàng)建精靈
let sprite = new PIXI.Sprite(texture);
如何加載圖像并將其轉(zhuǎn)化為紋理呢?可使用pixi的Loader對(duì)象狮杨,pixi的Loader對(duì)象可加載任何種類的圖像資源母截,使用load方法加載圖像完成時(shí)可使用回調(diào)方法使用它。
const imgpath = "images/avatar.jpg";
PIXI.loader.add(imgpath).load(function(){
let texture = PIXI.loader.resources[imgpath].texture;
let sprite = new PIXI.Sprite(texture);
app.stage.addChild(sprite);
});
紋理 PIXI.Texture
PixiJS使用WebGL或Canvas渲染圖像橄教,所以圖像需要轉(zhuǎn)化成GPU能夠處理的格式清寇,可以被GPU處理的圖像被稱為紋理Texture
。比如护蝶,當(dāng)讓精靈顯示圖片之前华烟,需要將普通的圖片轉(zhuǎn)化成WebGL紋理。為了讓工作執(zhí)行的快速有效率持灰,PixiJS使用紋理緩存來(lái)存儲(chǔ)和應(yīng)用精靈所需的紋理盔夜。紋理的名稱也就是圖像的地址。
紋理存儲(chǔ)著圖像或圖像的部分信息堤魁,圖像是不能直接添加到顯示列表中喂链,必須將圖像轉(zhuǎn)化為精靈的紋理。
從圖片獲取紋理
const texture = PIXI.Texture.from(imgPath);
游戲是一種很耗資源的應(yīng)用姨涡,特別是在移動(dòng)設(shè)備中的游戲衩藤。紋理圖集(Texture Atlas)又稱為精靈表(Sprite Sheet)是將許多小的精靈圖片組合到一張大圖中。
精靈 PIXI.Sprite
PIXI的核心是Sprite涛漂,PIXI.Sprite
繼承自PIXI.Container
赏表,PIXI.Container
繼承自PIXI.DisplayObject
检诗。
Sprite對(duì)象是渲染到屏幕的所有紋理對(duì)象的基礎(chǔ),它能輕松的改變紋理瓢剿。
Sprite默認(rèn)是不會(huì)響應(yīng)點(diǎn)擊等事件的逢慌,必須需要Interactive。
pixi擁有一個(gè)sprite精靈類用來(lái)創(chuàng)建游戲精靈间狂,創(chuàng)建的方式有三種攻泼。
- 使用單圖像文件創(chuàng)建
- 使用雪碧圖來(lái)創(chuàng)建
- 從紋理圖集中創(chuàng)建
創(chuàng)建Sprite的方式分為
- 常用方式
const sprite = new PIXI.Sprite(texture?);
- 快捷方式
const sprite = PIXI.Sprite.from(source);
參數(shù)source可以是URL地址、Canvas鉴象、紋理忙菠。
- 快捷方式
const sprite = PIXI.Sprite.fromFrame(key);
參數(shù)key是JSON格式中的key或加載時(shí)定義的key。
- 快捷方式
const sprite = PIXI.Sprite.fromImage(url, crossorigin?;
例如:
const imgpath = "images/avatar.jpg";
//將圖片添加到紋理緩存
PIXI.loader.add(imgpath).load(function(){
//從紋理緩存中獲取紋理
let texture = PIXI.loader.resources[imgpath].texture;
//使用紋理創(chuàng)建精靈
let sprite = new PIXI.Sprite(texture);
//隱藏精靈
sprite.visible = false;
//將精靈添加舞臺(tái)
app.stage.addChild(sprite);
//將精靈從舞臺(tái)中刪除
app.stage.removeChild(sprite);
});
使用別名
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let Sprite = PIXI.Sprite;
//創(chuàng)建應(yīng)用
let app = new Application({width:256, height:256, resolution:1, transparent:false, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//添加圖片
const img = "images/avatar.jpg";
loader.add(img).load(function(){
let texture = resources[img].texture;
let sprite = new Sprite(texture);
app.stage.addChild(sprite);
});
監(jiān)視加載進(jìn)程
const name = "avatar";
const url = "images/avatar.jpg";
loader.add(name, url).load(function(){
let texture = resources[name].texture;
let sprite = new Sprite(texture);
app.stage.addChild(sprite);
}).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
add方法參數(shù)
add(name, url, optionObject, callbackFunction)
參數(shù) | 類型 | 描述 |
---|---|---|
name | string | 加載源文件別名 |
url | string | 源文件地址 |
options | object literal | 加載設(shè)置 |
options.crossOrigin | boolean | 源文件請(qǐng)求跨域 |
options.loadType | string | 原文加加載類型纺弊,默認(rèn)為Resource.LOAD_TYPE.XHR |
options.xhrType | string | XHR處理方式牛欢,默認(rèn)為Resource.XHR_RESPONSE_TYPE.DEFAULT |
callbackFunction | function | 加載完后執(zhí)行的回調(diào)函數(shù) |
add方法可傳入對(duì)象數(shù)組,也可使用鏈?zhǔn)郊虞d淆游。
const imgs = [
{name:"avatar", url:"images/avatar.jpg"},
{name:"person", url:"images/person.png"},
{name:"plane", url:"images/plane.bmp"},
];
loader.add(imgs).load(function(){
let texture = resources["plane"].texture;
let sprite = new Sprite(texture);
app.stage.addChild(sprite);
}).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
精靈位置
默認(rèn)精靈sprite對(duì)象保存x和y屬性用來(lái)定位
let sprite = new Sprite(texture);
sprite.x = 100;
sprite.y = 100;
sprite.position.set(10, 10);
設(shè)置精靈的寬高大小
sprite.width = 150;
sprite.height = 120;
設(shè)置精靈的縮放比例
sprite.scale.x = 0.5;
sprite.scale.y = 0.5;
sprite.scale.set(0.5, 0.5);
scale的值從0到1表示對(duì)原精靈大小的百分比傍睹,1表示100%原來(lái)大小,0.5表示50%一般大小犹菱。
設(shè)置精靈的旋轉(zhuǎn)角度
可設(shè)置精靈的rotation來(lái)設(shè)定角度來(lái)旋轉(zhuǎn)拾稳,旋轉(zhuǎn)是針對(duì)錨點(diǎn)anchor發(fā)生的,默認(rèn)在精靈的左上角腊脱,錨點(diǎn)是精靈旋轉(zhuǎn)的中心點(diǎn)访得。
sprite.rotation = 0.5;
設(shè)置紋理錨點(diǎn)anchor
sprite.anchor.x = 0.5;
sprite.anchor.y = 0.5;
錨點(diǎn)anchor取值范圍從0到1,是紋理長(zhǎng)度或?qū)挾鹊陌俜直取?/p>
設(shè)置精靈中心點(diǎn)pivot
精靈提供和anchor錨點(diǎn)類似的pivot屬性來(lái)設(shè)置精靈的原點(diǎn)虑椎,若改變pivot中心點(diǎn)的值后旋轉(zhuǎn)精靈震鹉,將會(huì)圍繞設(shè)置的原點(diǎn)來(lái)旋轉(zhuǎn)。
sprite.pivot.x = 100;
sprite.pivot.y = 100;
sprite.pivot.set(100, 100);
若精靈的尺寸為200x200捆姜,設(shè)置pivot(100, 100)后,精靈將圍繞其中心點(diǎn)旋轉(zhuǎn)迎膜。
錨點(diǎn)pivot和中心點(diǎn)pivot的區(qū)別在于
- anchor錨點(diǎn)改變了紋理的原點(diǎn)泥技,使用0到1填充。
- pivot中心點(diǎn)則精靈的原點(diǎn)磕仅,使用像素來(lái)填充珊豹。
雪碧圖SpriteSheet
雪碧圖是使用單個(gè)文件包含游戲所需的所有圖片文件,pixi中使用雪碧圖中的小圖片的方式是使用一個(gè)矩形去截取紋理緩存中的對(duì)應(yīng)位置來(lái)創(chuàng)建精靈榕订。
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let Sprite = PIXI.Sprite;
let TextureCache = PIXI.utils.TextureCache;
let Rectangle = PIXI.Rectangle;
//創(chuàng)建應(yīng)用
let app = new Application({width:256, height:256, resolution:1, transparent:false, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//添加圖片
const imgs = [
{name:"altas", url:"images/altas.png"},
];
loader.add(imgs).load(function(){
let texture = TextureCache["altas"];
let rectangle = new Rectangle(0, 0, 64, 64);
texture.frame = rectangle;
let sprite = new Sprite(texture);
sprite.position.set(150, 150);
app.stage.addChild(sprite);
}).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
Pixi內(nèi)置通用Rectangle對(duì)象PIXI.Rectangle
店茶,用來(lái)定義矩形對(duì)象,矩形對(duì)象僅僅是一個(gè)數(shù)據(jù)對(duì)象劫恒。
let rectangle = new PIXI.Rectangle(x, y, width, height);
Pixi的紋理中存在frame屬性可被設(shè)置為任何Rectangle矩形對(duì)象贩幻,frame將紋理映射到Rectangle的維度轿腺。
從雪碧圖創(chuàng)建精靈的紋理是一個(gè)使用頻繁的操作,Pixi提供更為合適的方式來(lái)處理丛楚。
紋理貼圖
紋理貼圖集是一個(gè)JSON數(shù)據(jù)文件族壳,包含了匹配的PNG雪碧圖的子圖像的大小和位置。使用紋理貼圖集時(shí)只需要知道對(duì)應(yīng)名稱即可趣些。修改或刪除圖片只需要修改JSON數(shù)據(jù)文件即可仿荆,游戲內(nèi)會(huì)自動(dòng)給程序內(nèi)所有數(shù)據(jù)應(yīng)用更新紋理貼圖集。
Pixi可使用Texture Packer軟件輸出標(biāo)準(zhǔn)紋理貼圖集格式
const imgs = [
{name:"man", url:"texture/man.json"},
];
loader.add(imgs).load(function(){
//let texture = TextureCache["man1.jpg"];
let texture = resources["man"].textures["man1.jpg"];
let sprite = new Sprite(texture);
sprite.position.set(150, 150);
app.stage.addChild(sprite);
}).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
例如:加載并創(chuàng)建紋理貼圖集并獲取其一居中顯示
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let Sprite = PIXI.Sprite;
let TextureCache = PIXI.utils.TextureCache;
let Rectangle = PIXI.Rectangle;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
let app = new Application({width:width, height:height, resolution:1, transparent:false, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//資源位置
const urls = [
{name:"man", url:"texture/man.json"},
];
//加載紋理貼圖集
loader.add(urls).load(function(){
//獲取紋理創(chuàng)建精靈
let texture = resources["man"].textures["man1.jpg"];
let sprite = new Sprite(texture);
//水平垂直居中定位
const x = (width - sprite.width)/2;
const y = (height - sprite.height)/2;
sprite.position.set(x, y);
//精靈添加到舞臺(tái)
app.stage.addChild(sprite);
}).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
精靈移動(dòng)
使用pixi的ticker實(shí)現(xiàn)游戲循環(huán)坏平,任何在游戲循環(huán)中的代碼都會(huì)1秒更新60次拢操。
例如:讓hero精靈以每幀1像素的速率移動(dòng)
//加載紋理貼圖集
loader.add(urls).load(function(){
//獲取紋理創(chuàng)建精靈
let texture = resources["man"].textures["hero1.png"];
let sprite = new Sprite(texture);
//水平垂直居中定位
const x = (width - sprite.width)/2;
const y = (height - sprite.height)/2;
sprite.position.set(x, y);
sprite.scale.set(0.5, 0.5);
sprite.vx = 1;
sprite.vy = 1;
//精靈添加到舞臺(tái)
app.stage.addChild(sprite);
//精靈移動(dòng)
app.ticker.add(delay=>{
console.log(sprite.y, sprite.vy);
if(sprite.x < height/2){
sprite.x += sprite.vx + delay;
sprite.y += sprite.vy + delay;
}
});
}).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
動(dòng)畫精靈 PIXI.AnimatedSprite
- 動(dòng)畫精靈就是逐幀動(dòng)畫,是通過(guò) 一幀一幀的播放圖像來(lái)產(chǎn)生運(yùn)動(dòng)的錯(cuò)覺(jué)舶替。
- 動(dòng)畫精靈使按一系列略不相同的圖像創(chuàng)建精靈庐冯,然后一幀一幀播放這些圖像產(chǎn)生運(yùn)動(dòng)的幻覺(jué)。
- 制作動(dòng)畫精靈需使用PIXI的AnimatedSprite方法
例如:將序列幀圖片使用Texture Packer制作成紋理貼圖集并導(dǎo)出JSON文件后制作精靈動(dòng)畫
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let Sprite = PIXI.Sprite;
let TextureCache = PIXI.utils.TextureCache;
let Rectangle = PIXI.Rectangle;
let AnimatedSprite = PIXI.AnimatedSprite;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
let app = new Application({width:width, height:height, resolution:1, transparent:false, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//資源位置
const urls = [
{name:"effect", url:"texture/effect.json"},
];
//加載紋理貼圖集
loader.add(urls).load(setup).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
let sprite;
//啟動(dòng)代碼
function setup(){
//獲取紋理創(chuàng)建精靈
let textures = resources["effect"].textures;
//對(duì)象轉(zhuǎn)數(shù)組
const arrTextures = Object.values(textures);
//創(chuàng)建精靈動(dòng)畫
sprite = new AnimatedSprite(arrTextures);
sprite.animationSpeed = 1;
//水平垂直居中定位
const x = (width - sprite.width)/2;
const y = (height - sprite.height)/2;
sprite.position.set(x, y);
//精靈添加到舞臺(tái)
app.stage.addChild(sprite);
//播放精靈動(dòng)畫
sprite.play();
};
PIXI.AnimatedSpirte
使用紋理數(shù)組創(chuàng)建動(dòng)畫精靈
const sprite = new PIXI.AnimatedSprite(textures, autoUpdated);
參數(shù) | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
textures | array | - | 紋理貼圖數(shù)組 |
autoUpdated | boolean | true | 是否使用PIXI.ticker.shared自動(dòng)更新動(dòng)畫時(shí)間 |
返回值:返回用于控制動(dòng)畫精靈的對(duì)象
返回值屬性 | 類型 | 描述 |
---|---|---|
animationSpeed | number | 播放速度默認(rèn)為1坎穿,值越大速度越快展父。 |
currentFrame | number | 當(dāng)前幀編號(hào) |
totalFrames | number | 幀總數(shù) |
playing | boolean | 當(dāng)前動(dòng)畫是否在播放 |
loop | boolean | 是否循環(huán)播放 |
onLoop | function | loop為true時(shí)調(diào)用 |
onComplete | function | 當(dāng)loop為false時(shí)動(dòng)畫完成后調(diào)用 |
onFrameChange | function | 但動(dòng)畫更改要呈現(xiàn)的紋理時(shí)調(diào)用 |
textures | array | 紋理數(shù)組 |
返回值方法 | 參數(shù) | 描述 |
---|---|---|
play | - | 播放的動(dòng)畫精靈 |
stop | - | 停止播放動(dòng)畫精靈 |
gotoAndPlay | frameNumber, numberType, frameIndex | 轉(zhuǎn)到特定幀并開(kāi)始播放動(dòng)畫 |
gotoAndStop | frameNumber, numberType, frameIndex | 轉(zhuǎn)到特定幀并停止播放動(dòng)畫 |
平鋪精靈PIXI.TilingSprite
平鋪精靈是一種特殊的精靈,可在一定的范圍內(nèi)重復(fù)一個(gè)紋理玲昧∑苘裕可使用平鋪精靈創(chuàng)建無(wú)線滾動(dòng)的背景效果。
創(chuàng)建平鋪精靈
const TilingSprite = PIXI.TilingSprite;
const tiling = new TilingSprite(texture, width, height);
參數(shù) | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
texture | PIXI.Texture | - | 平鋪精靈紋理 |
width | number | 100 | 平鋪精靈的寬度 |
height | number | 100 | 平鋪精靈的高度 |
平鋪精靈具有和普通精靈相同的屬性孵延,與普通精靈工作方式相同吕漂。
例如:使用小圖創(chuàng)建平鋪精靈并移動(dòng)
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let TextureCache = PIXI.utils.TextureCache;
let Rectangle = PIXI.Rectangle;
let Container = PIXI.Container;
let Sprite = PIXI.Sprite;
let AnimatedSprite = PIXI.AnimatedSprite;
let TilingSprite = PIXI.TilingSprite;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
let app = new Application({width:width, height:height, resolution:1, transparent:false, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//資源位置
const urls = [
{name:"brick", url:"images/brick.png"},
];
//加載紋理
loader.add(urls).load(setup).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
//啟動(dòng)代碼
let tiling;
function setup(){
//創(chuàng)建平鋪精靈
const texture = resources["brick"].texture;
tiling = new TilingSprite(texture, width, height);
tiling.tileScale.set(0.5, 0.5);
app.stage.addChild(tiling);
app.ticker.add(delay=>loop(delay));
};
let state = play;
function loop(delay){
state(delay);
}
function play(delay){
tiling.tilePosition.x -= 1;
}
例如:視差滾動(dòng)的偽3D效果
在同一位置層疊多個(gè)平鋪精靈,遠(yuǎn)景圖片移動(dòng)要慢于近景圖像尘应。
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let TextureCache = PIXI.utils.TextureCache;
let Rectangle = PIXI.Rectangle;
let Container = PIXI.Container;
let Sprite = PIXI.Sprite;
let AnimatedSprite = PIXI.AnimatedSprite;
let TilingSprite = PIXI.TilingSprite;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
let app = new Application({width:width, height:height, resolution:1, transparent:true, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//資源位置
const urls = [
{name:"wood", url:"images/wood.jpg"},
{name:"ground", url:"images/ground.png"},
];
//加載紋理
loader.add(urls).load(setup).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
//啟動(dòng)代碼
let wood, ground;
function setup(){
const woodTexture = resources["wood"].texture;
wood = new TilingSprite(woodTexture, width, height);
const groundTexture = resources["ground"].texture;
ground = new TilingSprite(groundTexture, width, groundTexture.height);
ground.y = height - groundTexture.height;
app.stage.addChild(wood);
app.stage.addChild(ground);
app.ticker.add(delay=>loop(delay));
};
let state = play;
function loop(delay){
state(delay);
}
function play(delay){
wood.tilePosition.x -= 1;
ground.tilePosition.x += 2;
}
精靈狀態(tài)SpriteUtilities
當(dāng)具有復(fù)雜的游戲角色或交互式對(duì)象時(shí)惶凝,可能希望角色根據(jù)游戲環(huán)境中發(fā)生的動(dòng)作,以不同的方式運(yùn)行犬钢。每個(gè)單獨(dú)的行為稱為狀態(tài)苍鲜,如果在精靈上定義狀態(tài),只要游戲中出現(xiàn)與該狀態(tài)相應(yīng)的事件時(shí)玷犹,就可以觸發(fā)這些狀態(tài)混滔。比如,通過(guò)鍵盤控制角色移動(dòng)歹颓。
使用精靈狀態(tài)坯屿,首先需要狀態(tài)播放器,狀態(tài)播放器用于控制精靈的狀態(tài)巍扛。pixi精靈沒(méi)有自己的狀態(tài)播放器领跛,可使用SpriteUtilities庫(kù)中的sprite方法,sprite方法將創(chuàng)建一個(gè)內(nèi)置狀態(tài)播放器的精靈撤奸。
游戲狀態(tài)
游戲狀態(tài)作為一種代碼風(fēng)格吠昭,幫助模塊組織代碼喊括,結(jié)構(gòu)化游戲循環(huán)代碼,使場(chǎng)景切換和關(guān)卡類操作變得更加簡(jiǎn)單怎诫。
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let Sprite = PIXI.Sprite;
let TextureCache = PIXI.utils.TextureCache;
let Rectangle = PIXI.Rectangle;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
let app = new Application({width:width, height:height, resolution:1, transparent:false, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//資源位置
const urls = [
{name:"man", url:"texture/man.json"},
];
let state;//游戲狀態(tài)
//加載紋理貼圖集
loader.add(urls).load(setup).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
let sprite;
//啟動(dòng)代碼
function setup(){
//獲取紋理創(chuàng)建精靈
let texture = resources["man"].textures["hero1.png"];
sprite = new Sprite(texture);
//水平垂直居中定位
const x = (width - sprite.width)/2;
const y = (height - sprite.height)/2;
sprite.position.set(x, y);
sprite.scale.set(0.5, 0.5);
sprite.vx = 1;
sprite.vy = 1;
//精靈添加到舞臺(tái)
app.stage.addChild(sprite);
//精靈移動(dòng)
app.ticker.add(delay=>loop(delay));
};
//設(shè)置游戲狀態(tài)
state = play;
//游戲環(huán)迅
function loop(delay){
state(delay);
};
//運(yùn)行狀態(tài)
function play(delay){
console.log(sprite.y, sprite.vy);
if(sprite.x < height/2){
sprite.x += sprite.vx + delay;
sprite.y += sprite.vy + delay;
}
};
游戲狀態(tài)機(jī)
游戲狀態(tài)機(jī)是用于設(shè)計(jì)游戲的基本狀態(tài)邏輯
例如
const GAME_STATUS = {UNINIT:0, INIT:1, LOADED:2, PLAYING:3, GAMEOVER:4};
消息總線
監(jiān)聽(tīng)器模式是一個(gè)減少組件之間耦合的辦法瘾晃,不同組件之間通過(guò)消息總線收發(fā)消息,可以有效地避免組件之間的復(fù)雜調(diào)用幻妓。游戲是游戲互動(dòng)多狀態(tài)多的情況蹦误。比如游戲裝狀態(tài)機(jī)從LOADED轉(zhuǎn)變?yōu)镻LAYING時(shí)廣播這個(gè)消息給相關(guān)組件游戲開(kāi)始了。
鍵盤控制
自定義keyboard鍵盤函數(shù)用于監(jiān)聽(tīng)和捕獲鍵盤事件
編寫鍵盤方法
const keycode = {
left:37,
up:38,
right:39,
down:40
};
function keyboard(code){
let key = {};
key.code = code;
//key status
key.isDown = false;
key.isUp = true;
//key action
key.press = undefined;
key.release = undefined;
//key down handler
key.down = evt=>{
if(evt.keyCode === key.code){
if(key.isUp && key.press){
key.press();
}
key.isDown = true;
key.isUp = false;
}
evt.preventDefault();
};
// key up handler
key.up = evt=>{
if(evt.keyCode===key.code){
if(key.isDown && key.release){
key.release();
}
key.isUp = true;
key.isDown = false;
}
evt.preventDefault();
};
//attach event listeners
window.addEventListener("keydown", key.down.bind(key), false);
window.addEventListener("keyup", key.up.bind(key), false);
return key;
}
使用鍵盤控制角色的移動(dòng)
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let Sprite = PIXI.Sprite;
let TextureCache = PIXI.utils.TextureCache;
let Rectangle = PIXI.Rectangle;
let AnimatedSprite = PIXI.extras.AnimatedSprite;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
let app = new Application({width:width, height:height, resolution:1, transparent:false, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//資源位置
const urls = [
{name:"effect", url:"texture/effect.json"},
];
//加載紋理貼圖集
loader.add(urls).load(setup).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
let sprite;
//啟動(dòng)代碼
function setup(){
//獲取紋理創(chuàng)建精靈
let textures = resources["effect"].textures;
//對(duì)象轉(zhuǎn)數(shù)組
const arrTextures = Object.values(textures);
//創(chuàng)建精靈動(dòng)畫
sprite = new AnimatedSprite(arrTextures);
sprite.animationSpeed = 1;
//水平垂直居中定位
const x = (width - sprite.width)/2;
const y = (height - sprite.height)/2;
sprite.position.set(x, y);
//移動(dòng)速度
sprite.vx = 0;
sprite.vy = 0;
//精靈添加到舞臺(tái)
app.stage.addChild(sprite);
//播放精靈動(dòng)畫
sprite.play();
//設(shè)置游戲狀態(tài)
state = play;
//循環(huán)播放
app.ticker.add(delta=>loop(delta));
};
function loop(delta){
state(delta);
}
function play(delta){
sprite.x += sprite.vx;
sprite.y += sprite.vy;
}
//鍵盤方向鍵
const keyUp = keyboard(keycode.up);
const keyDown = keyboard(keycode.down);
const keyLeft = keyboard(keycode.left);
const keyRight = keyboard(keycode.right);
//鍵盤控制
keyUp.press = function(){
sprite.vx = 0;
sprite.vy = -5;
};
keyUp.release = function(){
if(sprite.vx===0 && !keyDown.isDown){
sprite.vy = 0;
}
};
keyDown.press = function(){
sprite.vx = 0;
sprite.vy = 5;
};
keyDown.release = function(){
if(sprite.vx===0 && !keyUp.isDown){
sprite.vy = 0;
}
};
keyLeft.press = function(){
sprite.vx = -5;
sprite.vy = 0;
};
keyLeft.release = function(){
if(sprite.vy===0 && !keyRight.isDown){
sprite.vx = 0;
}
};
keyRight.press = function(){
sprite.vx = 5;
sprite.vy = 0;
};
keyRight.release = function(){
if(sprite.vy === 0 && !keyLeft.isDown){
sprite.vx = 0;
}
};
容器PIXI.Container
容器可以用來(lái)管理相似的多個(gè)精靈
例如:將不同精靈放入容器后添加到舞臺(tái)
//設(shè)置別名
let Application = PIXI.Application;
let loader = PIXI.loader;
let resources = PIXI.loader.resources;
let Sprite = PIXI.Sprite;
let TextureCache = PIXI.utils.TextureCache;
let Rectangle = PIXI.Rectangle;
let AnimatedSprite = PIXI.AnimatedSprite;
let Container = PIXI.Container;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
let app = new Application({width:width, height:height, resolution:1, transparent:false, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//資源位置
const urls = [
{name:"hero1", url:"images/hero1.png"},
{name:"hero2", url:"images/hero2.png"},
];
//加載紋理
loader.add(urls).load(setup).on("progress", function(loader, resource){
console.log("loading", loader.progress, resource.name, resource.url);
});
//啟動(dòng)代碼
function setup(){
//從紋理緩存中創(chuàng)建精靈
let hero1 = new Sprite(resources["hero1"].texture);
let hero2 = new Sprite(resources["hero2"].texture);
//縮放精靈
hero1.scale.set(0.5, 0.5);
hero2.scale.set(0.5, 0.5);
//創(chuàng)建容器并添加元素
let container = new Container();
container.addChild(hero1);
container.addChild(hero2);
//設(shè)置容器在場(chǎng)景中的位置
const x = (width - container.width)/2;
const y = (height - container.height)/2;
container.position.set(x, y);
//將容器添加到舞臺(tái)
app.stage.addChild(container);
};
當(dāng)往一個(gè)Container容器中添加精靈時(shí)肉津,其x和y的位置是相對(duì)于分組左上角强胰,這是精靈的局部位置。精靈還具有一個(gè)全局位置妹沙,全局位置是舞臺(tái)左上角到精靈錨點(diǎn)(通常是精靈左上角)的距離偶洋,可通過(guò)toGlobal方法獲取精靈圖的全局位置。
粒子容器PIXI.ParticleContainer
Pixi有一個(gè)額外的距糖、高性能的容器稱為ParticleContainer玄窝,任何在ParticleContainer中的精靈都會(huì)比在普通Container的渲染速度快2到5倍,這是用于提升游戲性能的一個(gè)很不錯(cuò)的方式悍引。
為什么ParticleContainer中的精靈圖能處理的這么快呢恩脂?因?yàn)榫`的位置是直接在GPU上計(jì)算的。Pixi開(kāi)發(fā)團(tuán)隊(duì)正努力讓更多的雪碧圖在GPU上處理趣斤。
創(chuàng)建粒子容器
const ParticleContainer = PIXI.ParticleContainer;
const particleContainer = new ParticleContainer(options);
創(chuàng)建ParticleContainer時(shí)可以傳遞四個(gè)參數(shù)size俩块、properties、batchSize浓领、autoResize玉凯。
- ParticleContainer中的精靈只有Container中少部分屬性x、y联贩、width漫仆、height、scale撑蒜、pivot歹啼、alpha、visible座菠。
- ParticleContainer包含的精靈不能再繼續(xù)嵌套。
- ParticleContainer不能使用Pixi中的視覺(jué)效果藤树,比如過(guò)濾器和混合模式浴滴。
- 每個(gè)ParticleContainer只能使用一個(gè)紋理,如果想讓精靈有不同的表現(xiàn)形式岁钓,則必須更換雪碧圖升略。
幾何圖形PIXI.Graphics
使用圖片紋理制作精靈使最有效的方式之一微王,Pixi提供了自己的繪圖工具用來(lái)創(chuàng)造矩形、線段品嚣、多邊形以及文本炕倘。
Pixi的繪圖工具和Canvas Drawing API幾乎一致,不同之處在于Pixi的繪圖API是通過(guò)WebGL在GPU上渲染的翰撑。
所有圖形的初始化都需要先創(chuàng)建一個(gè)Pixi的Graphics類的實(shí)例
const Graphics = PIXI.Graphics;
const graphics = new Graphics();
矩形
繪制矩形
graphics.drawRect(x, y, width, height);
例如:繪制100x100罩旋,背景黑色,3像素紅色邊框的矩形眶诈。
//設(shè)置別名
let Application = PIXI.Application;
let Graphics = PIXI.Graphics;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
const resolution = window.devicePixelRatio;
let app = new Application({width:width, height:height, resolution:resolution, transparent:true, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//創(chuàng)建矩形
let graphics = new Graphics();
graphics.beginFill(0x000000);
graphics.lineStyle(3, 0xff0000, 1);
graphics.drawRect(0, 0, 100, 100);
graphics.endFill();
graphics.x = (width - graphics.width)/2;
graphics.y = (height - graphics.height)/2;
app.stage.addChild(graphics);
圓角矩形
graphics.drawRoundedRect(x, y, width, height, cornerRadius);
圓形
graphics.drawCircle(x, y, radius);
橢圓
graphics.drawEllipse(x, y, width, height);
顯示文本PIXI.Text
Pixi使用Text對(duì)象在舞臺(tái)上顯示文本涨醋,Text文本對(duì)象繼承自Sprite類,可以像處理精靈一樣在舞臺(tái)上定位和調(diào)整文本逝撬。
//設(shè)置別名
let Application = PIXI.Application;
let Text = PIXI.Text;
let TextStyle = PIXI.TextStyle;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
const resolution = 1;
let app = new Application({width:width, height:height, resolution:resolution, transparent:true, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置滿屏
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
app.renderer.autoResize = true;
app.renderer.resize(window.innerWidth, window.innerHeight);
//創(chuàng)建文本并設(shè)置樣式
const style = new TextStyle({
fontFamily:"Arial",
fontSize:36,
fill:"white",
stroke:"#ff3300",
strokeThickness:4,
dropShadow:true,
dropShadowColor:"#000000",
dropShadowBlur:4,
dropShadowAngle:Math.PI/6,
dropShadowDistance:6
});
let str = "Hello World";
const text = new Text(str, style);
text.text = "HELLO WORLD";
let x = (width - text.width)/2;
let y = (height - text.height)/2;
text.position.set(x, y);
app.stage.addChild(text);
碰撞檢測(cè)hitTestRectangle
自定義hitTestRectangle
函數(shù)用于檢測(cè)兩個(gè)矩形是否接觸
const boolean = hitTestRectangle(sprite1, sprite2);
若精靈1和精靈2發(fā)生重疊則返回true浴骂,反之為false。
//矩形碰撞檢查
function hitTestRectangle(r1, r2){
let hit = false;//是否發(fā)生碰撞
//獲取矩形中心點(diǎn)
r1.centerX = r1.x + r1.width/2;
r1.centerY = r1.y + r1.height/2;
r2.centerX = r2.x + r2.width/2;
r2.centerY = r2.y + r2.height/2;
//計(jì)算矩形中心點(diǎn)距離
const vx = Math.abs(r1.centerX - r2.centerX);
const vy = Math.abs(r1.centerY - r2.centerY);
//計(jì)算矩形合并時(shí)尺寸
const combinedHalfWidth = (r1.width + r2.width)/2;
const combinedHalfHeight = (r1.height + r2.height)/2;
//檢測(cè)矩形是否發(fā)生碰撞
if(combinedHalfWidth>vx && combinedHalfHeight>vy){
hit = true;
}
return hit;
}
例如:繪制兩個(gè)矩形宪潮,測(cè)試是否發(fā)生碰撞溯警。
//設(shè)置別名
let Application = PIXI.Application;
let Rectangle = PIXI.Rectangle;
let Graphics = PIXI.Graphics;
//創(chuàng)建應(yīng)用
const width = window.innerWidth;
const height = window.innerHeight;
const resolution = 1;
let app = new Application({width:width, height:height, resolution:resolution, transparent:true, antialias:true});
//添加canvas到document
document.body.appendChild(app.view);
//設(shè)置別名
const renderer = app.renderer;
const stage = app.stage;
//設(shè)置滿屏
renderer.view.style.position = "absolute";
renderer.view.style.display = "block";
renderer.autoResize = true;
renderer.resize(window.innerWidth, window.innerHeight);
//創(chuàng)建矩形
const r1 = new Graphics();
r1.beginFill(0x00ffff);
r1.drawRect(0, 0, 100, 100);
r1.endFill();
r1.position.set((width-r1.width)/2, (height - r1.height)/2);
stage.addChild(r1);
const r2 = new Graphics();
r2.beginFill(0x0000ff);
r2.drawRect(0, 0, 100, 100);
r2.endFill();
r2.position.set((width-r2.width)/2, (height - r2.height)/2+10);
stage.addChild(r2);
//判斷舉行是否發(fā)生碰撞
const hit = hitTestRectangle(r1, r2);
console.log(hit);