自己写一个简单的游戏对象基类
我希望所有的游戏对象都保存在一个集合中,这里我简单使用一个数组保存,即GAME_OBJECT
,在这之后,所有GameObject类的对象在创建后,都会被保存在GAME_OBJECT
数组中。
为了做到上述这一点,在GameObject
的constructor
中,加入这一行代码GAME_OBJECT.push(this)
为了不让游戏对象过多,要记得在对象被销毁时将对象在GAME_OBJECT
中删除,即以下代码:
destroy() {
this.beforeDestroy()
GAME_OBJECT.splice(GAME_OBJECT.indexOf(this), 1)
}
要想在浏览器中使对象按每秒60帧的帧率执行对象中的函数,我们需要利用requestAnimationFrame
这个函数。它可以接收一个函数,我们在这个函数中递归调用requestAnimationFrame
就可以持续执行下去。
let last_timestamp
const step = (timestamp) => {
for (let obj of GAME_OBJECT) {
if (obj.has_called_start === false) {
obj.has_called_start = true
obj.start()
} else {
obj.timedelta = timestamp - last_timestamp
obj.update()
}
}
last_timestamp = timestamp
requestAnimationFrame(step)
}
requestAnimationFrame(step)
这里我们需要记录一下当前帧与上一帧之间的时间间隔,单位为毫秒,即timedelta
我们有时还需要在对象创建的第一时间做些初始化工作,所以可以实现一个start()
函数,为了实现start
函数只执行一次,可以定义一个变量has_called_start
,用于判断是否执行了start
函数。
总的函数实现
const GAME_OBJECT = []
class GameObject {
constructor() {
GAME_OBJECT.push(this)
this.timedelta = 0
this.has_called_start = false
}
start() {}
update() {}
beforeDestroy() {}
destroy() {
this.beforeDestroy()
GAME_OBJECT.splice(GAME_OBJECT.indexOf(this), 1)
}
}
let last_timestamp
const step = (timestamp) => {
for (let obj of GAME_OBJECT) {
if (obj.has_called_start === false) {
obj.has_called_start = true
obj.start()
} else {
obj.timedelta = timestamp - last_timestamp
obj.update()
}
}
last_timestamp = timestamp
requestAnimationFrame(step)
}
requestAnimationFrame(step)
export default GameObject
评论区