metalslug87 Posted June 13, 2016 Share Posted June 13, 2016 Hi, I'm new to OOP and Phaser, and I'm writing a simple game script to learn the OOP principles. //main game function battleLevel.prototype = { battle:function () { this.obj1 = { enterMonsterMenu: function() { return console.log('enterMonsterMenu'); } }; }, } /* end OOP prototype */ //external contructor var Hero = function (warpX, warpY, game, name, life, mana, speed) { //some code }; Hero.prototype.monsterSelectUp = function() { console.log('monsterSelectUp'); //this.enterMonsterMenu(); battleLevel.prototype.battle.call(obj1); }; I want to access enterMonsterMenu() method by calling the monsterSelectUp() but I can't call it properly. What I am doing wrong ? Link to comment Share on other sites More sharing options...
mattstyles Posted June 13, 2016 Share Posted June 13, 2016 You're a little ways off currently. In your snippet you have a few things that won't work with JS. Have a look at the docs for how function.call works, the first parameter basically ends up setting scope for the function, so its probably not what you want here. It almost looks like you want to setup a static method to be called from the `battleLevel` object, but you can't really do that in JS. It looks like you are setting up a hierarchy and you want to perform some level actions when the Hero reaches a certain point, for example, when the Hero reaches the 'end' of a level (stairs up or whatever). If this is the case you probably want to decouple the level from the hero (or, objects/actors within that level), you might be best off employing pub/sub (using event emitters) to separate out your bits of logic. If you went the pub/sub route then the hero object would emit a request via an event, anything listening to that event would then update. It would end up something like: // There are many many event emitter libraries to create basic pub/sub, some get quite complex var events = new EventEmitter() // Level Constructor var BattleLevel = function() { // Do whatever you need here but bind up a listener to the event emitter // e.g. events.on( 'EndLevel', this.battle ) } BattleLevel.prototype.battle = function() { // Do stuff } // Hero var Hero = function() { ... } Hero.prototype.monsterSelectUp = function() { events.emit( 'EndLevel' ) } In this terse example your 2 objects are totally decoupled, neither gives a monkeys about the others implementation, they literally know nothing about each other. The Hero object initiates an event, and the BattleLevel object is able to hear that event and respond to it. There are other methods for doing this that would allow you to specifically use BattleLevel.enterMonsterLevel directly from your Hero object but I think that is a bad way to start learning this stuff. drhayes 1 Link to comment Share on other sites More sharing options...
sanojian Posted June 13, 2016 Share Posted June 13, 2016 Here is an earlier discussion of using OOP with Phaser with some code examples. Hope it is useful. http://www.html5gamedevs.com/topic/15503-some-oop-technique-in-phaser/#comment-87901 Link to comment Share on other sites More sharing options...
metalslug87 Posted June 14, 2016 Author Share Posted June 14, 2016 Thank you for your replies :), my problem is mainly about the scope. I just need to know if it's possible to reach the method inside other prototype from inside another like here: //main game function battleLevel.prototype = { battle:function () { function test_function () { console.log('test 1'); } }, } /* end OOP prototype */ //external contructor var Hero = function (warpX, warpY, game, name, life, mana, speed) { //some code }; Hero.prototype.monsterSelectUp = function() { console.log('monsterSelectUp'); // call somehow the test_function here test_function(); }; Link to comment Share on other sites More sharing options...
LTNGames Posted June 14, 2016 Share Posted June 14, 2016 I would suggest taking a look at some of the Phaser templates, if you look in the basic template you'll notice they use what's called a Namespace, with the use of this namespace it keep everything out of global space as well as making all functions available to you from anywhere. There are a few other ways to do this and I would recommend following the links above posted by others. // This is the namespace var BasicGame = {}; //Notice how we use it to create the function BasicGame.Boot = function () { }; BasicGame.Boot.prototype = { test: function () { console.log('Test function'); } }; // Outside of boot BasicGame.Sprite= function () { }; BasicGame.Sprite.prototype = { // I can call test function from boot above here by using the namespace BasicGame.Boot.prototype.test(); }; //You can also use it in global space BasicGame.Boot.prototype.test(); Link to comment Share on other sites More sharing options...
Noid Posted June 14, 2016 Share Posted June 14, 2016 It'd be better if you explained what you're trying to accomplish with the code so we can help you. The obj1 at the end is undefined and even if it were, you would end up adding an obj1 property to it that contains { enterMonsterMenu: function() { return console.log('enterMonsterMenu'); } } . It seems that you wanted to call a function instead. Link to comment Share on other sites More sharing options...
mattstyles Posted June 15, 2016 Share Posted June 15, 2016 Your code snippet, battleLevel.prototype = { battle:function () { function test_function () { console.log('test 1'); } } } You need to try reading up about closures and how JS deals with scope. Very simply, the `battle` function creates a new scope (if you come from a managed background this would add stuff to the stack which gets deallocated at the end of the function), nothing leaks out from this scope unless you employ some mechanism to do so, in this case you don't so `test_function` is entirely captured (or scoped) to that `battle` function. There's no need to place it there though, you could also add your test_function to the prototype and access it via `this`. battleLevel.prototype = { battle:function () { this.test_function() }, test_function: function () { console.log('test') } } This places it as a public method (they all are in JS) on the `battleLevel` object, once instantiated (convention dictates that it should be `BattleLevel`, capitalised): var level = new battleLevel() level.test_function() Instantiate objects, accessing static methods on prototypes becomes impossible when you start mixing in data to your objects, without an instantiation those bits of data won't be initialised and ready for use (not a problem if you're attaching pure functions to the prototype). I agree with @Noid though, it sounds like maybe you are heading down the wrong track to solve whichever problem you're actually solving, or, more accurately, maybe there is a better solution Link to comment Share on other sites More sharing options...
glantucan Posted June 15, 2016 Share Posted June 15, 2016 I agree with most of what's said. Javascript is not as simple as it seems at first. There is a very good series of small books which I highly recomend to learn the basics and all the good habits with javascript: "You don't know JS" by Kyle Simpson It's free to read online. Here is the link: https://github.com/getify/You-Dont-Know-JS mattstyles 1 Link to comment Share on other sites More sharing options...
Recommended Posts