Jump to content

Need Less Flexibility - More Guidance Please


LokisHood
 Share

Recommended Posts

As someone whose main job is a web dev using jQuery I'm struggling to decide on the best approach to structuring my code now I'm onto states .

 

I appreciate Richard not forcing you to use any particular method but I'd really appreciate being told what method to use right (best practice).

 

I've seen 2 major ways of creating states:
 

1. In the Examples Repo:

Rox.MainMenu = function (game) {    this.music = null;    this.playButton = null;};// Use of "prototype" indicates "prototype pattern"?Rox.MainMenu.prototype = {    create: function () {        this.add.image(390, 360, 'photonstorm');        this.input.onDown.addOnce(this.startGame, this);    },    update: function () {    },    startGame: function (pointer) {        this.state.start('Game');    }};

2. In LessMilks Flappy Bird Tutorial:

// "Object literal notation"?var menu_state = {    create: function() {        var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);        space_key.onDown.add(this.start, this);         var style = { font: "30px Arial", fill: "#ffffff" };        var x = game.world.width/2, y = game.world.height/2;                var text = this.game.add.text(x, y-50, "Press space to start", style);        text.anchor.setTo(0.5, 0.5);         if (score > 0) {            var score_label = this.game.add.text(x, y+50, "score: " + score, style);            score_label.anchor.setTo(0.5, 0.5);         }    },    start: function() {        this.game.state.start('play');    }}

My ultimate question (without starting a 'religious' war) is: Which of these is best practice way of structuring a game with multiple states like this?

 

Secondly - what are the relative advantages/disadvantages to using either of these methods?

 

 

Really hoping you can help - I've been reading "Learning JavaScript Design Patterns" by Addy Osmani as well as checking SO to get some insight but the book is just confusing me with even more JS possible patterns so I'm looking to you guys for some prodding in the right direction. :)

Link to comment
Share on other sites

The prototype approach gives you the option of easily creating a new instance of the state if you wanted to. In other words you can reuse the state over and over without having to duplicate code.  One use case for this might be procedural or random level generation.  Hopefully my meaning is clear here, but if not let me know and I can explain further.

Link to comment
Share on other sites

I think the reuse argument is not so relevant to most people. I never reused a state. You question is a fundamental one to JS programming- many people ask if they should use prototypes or stick to object literals (that is: using x = {}, your second version ). For the usage as a Phaser state, there is really no advantage or disadvantage between them.

 

I guess you're not using classes in JS yet, are you ? Because then you would have already made the decision for variant 1 as you would be comfort with prototypes.

if you're not able to make a decision: Choose variant 1. Maybe this leads you to learn JS classes - and THAT would be a huge win for you! So go for variant 1 and with this look into classes & prototypes in JS.

 

There is a compact reading I always recommend for beginners with some experience in programming: 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

 

Enjoy!

Regards George

 

 

Edit/By the way:

You will also see the second version when someone (who usually uses variant 1) wants to create a fast & dirty example in phaser. It's simply faster to write a short literal than the whole prototype stuff.

Link to comment
Share on other sites

Yeah, I totally agree with george. If you are going to be using classes (or anything with an inheritance structure), it is best to learn how the prototype property of objects works and when to use it. That can save you a great deal of code writing for larger projects. Trying to write object literals of everything would just be a waste of time in many cases.

 

As for game states specifically, I agree with both sleekdigital and george. Since new instances of an object have all previously prototype properties defined for that object, it can make sense to define how, for example, a menu works once and then have subclasses only change simple settings. That could save you some time and lines of code, definitely. (However, like george, I rarely use this approach myself.)

 

On the other hand, the disadvantage for associating all game objects to a specific state is that you can't easily use them outside of that scope without making a new reference. And switching between states is destructive too. Keep in mind that moving between a 'menu' and 'game' state means that all objects bound to the 'menu' state's 'this' scope will be wiped out.

 

So, if we are talking about combining different patterns, I personally use a module pattern on a global level, creating a function closure and passing in the 'Phaser' object. Then, for my own sprites, I make subclasses of Phaser.Sprite and use a prototype pattern for the states themselves. That way, I can have a singleton instance of a player object existing outside of any one state and then move (update its coordinates) between states. (This is more useful when I map states to different levels. Each state's change is a level load.)

 

 

However, as george wrote, which pattern to use is often dictated by how comfortable you are with JavaScript's prototype property. And generally what problem you are trying to solve too. All the different patterns are to solve different problems. Some can be used as solutions to the same issues, but not always. Or not without some knowledge of how they work in the first place and why they happen to solve a certain problem.

Link to comment
Share on other sites

Some really. really helpful answers. Thank you so much to sleekdgital, george and Videlais! You've been more than helpful.

 

Strangely enough I find classes (in Java, PHP, Python) easy to grasp. But when I start using Javascript I'm completely thrown by the use of "prototype" and insistance that JS isn't class-based although it can behave like it.

 

I'm giving your link a read George as it looks to answer some of my biggest questions on JS in general - thank you.

 

Once more into the breach!  :ph34r:

Link to comment
Share on other sites

With the risk of diving into a lesson on JavaScript objects and the prototype chain, I've found a lot of the frustration people coming to JavaScript from other OOP languages have is that JavaScript isn't a typed language. That's the root of most of the issues between, say, coming to JS from Java, for example. Because JavaScript isn't a typed language, you can bind properties to nearly any object at any time. There are very few restrictions on that.

 

JavaScript also borrows from some Functional Language aspects in how it handles execution scope too. A lot of its "weirdness" comes from how it binds the function scope of its this. Depending on the calling context, a function's this can be different things and still work correctly.

 

As for the prototype property of objects, it might be helpful to know that, like in Java, all JavaScript objects inherit from Object too. However, the way inheritance works in JavaScript is that all objects created from another, preexisting object inherit all of its prototype properties too. Any object created through a constructor has all the prototype properties (including its functions) of its superclass. For example, unless the prototype.constructor property is overwritten on an object, it is an instance of Object in JavaScript (similar to how everything is based Java's Object class in that language).

 

(It might be confusing to read now, but I've recently put together a crash course on my blog that covers JavaScript objects, classical inheritance in the language, and how to create hybrid classes.)

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...