PIXI 創建 Sprite的幾種方法-PIXI文檔翻譯(3)

[b]1、通過spritesheets圖創建sprite[/b]

你現在知道如何從單個圖像文件製作精靈。但是,作爲遊戲設計師,你通常會使用tilesets(也稱爲spritesheets)來製作 sprite。Pixi有一些方便的內置方法來幫助你做到這一點。tileset是包含子圖像的單個圖像文件。子圖像表示您要在遊戲中使用的所有圖形。這裏是一個包含遊戲角色和遊戲對象作爲子圖像的tileset圖像的示例。


[img]http://dl2.iteye.com/upload/attachment/0123/3397/1572ac89-f2f7-3332-901a-b21923a3b408.png[/img]


整個圖塊集爲192×192像素。每個圖像都在一個自己的32 x 32像素的網格單元。存儲和訪問所有的遊戲圖形在一個tileset是一個非常處理器和內存高效的方式來處理圖形,而Pixi是爲他們優化。

您可以通過定義與要提取的子圖像大小和位置相同的矩形區域,從圖塊集中捕獲子圖像。這裏是從tileset中提取的火箭子圖像的例子


[img]http://dl2.iteye.com/upload/attachment/0123/3399/97423353-0a71-32f4-81d8-92468cf1fac7.png[/img]

讓我們看看這樣做的代碼。首先,tileset.png使用Pixi的加載圖像loader,就像你在前面的例子中做的一樣。

loader
.add("images/tileset.png")
.load(setup);


接下來,當圖像加載時,使用tileset的矩形子部分創建sprite的圖像。這裏是提取子圖像,創建火箭精靈,並定位和顯示在畫布上的代碼。


function setup() {

//Create the `tileset` sprite from the texture
var texture = TextureCache["images/tileset.png"];

//Create a rectangle object that defines the position and
//size of the sub-image you want to extract from the texture
var rectangle = new Rectangle(192, 128, 64, 64);

//Tell the texture to use that rectangular section
texture.frame = rectangle;

//Create the sprite from the texture
var rocket = new Sprite(texture);

//Position the rocket sprite on the canvas
rocket.x = 32;
rocket.y = 32;

//Add the rocket to the stage
stage.addChild(rocket);

//Render the stage
renderer.render(stage);
}


這個怎麼用?

Pixi有一個內置Rectangle對象(PIXI.Rectangle),它是一個用於定義矩形形狀的通用對象。它需要四個參數。前兩個參數定義了矩形x和y位置。最後兩個定義它width和height。以下是定義新Rectangle對象的格式。

var rectangle = new PIXI.Rectangle(x, y, width, height);


矩形對象只是一個數據對象 ; 它由你決定如何使用它。在我們的示例中,我們使用它來定義要提取的圖塊上的子圖像的位置和麪積。Pixi紋理有一個有用的屬性frame,可以設置爲任何Rectangle對象。的frame作物的紋理的尺寸Rectangle。這裏是如何使用frame 來裁剪紋理到火箭的大小和位置。


var rectangle = new Rectangle(192, 128, 64, 64);
texture.frame = rectangle;


然後,您可以使用裁剪的紋理創建精靈:

var rocket = new Sprite(texture);


這就是它的工作原理!

因爲製作sprite紋理從一個瓷磚是你會做的很多頻率,Pixi有一個更方便的方式來幫助你這樣做 - 讓我們來看看下一步是什麼。

[b]2、使用紋理圖集[/b]

如果你在一個大型,複雜的遊戲,你會想要一個快速,有效的方式來創建精靈從tilesets。這是 紋理地圖集真正有用的地方。紋理地圖集是一個JSON數據文件,其中包含匹配圖塊集PNG圖像上的子圖像的位置和大小。如果你使用紋理地圖集,你需要知道你想要顯示的子圖像是它的名字。您可以按任何順序排列tileset圖像,JSON文件將跟蹤其大小和位置。這真的很方便,因爲它意味着tileset圖像的大小和位置沒有硬編碼到您的遊戲程序。如果您對圖塊集進行更改,例如添加圖片,調整圖片大小或刪除圖片,只需重新發布JSON文件,遊戲就會使用該數據顯示正確的圖片。您不必對您的遊戲代碼進行任何更改。

