纯JavaScript游戏中如何用静态方法为子类实例存储静态对象数组
问题根因
- 错误1:
StdObject.getObj[i]语法错误,getObj是静态方法,需要用括号传参调用,而非方括号取下标 - 错误2:
addObj静态方法逻辑错误,构造函数中调用addObj时没有传入实例,方法内this指向类本身,导致数组里存储的是类而非实例对象 - 可选优化点:全局提前存储数组长度
obl不会随后续新增实例动态更新,建议每次循环获取最新数组
基于静态方法的解决方案
第一步:修改StdObject类相关逻辑
class StdObject { static objs = []; constructor(x=null,y=0,width=10,height=10,speed=0.4) { if (x == null) x = Math.floor(Math.random() * canvas_width); this.x = x; this.y = y; this.width = width; this.height = height; this.speed = speed; this.friction = 0.3; this.color = '#000000'; this.gravity = 0; // 传入当前实例到静态方法 this.constructor.addObj(this); } update() {}; render() { ctx.clearRect(this.x, this.y, this.width, this.height); ctx.fillStyle = this.color; ctx.fillRect(this.x, this.y, this.width, this.height); } // 接收实例参数存入数组 static addObj(instance) { this.objs.push(instance); } static getObj(index) { return this.objs[index]; } static getAll() { return this.objs; } } // 子类Ball、Enemy代码无需修改
第二步:修改游戏循环逻辑
直接遍历getAll()返回的实例数组即可,无需手动处理下标:
function gameLoop() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 每次循环获取最新的实例数组 const allInstances = StdObject.getAll(); // 批量调用update allInstances.forEach(obj => obj.update()); // 批量调用render allInstances.forEach(obj => obj.render()); window.requestAnimationFrame(gameLoop); }
如果要保留原有下标写法,修改调用语法即可:
function gameLoop() { ctx.clearRect(0, 0, canvas.width, canvas.height); const obl = StdObject.getAll().length; for(let i=0;i<obl;i++) { StdObject.getObj(i).update(); } for(let i=0;i<obl;i++) { StdObject.getObj(i).render(); } window.requestAnimationFrame(gameLoop); }
该方案完全基于静态方法实现,不需要额外创建管理实例,也不需要额外的全局变量存储数组,符合需求。
内容的提问来源于stack exchange,提问作者bestprogrammerintheworld
相关产品推荐
相关产品推荐

