0

I'm making a 2D game in HTML5 canvas which will have a lot of objects. Some of the objects shares some properties with each other. Some of the properties will be for only one object. Objects may have an empty value property.

I want to to create a main object that will have the properties of all the objects. If there is an object with only 3 of the properties of the main object, the other properties will be empty.

For example, lets say that all the possible properties for any object in the game are {a,b,c,d,e,f,g} and we have 2 objects in the game ob0 & ob1.

ob0's properties are a,c,d so I will fill them only and the other properties {b,e,f} will be blank.

ob1's properties are b,e,f so I will fill them only and the other properties {a,c,d} will be blank.

I thought of this presentation because of two things. the first thing is that I'm not very good in OOP and inheritance and other OOP things. and the second thing is about 2 years ago, in a game called Red Alert2, there was a .INI file, and in the file were all the objects in the game. Data were represented like this way

[obj1]
color=red
width=100px
cankill=yes
[obj2]
weapontype:4
canswim=yes
weapontype=4
speed=20

For example, the property cankill is not in obj2 and obj2 couldn't kill in the game. But if you gave obj2 this property and gave it weapontype=10 it would kill in the game using the 10th weapon in the game. This tells me that if a property hasn't a value, it means that in the game it value will be zero or ??

Here comes my questions.

  1. How could that be done in JS? I mean can I really connect the .INI file with JS?

  2. Is there a more effective way to save the objects properties? I'm not asking to describe that way in two pages. I just want to know the main idea of that point.

  3. I thing my solution to this problem will experience the problem of overloaded size. If the game has 1000 properties, each object will be consisted of 1000 properties, when the object would need only 4 or 5 properties, and that will affect badly on the memory. How could that be solved?
Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52
Abozanona
  • 2,261
  • 1
  • 24
  • 60
  • 1
    This sounds similar to my question: http://stackoverflow.com/questions/5134208/jquery-oop-basics – XCS Mar 22 '15 at 22:03
  • Yes,it shows me a good way to start OOP, but I want to know all possible options for representing my objects. – Abozanona Mar 22 '15 at 22:08

2 Answers2

1

You can use the extending / default method of jQuery or Underscore and probably some other frameworks.

But I think the best / fastest way to extend an object is with vanilla javascript.

Please have a look at this SO question for an extending method.

In the following demo and in this jsFiddle I've added it with jQuery, Underscore and pure js. (jQuery and Underscore code is commented out.)

You can find a benchmark of these methods here. (I hope I've created the jsperf test correctly because it's my first test case there.)

To your questions:

  1. I would recommend to store your configuration in a JSON file because that's easier to load for your javascript.
  2. Yes, I think the best is to use prototypes for your properties. Because protos are only stored once and not for every instance.
  3. Should be no problem if you use prototypes. Because the object instance then got only the lower property count.

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);
Community
  • 1
  • 1
AWolf
  • 8,770
  • 5
  • 33
  • 39
0

If I understand it well

  • You have multiple objects
  • Those objects share their property names, but not necessarily the values

Then I think the simplest way is using plain objects, and ignore the fact that they share property names.

Therefore,

[obj1]
color=red
width=100px
cankill=yes
[obj2]
weapontype:4
canswim=yes
weapontype=4
speed=20

would become

var obj1 = {
    color: "red",
    width: "100px",
    cankill: true
}, obj2 = {
    weapontype: 4,
    canswim: true,
    weapontype: 4,
    speed: 20
};
Oriol
  • 274,082
  • 63
  • 437
  • 513