Building JavaScript Games for Phones Tablets and Desktop(4)-遊戲資源

遊戲資源

前面的章節已經教會了如何用一個構造的Game對象來寫一個簡單的遊戲例子。你也發現JavaScript能夠獲取canvas和canvasContext的值,用來進行canvas的運算。你也知道了如何改變畫布背景色。也知道結合系統時間讓一個方塊在屏幕上進行移動。這章講解如何在屏幕上繪畫圖片,這是創造出好看遊戲的第一步。在計算機圖形學中,這些圖形被稱做精靈。精靈通常都從文件裏進行加載。這意味着任何繪畫精靈的程序再也不僅僅只是一個簡單的指令,而是須要知道這些遊戲資源放在何處。即將講的幾個事情你須要思考下:web

  • 能夠從哪裏加載精靈?canvas

  • 怎樣從一個圖像文件裏獲取信息瀏覽器

  • 怎樣將精靈顯示在屏幕上markdown

這章將會回答這些問題。函數

音樂是另外一種類型的遊戲資源。它的處理與精靈十分相似。所以,在本章的最末,你會看到如何在你的遊戲中播放音樂和音效。oop

定位精靈

在一個程序可使用任何資源前,須要知道在哪裏找到這些資源。默認狀況下,瀏覽器會自動在當前文件夾下尋找精靈,和尋找JavaScript文件同樣。看這章的SpriteDrawing例子,你會發現一個spr_balloon.png文件和HTML文件和JavaScript文件在一個文件夾下。網站

加載精靈

如今看如何從一個文件裏面加載精靈。經過一個變量來加載精靈。你須要在遊戲循環裏不一樣的地方使用這個變量。在start方法裏,加載這個精靈而且存放在一個變量裏。所以,在Game對象中添加一個 balloonSprite變量。以下所示:rest

var Game = {
 canvas : undefined,
 canvasContext : undefined,
 balloonSprite : undefined
};

能夠定義一個對象來包含關於這個精靈的全部信息。以下:code

Game.balloonSprite = {
 src : "spr_balloon.png",
 width : 35,
 height : 63,
 ...
}

若是你想在你的遊戲里加載成百上千的精靈時,上述的就有問題了。每次你都必須定義一個相似上面的對象字變量。另外,你並不肯定是否會用到一個對象裏面的其餘變量。由於一個圖片有不一樣的表現。幸虧,你能夠經過類來避免這些問題。對象

類的基本定義就是一個對象的原型。它是一個對象的抽象。好比,JavaScript知道一個叫作Image的類,這個類定義一個關於圖片的對象,對象有寬和高,有源文件地址等等。經過image類能夠很是簡單的建立一個對象,只須要只要new關鍵字:

Game.balloonSprite = new Image();

這比在一個對象裏寫出全部變量的值輕鬆多了,表達式new Image()作到了這些。經過使用類,你能夠輕鬆的創造對象。並且能夠肯定這些對象都有相同的結構。

你還不知道這個變量裏面究竟含有什麼。你能夠給src變量賦值爲圖片源文件的地址。

Game.balloonSprite.src = "spr_balloon.png";

當src一設置,瀏覽器就開始加載文件。並且瀏覽器自動的獲取圖片的寬和高。

有時候,加載源文件須要一些時間。好比,這個文件存在於世界另外一邊的網站上。這意味着若是你想立刻就看到圖片是很困難的。所以,你須要確保在遊戲啓動以前全部圖片都加載完畢。這裏有一個很是簡潔的方式,使用一個事件處理函數。第七章你就會知道它是如何工做的。如今,想象半秒以內就能夠加載這個圖片。經過使用setTimeout方法,你能夠在500ms後加載mainLoop方法。

window.setTimeout(Game.mainLoop, 500);

完成後的start方法以下:

Game.start = function () {
 Game.canvas = document.getElementById("myCanvas");
 Game.canvasContext = Game.canvas.getContext("2d");
 Game.balloonSprite = new Image();
 Game.balloonSprite.src = "spr_balloon.png";
 window.setTimeout(Game.mainLoop, 500);
};

精靈能夠從任何地方加載。若是你用JavaScript開發遊戲,思考如何組織你的精靈是個好習慣。好比,你能夠把你全部的精靈放在一個叫作sprites的文件夾裏。那樣你就能夠像下面這樣設置源文件。

Game.balloonSprite.src = "sprites/spr_balloon.png";

也許你不會使用本身的圖片,而是來自互聯網的圖片:

Game.balloonSprite.src = "http://www.somewebsite.com/images/spr_balloon.png";

JavaScript容許你從任何你想的地方加載圖片。只是但從互聯網上加載圖片時,須要確認圖片地址是固定不變的。不然,當網站主人在沒有告知你的狀況下移動掉這些文件,你的遊戲將沒法運行。

