kos/web/src/assets/scripts/AcGameObject.js
2023-02-11 18:51:00 +08:00

83 lines
2.5 KiB
JavaScript

// 该类作为基类使用,用于刷新绘制
// 定义绘制对象数组,存放每一帧绘制的对象
const AC_GAME_OBJECTS = [];
// 导出类
export class AcGameObject {
// 构造函数
constructor(){
// push(this) 是将当前对象存下来的意思
// 每创建一个,就 push 一个,先创建先 push,后创建后 push
// 先创建的先执行 update ,后创建的会把先创建的给覆盖掉
AC_GAME_OBJECTS.push(this);
// 帧与帧执行的时间间隔
this.timedelta=0;
// 是否执行过 start 函数
this.has_called_start = false;
}
// start 函数只执行一次
start(){
}
// 除第一帧之外,每一帧执行一遍
update(){
}
// 删除之前执行
on_destroy(){
}
// 删除
destroy(){
// 删除之前调用 on_destroy 函数
this.on_destroy();
// 在 js 里,使用 of 遍历的是数组里的值;使用 in 遍历的是数组的下标。
for(let i in AC_GAME_OBJECTS){
const obj = AC_GAME_OBJECTS[i];
// 如果 obj 等于当前对象,则删除该对象
if(obj === this){
// 使用 splice 删除数组里的对象
AC_GAME_OBJECTS.splice(i);
break;
}
}
}
}
// 上一帧执行的时刻
let last_timestamp;
// step 函数需要传入当前帧执行的时刻 timestamp
const step = (timestamp) => {
// 遍历所有的物品
// 在 js 里,使用 of 遍历的是数组里的值;使用 in 遍历的是数组的下标。
for(let obj of AC_GAME_OBJECTS){
// 如果当前物品没有执行 start 函数,则该物品执行一次 start 函数
if(!obj.has_called_start){
// 将该物品的 has_called_start 赋值为 true,表示其已经执行过了
obj.has_called_start = true;
obj.start();
}
// 如果执行过 start ,则接下来应该执行 update 函数
else{
// 当前帧与上一帧的时间间隔:当前帧执行时刻减去上一帧执行时刻
obj.timedelta = timestamp - last_timestamp;
obj.update();
}
}
// 更新 last_timestamp ,作为下一次更新的“上一帧执行的时刻”
last_timestamp = timestamp;
// 递归调用
requestAnimationFrame(step)
}
// 定义需要的刷新次数,传入的函数step会在下一帧浏览器渲染之前执行一遍。
requestAnimationFrame(step)