35

I'm somewhat new to Javascript, so maybe this is just a noob mistake, but I haven't found anything that specifically helps me while looking around. I'm writing a game, and I'm trying to build an object for the pause menu.

One of the things I would like to do is have the buttons on the menu be objects inside of the pause_menu object for the sake of organization. I'm eventually going to add event handlers to these objects, and I'd like to do that inside the pause_menu object as well. Some of the button's aren't fully coded yet, but I'd like to get at least something working before I keep going.

I'm using Raphael.js v1.5.2 to render the shapes. The Raphael stuff works for the rest of the interface, but the code for that is not as pleasant to look at as this, so something similar to this would be preferable to me.

My current problem is that nothing actually renders when I do var pause_menu = new pause_menu();

This is the code I have so far for the pause menu:

//Pause Menu Object:
function pause_menu() {

    function pause_button() {
        this.button = game.rect(0, 350, 150, 50, 5);
        this.text =  game.text(75, 375, 'PAUSE');
    }
    function resume_button() {
        this.button;
        this.text;
    }
    function quit_button() {
        this.button;
        this.text;
    }
    this.pause_button = new pause_button(); //the button that the user presses to pause the game (I want an event handler on this to trigger .show() method for presently hidden menu items)
    this.resume_button = new resume_button();
    this.quit_button = new quit_button();
    this.box = game.rect(150, 50, 400, 300, 5).hide(); //the box that surrounds the menu when it appears
}
var pause_menu = new pause_menu();

OK, so here's the solution (with an event handler):

var pause_menu = {

    pause_button: { button : game.rect(0, 350, 150, 50, 5).click(function (event){
                       pause_menu.menu_box.show();
                  }), text : game.text(75, 375, 'PAUSE') },
    menu_box: game.rect(150, 50, 400, 300, 5).hide(),
    resume_button: {},
    quit_button: {}

};
Michael Taufen
  • 1,704
  • 1
  • 17
  • 22
  • Not sure where the issue is without the rest of the code, but be aware that you're overwriting your `pause_menu` function when you do `var pause_menu = new pause_menu();` in the same variable scope as the function. – user113716 Jun 21 '11 at 18:19
  • Thanks patrick, in the actual game `var pause_menu = new pause_menu();` is not in the same scope as the function. Does it overwrite because the name of the variable is the same as the function? – Michael Taufen Jun 21 '11 at 19:33
  • well looks like you need to create a render() method that renders the game.rect() instances? – Nathan Romano Jun 21 '11 at 18:14
  • I'd suggest you have a look at this [SO Answer](http://stackoverflow.com/questions/1704618/what-is-the-difference-between-var-thing-and-function-thing-in-javascript/1704981#1704981). – Lance Jun 21 '11 at 18:18

2 Answers2

40
var pause_menu = {
    pause_button : { someProperty : "prop1", someOther : "prop2" },
    resume_button : { resumeProp : "prop", resumeProp2 : false },
    quit_button : false
};

then:

pause_menu.pause_button.someProperty //evaluates to "prop1"

etc etc.

Ethaan
  • 11,291
  • 5
  • 35
  • 45
Jonathan
  • 1,866
  • 12
  • 10
24

You may have as many levels of Object hierarchy as you want, as long you declare an Object as being a property of another parent Object. Pay attention to the commas on each level, that's the tricky part. Don't use commas after the last element on each level:

{el1, el2, {el31, el32, el33}, {el41, el42}}

var MainObj = {

  prop1: "prop1MainObj",
  
  Obj1: {
    prop1: "prop1Obj1",
    prop2: "prop2Obj1",    
    Obj2: {
      prop1: "hey you",
      prop2: "prop2Obj2"
    }
  },
    
  Obj3: {
    prop1: "prop1Obj3",
    prop2: "prop2Obj3"
  },
  
  Obj4: {
    prop1: true,
    prop2: 3
  }  
};

console.log(MainObj.Obj1.Obj2.prop1);
João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
  • 1
    trailing commas are ok in javascript. It is in the ecma-script specs since es5 (I think all the way down to es3 even). But IE8 and below didn't honor this so they would error out on encountering a "dangling comma". All that to say, it is perfectly fine to use a comma at the end of the final element. Indeed, it is often preferred now days. – the chad Dec 05 '18 at 14:42
  • @thechad why it is preferable to use traling commas on the last element of the object? – Aónio Feb 13 '19 at 13:21
  • 2
    @Aónio it is not a big deal either way. IMO it is nice to just be able to add new key values without having to remember to add a comma before hand. (trailing comma is fine, but forgetting to separate with commas is indeed an error). To say it is often "preferred" might have been too strong a statement, maybe "common practice" might be more accurate. "Preferred" kind of makes it sound like a bigger deal than it is... – the chad Feb 14 '19 at 14:36
  • 1
    "Trailing commas in JSON. Trailing commas in objects were only introduced in ECMAScript 5. As JSON is based on JavaScript's syntax prior to ES5, trailing commas are not allowed in JSON" Just found that explanation, my comment was to this specific post, where the author is using object literals and not JSON. Just wanted to be clear about that – the chad Feb 14 '19 at 14:39
  • @thechad I'd say for pedagogical reasons we should not confuse the readers. Trailing commas are "acceptable" but may lead to confusions, like you said in JSON, or even arrays `var arr = [1, 2,]` – Aónio Jun 25 '19 at 13:26