如何创建共享某些属性的对象
How to create objects that share some properties
我正在 HTML5 canvas 中制作一个 2D 游戏,其中会有很多对象。一些对象彼此共享一些属性。某些属性将仅适用于一个对象。对象可能有空值 属性.
我想创建一个具有所有对象属性的主对象。如果有一个对象只有主对象的3个属性,其他属性将为空。
例如,假设游戏中任何对象的所有可能属性都是 {a,b,c,d,e,f,g},我们在游戏中有 2 个对象 ob0
& ob1
.
ob0
的属性是a,c,d所以我只填充它们,其他属性{b,e,f}将是空白。
ob1
的属性是b,e,f所以我只填充它们,其他属性{a,c,d}将是空白。
我想到这个演示文稿是因为两件事。首先是我不太擅长 OOP 和继承以及其他 OOP 方面的东西。第二件事是大约两年前,在一个叫Red Alert2
的游戏里,有一个.INI
的文件,里面就是游戏中的所有物品。数据是这样表示的
[obj1]
color=red
width=100px
cankill=yes
[obj2]
weapontype:4
canswim=yes
weapontype=4
speed=20
例如属性 cankill
不在obj2
中,obj2
无法在游戏中击杀。但是如果你给了 obj2
这个 属性 并且给了它 weapontype=10
它会在游戏中使用游戏中的第 10 把武器杀死它。这告诉我,如果 属性 没有值,则意味着在游戏中它的值将为零或 ??
我的问题来了。
在 JS 中如何实现?我的意思是我真的可以将 .INI
文件与 JS
连接起来吗?
有没有更有效的保存对象属性的方法?我不是要求用两页来描述这种方式。我只想知道那一点的主要思想。
- 我认为我对这个问题的解决方案会遇到大小过载的问题。如果游戏有1000个属性,每个对象将由1000个属性组成,当对象只需要4或5个属性时,这将对内存造成严重影响。那怎么解决呢?
如果我理解的很好
- 您有多个对象
- 这些对象共享它们的 属性 名称,但不一定共享值
然后我认为最简单的方法是使用普通对象,忽略它们共享 属性 个名称的事实。
因此,
[obj1]
color=red
width=100px
cankill=yes
[obj2]
weapontype:4
canswim=yes
weapontype=4
speed=20
会变成
var obj1 = {
color: "red",
width: "100px",
cankill: true
}, obj2 = {
weapontype: 4,
canswim: true,
weapontype: 4,
speed: 20
};
您可以使用 jQuery 或 Underscore 的扩展/默认方法,可能还有一些其他框架。
但我认为扩展对象的最佳/最快方法是使用 vanilla javascript。
请查看此 SO question 以了解扩展方法。
在下面的演示和这个 jsFiddle 中,我添加了 jQuery、下划线和纯 js。 (jQuery 和下划线代码被注释掉。)
您可以找到这些方法的基准 here。 (我希望我已经正确创建了 jsperf 测试,因为这是我的第一个测试用例。)
针对您的问题:
- 我建议将您的配置存储在 JSON 文件中,因为这样更容易为您的 javascript.
加载
- 是的,我认为最好是为您的属性使用原型。因为原型只存储一次,而不是每个实例。
- 使用原型应该没问题。因为对象实例只得到较低的 属性 计数。
var GameObject = {
// init and other methods can be defined here
};
GameObject.prototype = {
color: undefined, // undefined properties will be removed by jQuery.extend
canKill: undefined,
width: undefined,
speed: undefined,
weaponType: undefined
};
// pure javascript extending
Object.prototype.extend = function (obj) {
// source from this SO question:
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
this[i] = obj[i];
}
}
};
var ob1 = Object.create(GameObject);
ob1.extend({
color: 'red',
canKill: 'yes'
});
var ob2 = Object.create(GameObject);
ob2.extend({
color: 'green',
canKill: 'no',
speed: 10
});
/*
// with underscore.defaults
var ob1 = _.defaults(Object.create(GameObject), {
color: 'red',
canKill: 'yes'
});
var ob2 = _.defaults(Object.create(GameObject), {
color: 'green',
canKill: 'no',
speed: 10
});
*/
/*
// with jQuery.extend(...)
var ob1 = $.extend(true, Object.create(GameObject), {
// true = deep copy, new GameObject = target, source object
color: 'red',
canKill: 'yes'
});
var ob2 = $.extend(true, Object.create(GameObject), {
color: 'green',
canKill: 'no',
speed: 10
});
*/
//console.log(ob1.prototype);
console.log(ob1, ob1.color, ob1.canKill);
console.log(ob2, ob2.color, ob2.canKill, ob2.speed);
//console.log(GameObject, GameObject.prototype);
我正在 HTML5 canvas 中制作一个 2D 游戏,其中会有很多对象。一些对象彼此共享一些属性。某些属性将仅适用于一个对象。对象可能有空值 属性.
我想创建一个具有所有对象属性的主对象。如果有一个对象只有主对象的3个属性,其他属性将为空。
例如,假设游戏中任何对象的所有可能属性都是 {a,b,c,d,e,f,g},我们在游戏中有 2 个对象 ob0
& ob1
.
ob0
的属性是a,c,d所以我只填充它们,其他属性{b,e,f}将是空白。
ob1
的属性是b,e,f所以我只填充它们,其他属性{a,c,d}将是空白。
我想到这个演示文稿是因为两件事。首先是我不太擅长 OOP 和继承以及其他 OOP 方面的东西。第二件事是大约两年前,在一个叫Red Alert2
的游戏里,有一个.INI
的文件,里面就是游戏中的所有物品。数据是这样表示的
[obj1]
color=red
width=100px
cankill=yes
[obj2]
weapontype:4
canswim=yes
weapontype=4
speed=20
例如属性 cankill
不在obj2
中,obj2
无法在游戏中击杀。但是如果你给了 obj2
这个 属性 并且给了它 weapontype=10
它会在游戏中使用游戏中的第 10 把武器杀死它。这告诉我,如果 属性 没有值,则意味着在游戏中它的值将为零或 ??
我的问题来了。
在 JS 中如何实现?我的意思是我真的可以将
.INI
文件与JS
连接起来吗?有没有更有效的保存对象属性的方法?我不是要求用两页来描述这种方式。我只想知道那一点的主要思想。
- 我认为我对这个问题的解决方案会遇到大小过载的问题。如果游戏有1000个属性,每个对象将由1000个属性组成,当对象只需要4或5个属性时,这将对内存造成严重影响。那怎么解决呢?
如果我理解的很好
- 您有多个对象
- 这些对象共享它们的 属性 名称,但不一定共享值
然后我认为最简单的方法是使用普通对象,忽略它们共享 属性 个名称的事实。
因此,
[obj1]
color=red
width=100px
cankill=yes
[obj2]
weapontype:4
canswim=yes
weapontype=4
speed=20
会变成
var obj1 = {
color: "red",
width: "100px",
cankill: true
}, obj2 = {
weapontype: 4,
canswim: true,
weapontype: 4,
speed: 20
};
您可以使用 jQuery 或 Underscore 的扩展/默认方法,可能还有一些其他框架。
但我认为扩展对象的最佳/最快方法是使用 vanilla javascript。
请查看此 SO question 以了解扩展方法。
在下面的演示和这个 jsFiddle 中,我添加了 jQuery、下划线和纯 js。 (jQuery 和下划线代码被注释掉。)
您可以找到这些方法的基准 here。 (我希望我已经正确创建了 jsperf 测试,因为这是我的第一个测试用例。)
针对您的问题:
- 我建议将您的配置存储在 JSON 文件中,因为这样更容易为您的 javascript. 加载
- 是的,我认为最好是为您的属性使用原型。因为原型只存储一次,而不是每个实例。
- 使用原型应该没问题。因为对象实例只得到较低的 属性 计数。
var GameObject = {
// init and other methods can be defined here
};
GameObject.prototype = {
color: undefined, // undefined properties will be removed by jQuery.extend
canKill: undefined,
width: undefined,
speed: undefined,
weaponType: undefined
};
// pure javascript extending
Object.prototype.extend = function (obj) {
// source from this SO question:
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
this[i] = obj[i];
}
}
};
var ob1 = Object.create(GameObject);
ob1.extend({
color: 'red',
canKill: 'yes'
});
var ob2 = Object.create(GameObject);
ob2.extend({
color: 'green',
canKill: 'no',
speed: 10
});
/*
// with underscore.defaults
var ob1 = _.defaults(Object.create(GameObject), {
color: 'red',
canKill: 'yes'
});
var ob2 = _.defaults(Object.create(GameObject), {
color: 'green',
canKill: 'no',
speed: 10
});
*/
/*
// with jQuery.extend(...)
var ob1 = $.extend(true, Object.create(GameObject), {
// true = deep copy, new GameObject = target, source object
color: 'red',
canKill: 'yes'
});
var ob2 = $.extend(true, Object.create(GameObject), {
color: 'green',
canKill: 'no',
speed: 10
});
*/
//console.log(ob1.prototype);
console.log(ob1, ob1.color, ob1.canKill);
console.log(ob2, ob2.color, ob2.canKill, ob2.speed);
//console.log(GameObject, GameObject.prototype);