是否可以在纯 JavaScript 中为游戏中的单独实例存储静态对象数组?
Is it possible store static array of objects for separate instances in game in pure JavaScript?
我有 class StdObject
。我的目标是将其作为 superclass 并为继承自此 StdObject-class 的每个 classes 实例存储对象为每个对象存储数组。将调用 getAll()
存储为静态方法似乎更有意义。
class StdObject {
static objs = [];
//When creating new objects, these properties
//are used/set by default
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(); //Add this instance to the array
}
//Update is here if no update() is created in classes
//the extends this class
update() {};
//Render the objects to the canvas as rectangle
//If another shape should be used, just create a render() in that class
//to overwrite this method
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);
}
//Adds an object to objects array objs
static addObj() {
this.objs.push(this);
}
//Gets a specific object in array objs
static getObj(index) {
return this.objs[index];
}
//Get all objects (StdObject.getAll() is called instead of the actual class used)
//because there are no inheritance when static methods are used.
static getAll() {
console.log(this);
console.log('ALL OBJECTS=');
console.log(this.objs);
return this.objs;
}
}
class Ball extends StdObject {
constructor(x,y,width,height,speed) {
super(x,y,width,height,speed);
this.angle = 0;
this.shoot = 0;
this.moving = false;
this.speed = 0;
this.radius = 7;
}
update() {
//Move, update of positions for these balls etc
}
render() {
//Update to canvas
}
}
class Enemy extends StdObject {
constructor(x,y,width,height,speed) {
super(x,y,width,height,speed);
this.angle = 0;
this.shoot = 0;
this.moving = false;
this.speed = 0;
}
update() {
//Move, update of positions for these enemies etc
}
render() {
//Update to canvas
}
}
在游戏循环中我想做这样的事情:
var obl = StdObject.getAll().length;
function gameLoop() {
let i;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(i=0;i<obl;i++) {
StdObject.getObj[i].update();
}
for(i=0;i<obl;i++) {
StdObject.getObj[i].render();
}
window.requestAnimationFrame(gameLoop);
}
问题是 StdObject.getObj[i].update();
和 StdObject.getObj[i].render();
没有引用对象的实际实例(它们引用了 StdObject class 中静态数组内部的对象) .因此我得到错误
Uncaught TypeError:无法在 gameLoop
读取未定义的属性(读取 'update')
这可以用静态方法解决吗?(创建一个对象的实例只是为了检索该对象的所有实例是没有意义的。)
(是的,我知道我可以存储一个包含所有对象数组的全局变量,然后循环遍历它们并调用 update() 和 render() )
代码存在多个问题。
- 您正在尝试将函数作为数组调用,但它应该作为函数调用,StdObject.getObj(i).render() 而不是 StdObject.getObj[i].render();
- 在构造函数中创建实例时,它没有在数组 objs 中正确注册。
class StdObject {
static objs = [];
//When creating new objects, these properties
//are used/set by default
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;
StdObject.addObj(this); //Add this instance to the array
}
//Update is here if no update() is created in classes
//the extends this class
update() {};
//Render the objects to the canvas as rectangle
//If another shape should be used, just create a render() in that class
//to overwrite this method
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);
}
//Adds an object to objects array objs
static addObj(obj)
{
StdObject.objs.push(obj);
}
//Gets a specific object in array objs
static getObj(index) {
return this.objs[index];
}
//Get all objects (StdObject.getAll() is called instead of the actual class used)
//because there are no inheritance when static methods are used.
static getAll() {
console.log(this);
console.log('ALL OBJECTS=');
console.log(this.objs);
return this.objs;
}
}
class Ball extends StdObject {
constructor(x,y,width,height,speed) {
super(x,y,width,height,speed);
this.angle = 0;
this.shoot = 0;
this.moving = false;
this.speed = 0;
this.radius = 7;
}
update() {
//Move, update of positions for these balls etc
console.log('Ball update');
}
render() {
//Update to canvas
console.log('Ball render');
}
}
class Enemy extends StdObject {
constructor(x,y,width,height,speed) {
super(x,y,width,height,speed);
this.angle = 0;
this.shoot = 0;
this.moving = false;
this.speed = 0;
}
update() {
//Move, update of positions for these enemies etc
console.log('update enemy');
}
render() {
//Update to canvas
console.log('render enemy');
}
}
var enemy = new Enemy(100,100,10,10,0.4);
var ball = new Ball(100,100,10,10,0.4);
const ctx = document.getElementById('canvas').getContext('2d');
function gameLoop()
{
var obl = StdObject.getAll().length;
let i;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(i=0;i<obl;i++) {
StdObject.getObj(i).update();
}
for(i=0;i<obl;i++) {
StdObject.getObj(i).render();
}
window.requestAnimationFrame(gameLoop);
}
gameLoop();
我有 class StdObject
。我的目标是将其作为 superclass 并为继承自此 StdObject-class 的每个 classes 实例存储对象为每个对象存储数组。将调用 getAll()
存储为静态方法似乎更有意义。
class StdObject {
static objs = [];
//When creating new objects, these properties
//are used/set by default
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(); //Add this instance to the array
}
//Update is here if no update() is created in classes
//the extends this class
update() {};
//Render the objects to the canvas as rectangle
//If another shape should be used, just create a render() in that class
//to overwrite this method
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);
}
//Adds an object to objects array objs
static addObj() {
this.objs.push(this);
}
//Gets a specific object in array objs
static getObj(index) {
return this.objs[index];
}
//Get all objects (StdObject.getAll() is called instead of the actual class used)
//because there are no inheritance when static methods are used.
static getAll() {
console.log(this);
console.log('ALL OBJECTS=');
console.log(this.objs);
return this.objs;
}
}
class Ball extends StdObject {
constructor(x,y,width,height,speed) {
super(x,y,width,height,speed);
this.angle = 0;
this.shoot = 0;
this.moving = false;
this.speed = 0;
this.radius = 7;
}
update() {
//Move, update of positions for these balls etc
}
render() {
//Update to canvas
}
}
class Enemy extends StdObject {
constructor(x,y,width,height,speed) {
super(x,y,width,height,speed);
this.angle = 0;
this.shoot = 0;
this.moving = false;
this.speed = 0;
}
update() {
//Move, update of positions for these enemies etc
}
render() {
//Update to canvas
}
}
在游戏循环中我想做这样的事情:
var obl = StdObject.getAll().length;
function gameLoop() {
let i;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(i=0;i<obl;i++) {
StdObject.getObj[i].update();
}
for(i=0;i<obl;i++) {
StdObject.getObj[i].render();
}
window.requestAnimationFrame(gameLoop);
}
问题是 StdObject.getObj[i].update();
和 StdObject.getObj[i].render();
没有引用对象的实际实例(它们引用了 StdObject class 中静态数组内部的对象) .因此我得到错误
Uncaught TypeError:无法在 gameLoop
读取未定义的属性(读取 'update')这可以用静态方法解决吗?(创建一个对象的实例只是为了检索该对象的所有实例是没有意义的。)
(是的,我知道我可以存储一个包含所有对象数组的全局变量,然后循环遍历它们并调用 update() 和 render() )
代码存在多个问题。
- 您正在尝试将函数作为数组调用,但它应该作为函数调用,StdObject.getObj(i).render() 而不是 StdObject.getObj[i].render();
- 在构造函数中创建实例时,它没有在数组 objs 中正确注册。
class StdObject {
static objs = [];
//When creating new objects, these properties
//are used/set by default
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;
StdObject.addObj(this); //Add this instance to the array
}
//Update is here if no update() is created in classes
//the extends this class
update() {};
//Render the objects to the canvas as rectangle
//If another shape should be used, just create a render() in that class
//to overwrite this method
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);
}
//Adds an object to objects array objs
static addObj(obj)
{
StdObject.objs.push(obj);
}
//Gets a specific object in array objs
static getObj(index) {
return this.objs[index];
}
//Get all objects (StdObject.getAll() is called instead of the actual class used)
//because there are no inheritance when static methods are used.
static getAll() {
console.log(this);
console.log('ALL OBJECTS=');
console.log(this.objs);
return this.objs;
}
}
class Ball extends StdObject {
constructor(x,y,width,height,speed) {
super(x,y,width,height,speed);
this.angle = 0;
this.shoot = 0;
this.moving = false;
this.speed = 0;
this.radius = 7;
}
update() {
//Move, update of positions for these balls etc
console.log('Ball update');
}
render() {
//Update to canvas
console.log('Ball render');
}
}
class Enemy extends StdObject {
constructor(x,y,width,height,speed) {
super(x,y,width,height,speed);
this.angle = 0;
this.shoot = 0;
this.moving = false;
this.speed = 0;
}
update() {
//Move, update of positions for these enemies etc
console.log('update enemy');
}
render() {
//Update to canvas
console.log('render enemy');
}
}
var enemy = new Enemy(100,100,10,10,0.4);
var ball = new Ball(100,100,10,10,0.4);
const ctx = document.getElementById('canvas').getContext('2d');
function gameLoop()
{
var obl = StdObject.getAll().length;
let i;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(i=0;i<obl;i++) {
StdObject.getObj(i).update();
}
for(i=0;i<obl;i++) {
StdObject.getObj(i).render();
}
window.requestAnimationFrame(gameLoop);
}
gameLoop();