Pixi與標準JSON紋理地圖集格式兼容,該格式由一個名爲Texture Packer的流行軟件工具輸出。Texture Packer的“Essential”許可證是免費的。讓我們來了解如何使用它來製作紋理圖集,並將圖集加載到Pixi中。(你不必使用Texture Packer。類似的工具,像Shoebox或spritesheet.js,以與Pixi兼容的標準格式輸出PNG和JSON文件。)

首先,從您要在遊戲中使用的單個圖像文件的集合開始。


[img]http://dl2.iteye.com/upload/attachment/0123/3401/ada266b1-0beb-301e-b80c-d737cbaddba5.png[/img]


(本節的所有圖像都是由Lanea Zimmerman創建的。你可以在這裏找到更多她的作品 ,謝謝你,Lanea!)

接下來,打開Texture Packer並選擇JSON Hash作爲框架類型。將圖像拖動到Texture Packer的工作區中。(您也可以將Texture Packer指向包含圖像的任何文件夾。)它將自動在單個tileset圖像上排列圖像,併爲它們指定與其原始圖像名稱匹配的名稱。


[img]http://dl2.iteye.com/upload/attachment/0123/3403/6aa2ee83-1151-390c-9fdf-151dae6d8f63.png[/img]

(如果您使用的是免費版的Texture Packer,請設置Algorithm爲Basic,設置Trim模式爲 None,設置Size約束,Any size然後將PNG Opt Level向左滑動,0這些是基本設置,版本的Texture Packer來創建您的文件,沒有任何警告或錯誤。)

完成後,點擊發布按鈕。選擇文件名和位置,並保存已發佈的文件。你最終會得到2個文件:一個PNG文件和一個JSON文件。在這個例子中,我的文件名是 treasureHunter.json和treasureHunter.png。爲了讓你的生活更輕鬆,只需將這兩個文件保存在項目的images文件夾中。(您可以將JSON文件視爲圖像文件的額外元數據,因此將這兩個文件保存在同一文件夾中是有意義的。)JSON文件描述了圖塊中每個子圖像的名稱,大小和位置。這裏是一個描述blob怪物子圖像的片段。


"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}
},


該treasureHunter.json文件還包含具有相似數據的“dungeon.png”,“door.png”,“exit.png”和“explorer.png”屬性。這些子圖像中的每一個被稱爲幀。擁有這些數據是非常有幫助的,因爲現在你不需要知道每個子圖像在tileset中的大小和位置。所有你需要知道的是sprite的幀id。框架id只是原始圖像文件的名稱,如“blob.png”或“explorer.png”。

使用紋理地圖集的許多優點是,您可以輕鬆地在每個圖像周圍添加2像素的填充(Texture Packer默認情況下會這樣做。)這對於防止紋理流失的可能性很重要 。紋理流失是當圖塊上的相鄰圖像的邊緣出現在子圖形旁邊時發生的效果。這是因爲您的計算機的GPU(圖形處理單元)決定如何舍入小數像素值。應該把它們向上還是向下?這對於每個GPU將是不同的。在圖像間留下1或2個像素間距,使所有圖像一致顯示。

(注意:如果你有一個圖形周圍有兩個像素填充,並且你仍然注意到一個奇怪的“關閉一個像素”毛刺的方式Pixi顯示它,嘗試改變紋理的縮放模式算法,這裏的方法:texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;。這些毛刺有時會因爲GPU浮點舍入錯誤而發生。)

現在你知道如何創建紋理地圖集,讓我們瞭解如何將它加載到你的遊戲代碼。

