Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm just wondering how to instantiate the same objects that all share the same variables, except their positions.

I'm basically working on the scene of my HTML5 game, and I've build a streetlamp post that turns on and off. All the lamps will have the same variables, such as Image, Size, on/off function. The only thing that will be different will be the position x and y.

I've built my lamp within a variable function (I think they're called that var = {), and within my actual game DrawFunction, I'm calling LampPost.draw();.

Is it possible to do something like this?

LampPost(0,0);
LampPost(100, 0);
LampPost(200, 0);

etc ... and then possibly place each instantiate Lamp within an array?

This is a snippet code for the lamp:

var LampPost = {

    lamp_xsprite : 0,
    lamp_ysprite : 0,

    light_xsprite : 0,
    lightysprite : 0,

    x : 440,
    y : 320,

    //Flicker effects
    lightFlicker : 0,
    seconds_Off : 0,
    seconds_On : 0,

    randomLength_Off : 500,
    randomLength_On : 150,


    draw: function(x, y) {

        this.x = x;
        this.y = y;

        ctxPropsOver.setTransform(1, 0, 0, 1, -Map.x + gameWidth/2, -Map.y + gameHeight/2);
        ctxPropsOver.rotate(Math.PI / -25);
        ctxPropsOver.clearRect(0, 0, 1000, 1000);

        ctxPropsOver.globalAlpha = this.lightFlicker;
        ctxPropsOver.drawImage(imgLights, 0, 36, 500, 463, -60 + this.x, -190 + this.y, 500, 463);
        ctxPropsOver.globalAlpha = 1;
        ctxPropsOver.drawImage(imgLights, 0, 0, 210, 36, 0 + this.x, 0 + this.y, 210, 36);

----- UPDATE -----

Okay, So I've converted it into an instance of object, this is what I have so far:

LampPost = function(lx, ly, la){

    x = lx; //500;
    y = ly; //335;

    centrex = 12;
    centrey = 17;

    rotate = la; //-8;

}

LampPost.prototype.draw = function (){

    ctxPropsOver.setTransform(1, 0, 0, 1, (-Map.x + gameWidth/2), (-Map.y + gameHeight/2) );

    ctxPropsOver.clearRect(0, 0, 1000, 1000);

    ctxPropsOver.save();
        ctxPropsOver.translate(this.x, this.y);
        ctxPropsOver.rotate(this.rotate*Math.PI/180);
        ctxPropsOver.translate(-this.centrex, -this.centrey);
        ctxPropsOver.globalAlpha = this.lightFlicker;
        ctxPropsOver.drawImage(imgLights, 0, 36, 500, 463, -60, -190, 500, 463);
        ctxPropsOver.globalAlpha = 1;
        ctxPropsOver.drawImage(imgLights, 0, 0, 210, 36, 0, 0, 210, 36);
    ctxPropsOver.restore();
};
share|improve this question
    
You could also try to look at typescriptlang.org –  Kikaimaru Jan 29 '13 at 17:40

3 Answers 3

up vote 3 down vote accepted

aha I see in your posted code that you created LampPost as a literal object, and not as an object to instantiate. So you'll do something like:

LampPost = function(x,y) {
  this.x = x;
  this.y = y;
  blah blah
}

LampPost.prototype.draw = function() {
  ctxPropsOver.translate(this.x, this.y);
  blah blah
}

var post = new LampPost(100, 0);
post.draw();

I suggest looking up JavaScript OOP, possibly by doing lessons on CodeAcademy

share|improve this answer
    
Thanks, I've changed it so its 'object to instantiate' (see update). Few questions, in createLampPost - why do I need to return Thing? as well as define the image location? < I am already defining that in the LampPost draw? Also, what are the both 'var post' doing? Thanks –  Oliver Jones Jan 28 '13 at 22:59
    
sorry if that was confusing, the original suggestion was before I noticed you were doing object literals instead of instantiating. I suppose I should remove that part, although I'll read what your question says now before I change stuff –  jhocking Jan 29 '13 at 18:28
    
oh and I just threw in the image location because in your original question you said to define Image for each lamp. If you don't actually need that, then you don't do that. As for 'var post' that is now the name of your object. In OOP you would use LampPost to define what all your lampposts will be like, while 'post' would be the name of one specific lamppost (ie. an instance). So then you would call post.draw() –  jhocking Jan 29 '13 at 18:31
    
I think in your updated code you need to type lines like 'this.x = lx;' and not just 'x = lx;' I'm not sure about that, but I think you need to do that to make sure it's a value attached to the object and not just a local variable in the constructor function. –  jhocking Jan 29 '13 at 18:36

Create a template object with all shared functions and member data. Then, use a create function to manufacture instances.

In the example below, you can provide arbitrary properties to be specified uniquely per instance, either overriding template parameters or adding new parameters unique to an instance.

Template for LampPost objects. Create instances with LampPostTemplate.create().

LampPostTemplate = {
  create:function(instanceVariableDictionary) {
    var result = createInstance(this, instanceVariableDictionary);
    //... any initialization code needed for LampPost instances.
    result.flickerAnimationTimeOffset = Math.random();
    return result;
  },
  draw:function() { /* ... */ },

  center:{x:.5, y:.5},
  position:{x:0, y:0},
  name:"Unnamed",
  flickerAnimation: [1,1,1,1,1,0,1,1,0,1,1,1,0],
  flickerAnimationTimeOffset: 0
};

Create instances:

Lamp1 = LampPostTemplate.create({ position:{x:1, y:2} });
Lamp2 = LampPostTemplate.create({
  position:{x:11, y:22},
  flickerAnimation:[1,0,0,0,0,1,0,0],
  name:"Hill top2"});

Here is the helper function to create copies of a template object and then copy arbitrary properties based on an input dictionary.

function createInstance(templateObject, instanceVariableDictionary) {
  var result = Object.create(templateObject);
  for (var property in instanceVariableDictionary) {
    if (typeof instanceVariableDictionary[property]['slice'] === 'function') {
      // Copy an array
      result[property] = instanceVariableDictionary[property].slice();
    } else if (typeof instanceVariableDictionary[property] === 'object') {
      // Copy an object
      result[property] = Object.create(instanceVariableDictionary[property]);
    } else {
      // Copy numbers, strings, ...
      result[property] = instanceVariableDictionary[property];
    }
  }
  return result;
};
share|improve this answer
    
Answers that are just code are not too useful. It would be better if you were to add some explanation about why this code would be good. –  Byte56 Jan 29 '13 at 17:58

You can use Object.create instead of new to explicitly set the object's prototype. This lets you easily implement the flyweight pattern. You can also set the prototype property of the constructor, though that's less flexible.

A more general for all languages solution is to split your objects between data and instance info. Eg your Lamppost instance just has a member referencing some LamppostData instance.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.