繪畫精靈

加載精靈並不意味着精靈就顯示到了屏幕上。想要讓精靈顯示出來,須要在draw方法裏面作些事情。爲了在畫布上畫出精靈,你可使用canvasContext對象的一個方法:drawImage。在JavaScript裏,當圖片須要顯示在固定的位置,這個位置的座標一般是圖片的左上角。下面是顯示精靈的指令:

Game.canvasContext.drawImage(sprite, 0, 0, sprite.width, sprite.height,
 0, 0, sprite.width, sprite.height);

drawImage方法有不少不一樣的參數。好比,你能夠指定在何處繪畫精靈,或者是否只是精靈的一部分進行顯示。你能夠簡單的調用此方法達到目的。然而,若是你考慮到你之後建立的遊戲,你可使用繪畫狀態來繪畫精靈。

繪畫狀態從根本上來講就是一組參數,這些參數用於全部繪畫之間的轉換。使用繪畫狀態而不是用單一的drawImage方法的好處是你能夠對精靈作更復雜的轉換。好比,使用繪畫狀態,你能夠翻轉或者比例縮放精靈,這在之後的遊戲中很是有用。創造一個新的繪畫狀態是經過調用save方法。

Game.canvasContext.save();

如今你可使用這個繪畫狀態來進行各類轉換。好比,你能夠移動精靈到一個肯定位置:

Game.canvasContext.translate(100, 100);

若是你如今調用drawImage方法,精靈會被繪畫在(100,100)處。一旦你完成繪畫,你能夠像下面這樣移除繪畫狀態。

Game.canvasContext.restore();

爲了方便,定義一個能夠作上述一切的方法:

Game.drawImage = function (sprite, position) {
 Game.canvasContext.save();
 Game.canvasContext.translate(position.x, position.y);
 Game.canvasContext.drawImage(sprite, 0, 0, sprite.width, sprite.height,
 0, 0, sprite.width, sprite.height);
 Game.canvasContext.restore();
};

經過上述參數看出,這個方法須要兩個信息,要被繪畫的精靈和繪畫精靈所在的位置。精靈應該是image類,這個地址是一個含有x和y部分的對象。當你調用這個方法,你須要提供上述這些信息。好比,像下面這樣在(100,100)出畫一個氣球精靈:

Game.drawImage(Game.balloonSprite, { x : 100, y : 100 });

你使用花括號定義了一個含有x和y的對象。正如你看到的那樣,容許在調用方法的指令中定義一個對象。固然,你能夠開始就定義一個對象,儲存在變量裏,好比下面這樣:

var balloonPos = {
 x : 100,
 y : 100
};
Game.drawImage(Game.balloonSprite, balloonPos);

這段代碼和以前的代碼是同樣的,只是多寫了些。你能夠把drawImage方法放在draw方法裏面,這樣氣球就會顯示在你想要的位置:

Game.draw = function () {
 Game.drawImage(Game.balloonSprite, { x : 100, y : 100 });
};

在瀏覽器上看到的結果如圖4-1

(省略圖4-1)

移動精靈

如今你能夠在屏幕上顯示一個精靈了,你可使用遊戲循環來讓它移動,就像上章裏面讓方塊移動那樣。在這裏咱們讓氣球的位置基於通過的時間來進行移動。爲了完成這個,你須要儲存氣球的位置。須要在update方法計算位置和在draw方法裏繪畫氣球。所以,在Game對象裏面添加一個位置變量:

var Game = {
 canvas : undefined,
 canvasContext : undefined,
 balloonSprite : undefined,
 balloonPosition : { x : 0, y : 50 }
};

如上所示,在game對象裏面定義了一個含有兩個變量的對象。如今你能夠在update方法裏面添加一條經過通過的時間來改變位置的指令,就像在移動方塊例子裏面同樣。以下:

Game.update = function () {
 var d = new Date();
 Game.balloonPosition.x = d.getTime() % Game.canvas.width;
};

剩下的就是畫出氣球:

Game.drawImage(Game.balloonSprite, Game.balloonPosition);

加載和繪畫多重精靈

建立一個只有白色背景的遊戲怎麼看都是乏味的。你可讓你的遊戲經過繪畫一個背景精靈來使其更具備可看性。這意味着你須要在start方法裏面加載另外一個精靈而且在draw裏面進行顯示。這個程序的最終版本叫作FlyingSprite。若是你在瀏覽器裏面打開的話,你會看見兩個精靈,一個背景圖和一個氣球。爲了實現這個,增長一個含有背景精靈的變量,以下所示:

var Game = {
 canvas : undefined,
 canvasContext : undefined,
 backgroundSprite : undefined,
 balloonSprite : undefined,
 balloonPosition : { x : 0, y : 50 }
};