[b]3、加載紋理圖集[/b]
要獲取紋理地圖集到Pixi,使用Pixi的加載 loader。如果JSON文件是用Texture Packer製作的,那麼 loader它將解釋數據並自動從tileset的每個框架創建一個紋理。以下是如何使用loader加載treasureHunter.json 文件。當它加載時,setup函數將運行。


loader
.add("images/treasureHunter.json")
.load(setup);


tileset上的每個圖像現在都是Pixi緩存中的單獨紋理。您可以使用與Texture Packer中相同的名稱(“blob.png”,“dungeon.png”,“explorer.png”等)訪問緩存中的每個紋理。

[b]4、從加載的紋理圖集創建精靈[/b]

Pixi給你三個一般的方法來創建一個精靈從紋理圖集:

使用TextureCache:
var texture = TextureCache["frameId.png"],
sprite = new Sprite(texture);


如果你使用Pixi的loader加載紋理地圖集,使用加載器的resources:
var sprite = new Sprite(
resources["images/treasureHunter.json"].textures["frameId.png"]
);


這是太多的輸入只是爲了創建一個sprite!所以我建議你創建一個別名id,指向紋理的altas的textures對象,像這樣:
var id = PIXI.loader.resources["images/treasureHunter.json"].textures; 


然後你可以創建每個新的sprite像這樣:
let sprite = new Sprite(id["frameId.png"]);


好多了!

這裏是你如何可以在使用這三種不同的精靈創作技法setup函數來創建和顯示 dungeon,explorer以及treasure精靈。


//Define variables that might be used in more
//than one function
var dungeon, explorer, treasure, door, id;

function setup() {

//There are 3 ways to make sprites from textures atlas frames

//1. Access the `TextureCache` directly
var dungeonTexture = TextureCache["dungeon.png"];
dungeon = new Sprite(dungeonTexture);
stage.addChild(dungeon);

//2. Access the texture using the loader's `resources`:
explorer = new Sprite(
resources["images/treasureHunter.json"].textures["explorer.png"]
);
explorer.x = 68;

//Center the explorer vertically
explorer.y = stage.height / 2 - explorer.height / 2;
stage.addChild(explorer);

//3. Create an optional alias called `id` for all the texture atlas
//frame id textures.
id = PIXI.loader.resources["images/treasureHunter.json"].textures;

//Make the treasure box using the alias
treasure = new Sprite(id["treasure.png"]);
stage.addChild(treasure);

//Position the treasure next to the right edge of the canvas
treasure.x = stage.width - treasure.width - 48;
treasure.y = stage.height / 2 - treasure.height / 2;
stage.addChild(treasure);


//Render the stage
renderer.render(stage);
}


以下是此代碼顯示的內容:


[img]http://dl2.iteye.com/upload/attachment/0123/3405/8f8e709f-10d4-39b0-b5fb-3fb2c8a892d1.png[/img]


階段維度爲512 x 512像素,您可以在上面的代碼中看到stage.height和stage.width屬性用於對齊精靈。這裏是如何explorer的y位置垂直居中:

explorer.y = stage.height / 2 - explorer.height / 2;


學習使用紋理地圖集創建和顯示精靈是一個重要的基準。所以在我們繼續之前,讓我們來看看你可以寫的代碼來添加剩餘的精靈:門blob和exit門,這樣你可以產生一個如下所示的場景:


[img]http://dl2.iteye.com/upload/attachment/0123/3407/a3cadc6d-c27f-35eb-b1fe-e44d77a2f367.png[/img]

這裏是完成所有這一切的整個代碼。我還包括HTML代碼,所以你可以看到一切在其正確的上下文。(你會在這個庫中的examples/spriteFromTextureAtlas.html文件中找到這個工作代碼 。)請注意,blobsprite被創建並在循環中添加到舞臺中,並分配隨機位置。


<!doctype html>
<meta charset="utf-8">
<title>Make a sprite from a texture atlas</title>
<body>
<script src="../pixi.js/bin/pixi.js"></script>
<script>

