06.08 VUE+Webpack遊戲設計:增加遊戲戰略性平衡和實現資源預加載

遊戲的一個可玩性在於,讓玩家在一種戰略平衡中做抉擇。例如我們在遊戲開始時讓玩家擁有120單位的能量,玩家可以採取以下幾種步驟來開展遊戲:

1.建築一個衛星30E,一個炮臺80E,然後還剩10E。然後等300毫秒後收集第一個能量泡,從而獲得足夠能源建造其他衛星或炮臺。

2.連續建造兩個衛星60E,剩下60E,等300毫秒後獲取兩個能量泡,從而獲得總共260E的能量,然後玩家可以連續建造三個炮臺。

3.一下子建造3個衛星90E,還剩30E。等300毫秒後連續收穫3個能量泡,使得能源達到330E,然後可以一口氣建造4個炮臺。

4.一下子建造4個衛星120E,等300毫秒後收穫4個能量泡,然後一下子建造5個炮臺。

無論玩家作何選擇,最終目的是頂住衝擊波中的外星人攻擊,好的戰略必須使得玩家能夠迅速的建築足夠多的炮臺。如果你一口氣建造4個衛星,那麼你只能眼睜睜的看著外星人攻打過來,你很可能來不及建造炮臺就完蛋了。因此玩家要根據每一輪衝擊波中外星人的數量和特性,在資源約束下,選擇不同的建造策略,如此一來,我們的遊戲就具備即時戰略的可玩性。

本節我們要完成的代碼,一來是增加各種建造物的成本,實現資源約束,而來是預加載彩色資源,把原來黑色線條的外星人變成愉悅的彩色圖案,本節完成後,效果如下:

VUE+Webpack遊戲設計:增加遊戲戰略性平衡和實現資源預加載

首先我們先把一系列彩色圖片資源放置在給定目錄’/static/images’:

VUE+Webpack遊戲設計:增加遊戲戰略性平衡和實現資源預加載

在頁面加載時,我們需要跑把這些資源加載到資源庫中,資源的預加載我們需要使用一個名為preloadjs的第三方輔助庫,因此在indexl.html中做如下修改:

 

....

<title>Space Defender/<title>

在代碼中我們將preloadjs庫加載到頁面時,把assets.js中的images數組引用到windows對象中,彩色圖片資源就是要加載到這個images數組裡。打開assets.js,做如下修改:

lib.properties = {
width: 640,
height: 1000,
fps: 24,
color: "#FFFFFF",
// change 2
manifest: [
{src:"static/images/bosspsd.png", id:"bosspsd"},
{src:"static/images/castlepsd.png", id:"castlepsd"},
{src:"static/images/castle2psd.png", id:"castle2psd"},
{src:"static/images/enemy1psd.png", id:"enemy1psd"},
{src:"static/images/enemy2psd.png", id:"enemy2psd"},
{src:"static/images/enemy3psd.png", id:"enemy3psd"},
{src:"static/images/junkpsd.png", id:"junkpsd"},
{src:"static/images/satellitepsd.png", id:"satellitepsd"},
{src:"static/images/satellite2psd.png", id:"satellite2psd"}
]
};

manifest數組用來指定彩色圖片資源的路徑,我們將其修改為/static/images。回到gamescenecomponent.vue,我們先在初始化函數中獲得資源庫的images數組:

 methods: {
init () {
...
// change 3
this.images = window.images
...
// change 4
this.load()
...
}
...
}

this.load函數是調用preloadjs庫的功能,將彩色圖片資源加載進來,我們看看它的實現:

// change 5
load () {
var loader = new this.cjs.LoadQueue(false)
loader.addEventListener('fileload', function (e) {
if (e.item.type === 'image') {
// 將彩色圖片加載到assets庫
this.images[e.item.id] = e.result
}
}.bind(this))
loader.addEventListener('complete', this.start)
loader.loadManifest(this.assetsLib.properties.manifest)
},
start () {
this.initWaves()
this.startWave()
},

在上面代碼中,我們獲得一個loader,這個loader就來找與preloadjs庫提供的對象,然後添加一個’fileload’事件監控,一旦有文件加載成功後,我們提供的函數就會被調用。我們在該函數里查看加載的是否是圖像資源,如果是,那麼我們把images數組裡面的內容做相應修改。最後我們添加一個’complete’事件的監控,一旦所有資源加載完成後,該事件就會被觸發,於是start函數被調用,由此就啟動了遊戲進程。loadManifest函數的作用是,從assets庫定義的mainifest數組中讀取要加載的資源所在路徑。start函數的實現也簡單,只是啟動一個外星人攻擊衝擊波即可。

接下來我們要增加遊戲的資源約束,讓玩家在選擇建築物時受當前能量的約束,於是做如下修改:

getBuildingCostByType (type) {
// change 6
var building = this.getBuilding(type)
return building.cost
},

上面代碼會根據玩家選擇的建築物類型,獲得建築物建造所需的能量值。

satellite2 () {
....
// change 7
b.energyFrequency = 100
b.ticks = 0
this.satelliteList.push(b)
...
},
castle () {
....
// change8
b.cost = 80
b.tick = 0
},
castle2 () {
...
// change 9
b.cost = 300
b.tick = 0
this.castleList.push(b)
},
summonBullet (castle) {
var bullet = this.bullet(castle.damageDeal)
// change 10
bullet.x = Math.abs(castle.x + Math.random() * 20 - 10)
bullet.y = castle.y
this.addBullet(bullet)
},
removeBuilding (building) {
if (building === undefined) {
return

}
this.boardLayer.buildingMap[building.col][building.row] = undefined
this.boardLayer.removeChild(building)
// change 11 將建築物從衛星數組或炮臺數組中刪除
for (var i = 0; i < this.satelliteList.length; i++) {
if (this.satelliteList[i] === building) {
this.satelliteList.splice(i, 1)
break
}
}
for (i = 0; i < this.castleList.length; i++) {
if (this.castleList[i] === building) {
this.castleList.splice(i, 1)
break
}
}
},

上面代碼對一些建築物的生成添加了資源消耗量,並對以前一些好書做一些小修改,上面代碼完成後,加載頁面就可以看到豐富多彩的外星人從天而降了,至此我們的地球防禦遊戲的開發就結束了。

我們的遊戲其實可以增加更多功能,例如沒換一輪衝擊波時就改變遊戲的頁面背景,增加一個暫停按鈕,玩家萬一玩到一半突然尿急可以立刻暫停,等噓噓回來後繼續再戰,相星際爭霸一樣增加快捷鍵,玩家不用點來點去,只要快速按下快捷鍵就能在指定位置建造指定建築物,除了能量泡之外再引入新的資源,例如我們可以把上一節的鑽石和錢幣引進來,有很多好玩的,能改進遊戲特色的地方,就等著你動手實現了!


分享到:


相關文章: