微信小游戲 demo 飛機大戰 代碼分析(二)(databus.js)
微信小游戲 demo 飛機大戰 代碼分析(一)(main.js)
微信小游戲 demo 飛機大戰 代碼分析(三)(spirit.js, animation.js)
微信小游戲 demo 飛機大戰 代碼分析(四)(enemy.js, bullet.js, index.js)
本博客將使用逐行代碼分析的方式講解該demo,本文適用於對其他高級語言熟悉,對js還未深入了解的同學,博主會盡可能將所有遇到的不明白的部分標注清楚,若有不正確或不清楚的地方,歡迎在評論中指正
本文的代碼均由微信小游戲自動生成的demo飛機大戰中獲取
databus.js
代碼:
import Pool from './base/pool'
let instance
/**
* 全局狀態管理器
*/
export default class DataBus {
constructor() {
if ( instance )
return instance
instance = this
this.pool = new Pool()
this.reset()
}
reset() {
this.frame = 0
this.score = 0
this.bullets = []
this.enemys = []
this.animations = []
this.gameOver = false
}
/**
* 回收敵人,進入對象池
* 此后不進入幀循環
*/
removeEnemey(enemy) {
let temp = this.enemys.shift()
temp.visible = false
this.pool.recover('enemy', enemy)
}
/**
* 回收子彈,進入對象池
* 此后不進入幀循環
*/
removeBullets(bullet) {
let temp = this.bullets.shift()
temp.visible = false
this.pool.recover('bullet', bullet)
}
}
instance
- 該對象用於承載該文件中惟一的databus類,實現單例模式
- 單例模式是一種設計模式,保證全局僅有一個該類的對象,這樣能在該demo中保證全局數據的一致性
constructor
構造器
- 如果instance不為空已經存在,那么就返回instance
- 這是實現單例模式,保證不管多少次new都只能產生一個對象
- 如果不為空,將instance設置為自身,並進行下列初始化操作
- 創建一個對象池pool
- 對象池技術是通過將生成的對象暫時保存於池中,需要對象時先在池中查看是否有多余對象,若不足再生成對象,而在銷毀對象時不進行真正銷毀,而是加入對象池中
- 重置所有內容,設置為空
- 創建一個對象池pool
removeEnemey(enemy)
移除某個敵方對象(敵機)
- 從enemys數組中獲取第一個元素
- shift方法是js中移除第一個元素並返回的方法
- 設置其不可見
- 移入名為enemy的池中
removeBullet(bullet)
移除某一個子彈
操作方式同上一個函數相同
pool.js
一個用於實現對象池的函數
代碼:
const __ = {
poolDic: Symbol('poolDic')
}
/**
* 簡易的對象池實現
* 用於對象的存貯和重復使用
* 可以有效減少對象創建開銷和避免頻繁的垃圾回收
* 提高游戲性能
*/
export default class Pool {
constructor() {
this[__.poolDic] = {}
}
/**
* 根據對象標識符
* 獲取對應的對象池
*/
getPoolBySign(name) {
return this[__.poolDic][name] || ( this[__.poolDic][name] = [] )
}
/**
* 根據傳入的對象標識符,查詢對象池
* 對象池為空創建新的類,否則從對象池中取
*/
getItemByClass(name, className) {
let pool = this.getPoolBySign(name)
let result = ( pool.length
? pool.shift()
: new className() )
return result
}
/**
* 將對象回收到對象池
* 方便后續繼續使用
*/
recover(name, instance) {
this.getPoolBySign(name).push(instance)
}
}
const __
用於防止魔術字符串出現的常量列表
- Symbol
- 在js中反復用於獲取某些值或者對象的字符串稱為魔術字符串,如果字符串過多,正常使用可以,但是若需要修改,則需要同時修改多個字符串,非常不利於維護
- 為了解決這個問題,ES6引入了一個新的數據類型Symbol,用於存儲這些字符串類型,而之后需要用到該字符串僅需要用該常量取得
- symbol類型為類似於字符串的類型,不能使用new命令,也不能添加屬性
- 在這里聲明了一個對象名稱為poolDic,用於保存多個對象池的一個字典
constructor()
- 創建一個空的poolDic
getPoolBySign(name)
- 根據傳入的名稱獲取相應的對象池,若不存在則生成一個新的,以一個數組來作為對象池
getItemByClass(name, className)
獲取對象
- 獲取相應對象池
- 判斷對象池是否為空,若不為空,返回第一個元素,並從對象池中移除
- 若不為空,則用傳入的類名生成新的一個對象
recover(name, instance)
回收對象
- 獲取對象池並向其中推入元素
- push是js數組中的操作,用於將元素打入數組當中