固然,在draw裏面,如今有兩個要繪畫方法調用:

Game.draw = function () {
Game.drawImage(Game.backgroundSprite, { x : 0, y : 0 });
Game.drawImage(Game.balloonSprite, Game.balloonPosition);
};

這些方法調用的順序是很是重要的。由於你想氣球顯示在背景上面。首先就得畫出背景,而後畫氣球。若是你反過來作,背景會覆蓋掉氣球,你將什麼也看不到。圖4-2展現了程序的輸出結果:

(省略圖4-2)

每次你想在屏幕上繪畫一個精靈,你就在draw方法裏多調用一次drawImage,你能夠一個精靈繪畫屢次,顯示在不一樣的位置。好比,你想在背景上畫出一些不一樣位置的氣球,你只須要調用屢次調用drawImage和睦球的位置參數:

Game.draw = function () {
 Game.drawImage(Game.backgroundSprite, { x : 0, y : 0 });
 Game.drawImage(Game.balloonSprite, { x : 0, y : 0 });
 Game.drawImage(Game.balloonSprite, { x : 100, y : 0 });
 Game.drawImage(Game.balloonSprite, { x : 200, y : 0 });
 Game.drawImage(Game.balloonSprite, { x : 0, y : 300 });
 Game.drawImage(Game.balloonSprite, { x : 200, y : 300 });
};

固然,再次注意繪畫的順序。

你能夠同時畫出多個移動的精靈。對於每個氣球,你能夠定義一個專屬於它的位置變量,以下所示:

Game.update = function () {
 var d = new Date();
 Game.balloonPosition1.x = d.getTime() % Game.canvas.width;
 Game.balloonPosition2.x = (d.getTime() + 100) % Game.canvas.width;
 Game.balloonPosition3.x = (d.getTime() + 200) % Game.canvas.width;
};

在draw方法裏,能夠用這些變量畫出靜止的和移動的氣球:

Game.draw = function () {
 Game.drawImage(Game.backgroundSprite, Game.balloonPosition1);
 Game.drawImage(Game.balloonSprite, Game.balloonPosition2);
 Game.drawImage(Game.balloonSprite, Game.balloonPosition3);
 Game.drawImage(Game.balloonSprite, { x : 200, y : 0 });
 Game.drawImage(Game.balloonSprite, { x : 0, y : 300 });
 Game.drawImage(Game.balloonSprite, { x : 200, y : 300 });
};

音樂和音效

另外一個常見的遊戲資源是音效。不少遊戲都有音效和背景音樂。這有不少重要的緣由。音效能夠告訴用戶某些重要的線索。好比,當用戶按下一個鍵時有一個肯定的點擊音效。聽見腳步聲表示敵人接近了,即便玩家沒有看見他們。老遊戲迷霧之島就是一個典型的這類型的遊戲,由於裏面的不少線索都是經過音效來找到的。

好的音效能給遊戲世界帶來更好的感覺。它們讓環境更真實,即便屏幕上什麼都沒有發生。

在JavaScript中播放背景音樂或音效是很是簡單的。使用音效以前首先須要音效文件。在FlyingSpriteWithSound這個例子裏,文件是snd_music.mp3,被當作背景音樂。跟儲存精靈同樣,須要一個變量來儲存音樂數據。以下:

var Game = {
 canvas : undefined,
 canvasContext : undefined,
 backgroundSprite : undefined,
 balloonSprite : undefined,
 balloonPosition : { x : 0, y : 50 },
 backgroundMusic : undefined
};

在start方法裏須要加載音效。JavaScript提供了一個能夠操做音效的類。類型叫作Audio,建立方法以下:

Game.backgroundMusic = new Audio();
Game.backgroundMusic.src = "snd_music.mp3";

上面看起來就跟加載精靈同樣。如今你能夠這個對象的方法了,好比下面這樣播放音效:

Game.backgroundMusic.play();

也能夠像下面這樣減小背景音樂的聲音:

Game.backgroundMusic.volume = 0.4;

volume變量的值的大小範圍是0到1,0表示沒有聲音,1表示聲音最大。

從技術上來講,背景音樂和音效之間沒有什麼不一樣。通常,背景音樂聲音要小點。不少背景音樂在遊戲循環裏面播放,完了後又從新開始。後面你將看到怎麼實現。這本書的全部遊戲都用到了聲音來讓遊戲更有趣。

你學到了什麼

這章裏,你學到了:

  • 如何加載遊戲資源好比精靈和音效
  • 如何在屏幕上繪畫多個精靈而且移動它們
  • 如何在你的遊戲裏播放背景音樂和音效
相關文章
相關標籤/搜索