如何创建共享某些属性的对象

时间:2015-03-22 21:55:59

标签: javascript object ini

我在HTML5画布中制作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方面都不是很好。第二件事是大约2年前,在一个名为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种武器杀死它。这告诉我,如果一个属性没有一个值,这意味着在游戏中它的值将为零或??

这是我的问题。

  1. 如何在JS中完成?我的意思是我真的能将.INI文件与JS连接起来吗?

  2. 是否有更有效的方法来保存对象属性?我并没有要求在两页中描述这种方式。我只想知道这一点的主要观点。

  3. 我的解决方案是这个问题会遇到超载大小​​的问题。如果游戏有1000个属性,则每个对象将由1000个属性组成,当对象只需要4或5个属性时,这将对内存造成严重影响。怎么能解决?

2 个答案:

答案 0 :(得分:1)

您可以使用jQuery或Underscore的扩展/默认方法,也可以使用其他一些框架。

但我认为扩展对象的最佳/最快方法是使用vanilla javascript。

请查看此SO question以获取扩展方法。

在下面的演示中以及jsFiddle中,我添加了jQuery,Underscore和纯js。 (jQuery和Underscore代码被注释掉了。)

您可以找到这些方法的基准here。 (我希望我已经正确创建了jsperf测试,因为这是我在那里的第一个测试用例。)

问题:

  1. 我建议您将配置存储在JSON文件中,因为这样可以更轻松地为您的javascript加载。
  2. 是的,我认为最好是为您的物业使用原型。因为protos只存储一次而不是每个实例。
  3. 如果你使用原型应该没问题。因为对象实例只获得较低的属性数。
  4. 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: https://stackoverflow.com/questions/10430279/javascript-object-extending
        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);

答案 1 :(得分:0)

如果我理解得很好

  • 您有多个对象
  • 这些对象共享其属性名称,但不一定是值

然后我认为最简单的方法是使用普通对象,并忽略它们共享属性名称的事实。

因此,

[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
};