//Aliases
var Container = PIXI.Container,
autoDetectRenderer = PIXI.autoDetectRenderer,
loader = PIXI.loader,
resources = PIXI.loader.resources,
TextureCache = PIXI.utils.TextureCache,
Texture = PIXI.Texture,
Sprite = PIXI.Sprite;

//Create a Pixi stage and renderer and add the
//renderer.view to the DOM
var stage = new Container(),
renderer = autoDetectRenderer(512, 512);
document.body.appendChild(renderer.view);

//load a JSON file and run the `setup` function when it's done
loader
.add("images/treasureHunter.json")
.load(setup);

//Define variables that might be used in more
//than one function
var dungeon, explorer, treasure, door, id;

function setup() {

//There are 3 ways to make sprites from textures atlas frames

//1. Access the `TextureCache` directly
var dungeonTexture = TextureCache["dungeon.png"];
dungeon = new Sprite(dungeonTexture);
stage.addChild(dungeon);

//2. Access the texture using throuhg the loader's `resources`:
explorer = new Sprite(
resources["images/treasureHunter.json"].textures["explorer.png"]
);
explorer.x = 68;

//Center the explorer vertically
explorer.y = stage.height / 2 - explorer.height / 2;
stage.addChild(explorer);

//3. Create an optional alias called `id` for all the texture atlas
//frame id textures.
id = PIXI.loader.resources["images/treasureHunter.json"].textures;

//Make the treasure box using the alias
treasure = new Sprite(id["treasure.png"]);
stage.addChild(treasure);

//Position the treasure next to the right edge of the canvas
treasure.x = stage.width - treasure.width - 48;
treasure.y = stage.height / 2 - treasure.height / 2;
stage.addChild(treasure);

//Make the exit door
door = new Sprite(id["door.png"]);
door.position.set(32, 0);
stage.addChild(door);

//Make the blobs
var numberOfBlobs = 6,
spacing = 48,
xOffset = 150;

//Make as many blobs as there are `numberOfBlobs`
for (var i = 0; i < numberOfBlobs; i++) {

//Make a blob
var blob = new Sprite(id["blob.png"]);

//Space each blob horizontally according to the `spacing` value.
//`xOffset` determines the point from the left of the screen
//at which the first blob should be added.
var x = spacing * i + xOffset;

//Give the blob a random y position
//(`randomInt` is a custom function - see below)
var y = randomInt(0, stage.height - blob.height);

//Set the blob's position
blob.x = x;
blob.y = y;

//Add the blob sprite to the stage
stage.addChild(blob);
}

//Render the stage
renderer.render(stage);
}

//The `randomInt` helper function
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

</script>
</body>


你可以在上面的代碼中看到,所有的blob都是使用for循環創建的 。每個blob沿x軸都是均勻分佈的,如下所示:


var x = spacing * i + xOffset;
blob.x = x;


spacing具有值48,並且xOffset具有值150.這意味着第一blob將具有x150 的位置。這從舞臺的左側偏移150像素。每個後續blob都將有一個x值比blob循環的上一次迭代中創建的值大48像素。這將創建一個均勻間隔的blob怪物線,從左到右,沿着地下城樓。

每個blob也給出隨機y位置。這裏是這樣做的代碼:


var y = randomInt(0, stage.height - blob.height);
blob.y = y;


所述blob的y位置可以分配0和512之間的任何隨機數,這是的值stage.height。這在一個自定義函數的幫助下工作randomInt。randomInt返回一個在您提供的任意兩個數字之間的範圍內的隨機數。

randomInt(lowestNumber, highestNumber)


這意味着如果你想要1和10之間的隨機數,你可以得到一個這樣:

var randomNumber = randomInt(1, 10);


這裏是執行randomInt所有這些工作的函數定義:

function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

randomInt 是一個偉大的小功能,保持在你的背部口袋裏製作遊戲 - 我一直使用它。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章