【问题标题】:How to create objects that share some properties如何创建共享某些属性的对象
【发布时间】:2015-03-22 21:55:58
【问题描述】:

我正在 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 个属性,这会严重影响内存。怎么可能解决?

【问题讨论】:

标签: javascript object ini


【解决方案1】:

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

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

请查看SO question 了解扩展方法。

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

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

对于您的问题:

  1. 我建议将您的配置存储在 JSON 文件中,因为这样更容易为您的 javascript 加载。
  2. 是的,我认为最好的方法是为您的属性使用原型。因为原型只存储一次,而不是每个实例。
  3. 如果你使用原型应该没问题。因为对象实例只获得了较低的属性计数。

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);

【讨论】:

    【解决方案2】:

    如果我理解得很好

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

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

    因此,

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

    【讨论】:

    • 不,属性可能不同。
    猜你喜欢
    • 1970-01-01
    • 2018-12-24
    • 2014-07-17
    • 1970-01-01
    • 2018-06-07
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    相关资源
    最近更新 更多