Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 12 of 12
  1. #1
    New Coder
    Join Date
    Nov 2009
    Location
    Tampa, Florida. US
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post

    Question Help understanding inheritance and nested objects (non-DOM related)

    I posted this once, but it disappeared, and I have no notifications that I did anything wrong. I read the rules before posting and wasn't breaking any so I am not sure why it disappeared but here goes again.

    I am trying to learn Javascript (particularly OOP) from a series of screencasts by Douglas Crockford. I have developed a theoretical "game" to build to illustrate it to myself better, and learn by example.

    I must be misunderstanding how inheritance works, because my code is not producing the results I thought it would.

    Here is what I have, followed by an explanation of my understanding.
    Code:
    $(function() {
    
    function object(o) {
    	function Funct() {}
    	Funct.prototype = o;
    	return new Funct();
    }
    
    
    soldier = {
          pointsCost: 0,
          movement: "1 Infantry Block",
          validTargets: {},
          weapons: {
    			"Main Weapon": {
    				"Weapon Type": "M4 Carbine",
    				"Fire Range": 12
    			},
    			"Secondary Weapon": {
    				"Weapon Type": "JCP .45",
    				"Fire Range": 3
    			}
    		}
    };
    
    var rifleman = object(soldier); 
    rifleman.pointsCost += 10;
    rifleman.validTargets.target1 = "Infantry"
    rifleman.weapons["Secondary Weapon"]["Weapon Type"] = "";
    rifleman.weapons["Secondary Weapon"]["Fire Range"] = "";
    
    
    var heavyGunner = object(soldier);
    heavyGunner.pointsCost += 20;
    heavyGunner.validTargets.target1 = "Infantry";
    heavyGunner.validTargets.target2 = "Light Armor";
    heavyGunner.weapons["Main Weapon"]["Weapon Type"] = "SAW M249";
    heavyGunner.weapons["Main Weapon"]["Fire Range"] = 12;
    heavyGunner.weapons["Secondary Weapon"]["Weapon Type"] = "";
    heavyGunner.weapons["Secondary Weapon"]["Fire Range"] = "";
     
    var sniper = object(soldier);
    sniper.pointsCost += 30;
    sniper.validTargets.target1 = "Infantry";
    sniper.weapons["Main Weapon"]["Weapon Type"] = "Savage .308";
    sniper.weapons["Main Weapon"]["Fire Range"] = 20;
    sniper.weapons["Secondary Weapon"]["Weapon Type"] = "JCP .45";
    sniper.weapons["Secondary Weapon"]["Fire Range"] = 3;
    
     
    var demolitions = object(soldier);
    demolitions.pointsCost += 30;
    demolitions.validTargets.target1 = "Infantry";
    demolitions.validTargets.target2 = "Light Armor";
    demolitions.validTargets.target3 = "Artilery";
    demolitions.validTargets.target4 = "Structures";
    demolitions.weapons["Main Weapon"]["Weapon Type"] = "SMAW MK153";
    demolitions.weapons["Main Weapon"]["Fire Range"] = 16;
    demolitions.weapons["Secondary Weapon"]["Weapon Type"] = "M1014 Combat Shotgun";
    demolitions.weapons["Secondary Weapon"]["Fire Range"] = 1; 
    
    
    var infantry = { 
    
        rifleman: rifleman, 
        
        heavyGunner: heavyGunner, 
         
        sniper: sniper, 
         
        demolitions: demolitions 
     
    };
    
    
    
    console.log(infantry);
    
    });

    I start by creating an object function that accepts an object passed in, and sets it to the prototype of a constructor (that would allow me to create a new object linked to, and inheriting from, the initial passed in object)

    I initialized a solider object literal, and pass that into the object function while creating 4 new objects (rifleman, heavyGunner, sniper, demolitions)
    These four should inherit from and customize upon the soldier object.

    The way I understood inheritance is that the new objects (example. rifleman) would inherit properties from the old object (i.e. soldier) and change or add properties, affecting only the new (rifleman) object but not changing the old(solider) object.

    this works ok somewhat in my example, until it comes to nested objects.
    In the above example I have objects as values for some Object's properties. (i.e. validTargets and weapons) When I change or add these, all of the new objects seem to inherit the last declarations, from demolitions, as if demolitions is actually changing that part of the soldier object so that the other's inherit those properties.

    From my viewpoint, I expected these values to not be changed and that the 4 infantry types had no link to each other, but only to the soldier object.

    I apparently misunderstood something, or coded something wrong.

    Some minor notes:
    -I will be updating most of the "string" values to be objects, so for instance, the validTargets value of "Infantry" would actually be the infantry object, stating that any of the 4 solider types would be a valid target.
    - I intend to create weapons as their own viable objects in the future, and pass those objects instead of "strings"
    - I intend to extend this (once this is working) to create an armor object that contains armor type units, similar in structure to the infantry object.
    - If I can get this all to work, I may make this into a "simple" dice style battle game. but that is way off, I just want to get this nesting of objects to work with inheritance for now.

    Thanks in advance for any help you can provide.
    Here is a link to the "live" example. (not much different there except if you have firebug you can see the console.log method showing the objects, and how they are inheriting in properly from my POV.)

    Link to Live example...


    Blue
    Last edited by blue642; 11-18-2009 at 05:54 PM. Reason: resolved

  • #2
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,374
    Thanks
    11
    Thanked 592 Times in 572 Posts
    the soldier "json" object is being used as the prototype for all instances.
    this means that the same object is the prototoype for all, thus changing it changes everything.


    i would argue that you really should be storing these properties in the object as object properties, not as prototype properties.


    the simplest workaround would be to use a fresh object for each instance, so that each instance has it's own prototype:

    wrap:
    Code:
    function soldier(){
     return {
          pointsCost: 0,
          movement: "1 Infantry Block",
          validTargets: {},
          weapons: {
    			"Main Weapon": {
    				"Weapon Type": "M4 Carbine",
    				"Fire Range": 12
    			},
    			"Secondary Weapon": {
    				"Weapon Type": "JCP .45",
    				"Fire Range": 3
    			}
    		}
    };
    }//end soldier()
    and call instead of point:
    Code:
    var rifleman = object(soldier());
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • Users who have thanked rnd me for this post:

    blue642 (11-17-2009)

  • #3
    New Coder
    Join Date
    Nov 2009
    Location
    Tampa, Florida. US
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post
    To be honest I didn't even know what "JSON" was until I looked it up. (I haven't finished the videos yet.)

    I made the changes and they work, but I'm not sure I completely comprehend exactly why this was works.

    The soldier "object" became a function (is this called a constructor?)

    I thought that the way I had it was making a new fresh instance for each object (apparently not though) Could you please explain where I went wrong in that, I would just like to know that I understand it all, before moving forward.

    Lastly, what exactly do you mean by "i would argue that you really should be storing these properties in the object as object properties, not as prototype properties." Do you mean that I should just create each object rather than try to use inheritance?

    Thanks so much for the advice, and the code fix. Greatly appreciated. Now I just hope I can wrap my head around why the fix works...

    If you'd rather point me to a resource that I can read and learn the answer, that is fine as well.

    Thanks again,
    Blue

  • #4
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,374
    Thanks
    11
    Thanked 592 Times in 572 Posts
    i would set aside the object() function for now; it's not really what you need at this point.

    generally, i like to put methods in the prototype and properties in the instance.
    then, the methods can manipulate the properties using "this.property" notation.
    in conjunction with "new", you get a pretty nice (if basic) OOP setup using constructors.

    there are fancier tricks (like crockford's object() function for example), but keeping with a simple in-grain javascript implementation is probably the easiest to get up and running.

    here is how your code might look with "regular" OOP javascript:

    PHP Code:
    function Soldier(){
          
    this.pointsCost0;
          
    this.movement"1 Infantry Block";
          
    this.validTargets= {};
          
    this.weapons={
                
    "Main Weapon": {
                    
    "Weapon Type""M4 Carbine",
                    
    "Fire Range"12
                
    },
                
    "Secondary Weapon": {
                    
    "Weapon Type""JCP .45",
                    
    "Fire Range"3
                
    }
            
          };
    }
    //end soldier()

    Soldier.prototype.showGun=function(){
     
    alert("Weapon:"+
        
    this.weapons["Main Weapon"]["Weapon Type"]
     );
    }



    var 
    heavyGunner = new Soldier();
    heavyGunner.pointsCost += 20;
    heavyGunner.validTargets.target1 "Infantry";
    heavyGunner.validTargets.target2 "Light Armor";
    heavyGunner.weapons["Main Weapon"]["Weapon Type"] = "SAW M249";
    heavyGunner.weapons["Main Weapon"]["Fire Range"] = 12;
    heavyGunner.weapons["Secondary Weapon"]["Weapon Type"] = "";
    heavyGunner.weapons["Secondary Weapon"]["Fire Range"] = "";


    heavyGunner.showGun()//shows "Weapon:SAW M249"

    // FF/chrome (or patch) required for next line:
    alert(JSON.stringify(heavyGunner ,null,"\t")) 
    which shows:

    Code:
    {
    	"pointsCost":20,
    	"movement":"1 Infantry Block",
    	"validTargets":{
    		"target1":"Infantry",
    		"target2":"Light Armor"
    	},
    	"weapons":{
    		"Main Weapon":{
    			"Weapon Type":"SAW M249",
    			"Fire Range":12
    		},
    		"Secondary Weapon":{
    			"Weapon Type":"",
    			"Fire Range":""
    		}
    	}
    }
    notice the prototype method, showGun() refers to this.weapons, just like code within the constructor function.

    i know OOP javascript can be a bit strange at first, so let me know what needs expanding on, or does this all actually make some sense?
    Last edited by rnd me; 11-17-2009 at 07:16 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • Users who have thanked rnd me for this post:

    blue642 (11-17-2009)

  • #5
    New Coder
    Join Date
    Nov 2009
    Location
    Tampa, Florida. US
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post
    I think I wrap my head around this now. It seems easier, and it's actually working!

    I did try something new and may have hit a stumbling block.

    I used the illustrated OOP method and defined all 4 of my units.

    then I added this to wrap them as one "infantry" object.
    Code:
    var infantry = { 
    
        rifleman: rifleman, 
        
        heavyGunner: heavyGunner, 
         
        sniper: sniper, 
         
        demolitions: demolitions 
     
    };
    
    rifleman.validTargets.target1 = infantry;
    heavyGunner.validTargets.target1 = infantry;
    sniper.validTargets.target1 = infantry;
    demolitions.validTargets.target1 = infantry;
    This creates a giant recursion of the objects, is this going to be a huge performance drain? I want to reference each as a valid target's in the way that this would allow, but I don;t want to create endless loops that will kill a computer.

    I noticed with the last alert (which I commented out for now) it notified me of "Too much recursion" in firebug. I would really like a way to reference the objects themselves as a valid target and not a string display of them.

    I would also like to say that your explanation really helped ease the understanding of methods (I was a little afraid of them before, but now they seem so easy.) and I like how they seamlessly inherit as well.

    Thanks so much, for your time and effort. I really appreciate it, and you've helped me understand this very nicely.

  • #6
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,374
    Thanks
    11
    Thanked 592 Times in 572 Posts
    Quote Originally Posted by blue642 View Post
    This creates a giant recursion of the objects, is this going to be a huge performance drain? I want to reference each as a valid target's in the way that this would allow, but I don;t want to create endless loops that will kill a computer.
    ....
    I noticed with the last alert (which I commented out for now) it notified me of "Too much recursion" in firebug. I would really like a way to reference the objects themselves as a valid target and not a string display of them.

    Each object would contain a ref to the infantry object, which actually contains all of the objects, as you've figured out. Javascript can point to itself like that pretty well. It doesn't waste ram, since objects are all basically pointers, your only extra overhead is a single "pointer" for each property.
    While not a problem on paper or silicone, in practice, pointers can make an object much harder to serialize/stringify.

    you could hide the big object behind a method, or use a variable to close the properties, instead of attaching them to the object.

    Code:
    rifleman.validTargets.target1= infantry;
    might work almost as well like:
    Code:
    rifleman.validTargets.target1=function(){return infantry;}
    you would just need to add the extra empty parens each time it's used: "xxx.target1().sniper.xxx"

    the other advantage to using function methods is that JSON.stringify discards them, leaving you with a nice clean data structure to view/archive.
    Last edited by rnd me; 11-17-2009 at 07:27 PM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • Users who have thanked rnd me for this post:

    blue642 (11-18-2009)

  • #7
    New Coder
    Join Date
    Nov 2009
    Location
    Tampa, Florida. US
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post
    Quote Originally Posted by rnd me View Post
    you would just need to add the extra empty parens each time it's used: "xxx.target1().sniper.xxx"

    the other advantage to using function methods is that JSON.stringify discards them, leaving you with a nice clean data structure to view/archive.

    I'm a little lost with the example above.... is it just chaining? I just don't understand why after the parens you added sniper.xxx

    Also I'm not familiar with JSON.stringify (except in the earlier code example you provided. I will research this though and learn about it.


    EDIT: Also, just a thinking out loud question, I'm at work now and can;t test.... but, Wouldn't it be possible to add the validTargets.target1 method to Soldier constructor (after infantry is built) in order to allow the units to all inherit the method as well?

    Thanks a ton for all your help.

    Blue
    Last edited by blue642; 11-17-2009 at 10:01 PM. Reason: adding a question....

  • #8
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,374
    Thanks
    11
    Thanked 592 Times in 572 Posts
    Quote Originally Posted by blue642 View Post
    I'm a little lost with the example above.... is it just chaining? I just don't understand why after the parens you added sniper.xxx

    EDIT: Also, just a thinking out loud question, I'm at work now and can;t test.... but, Wouldn't it be possible to add the validTargets.target1 method to Soldier constructor (after infantry is built) in order to allow the units to all inherit the method as well?
    you could make it before you define any units:
    Code:
    var infantry = {};
    and add each unit to infantry as it's created:
    Code:
    var heavyGunner = new Soldier();
    infantry.heavyGunner = heavyGunner;
    ----------
    well, i have to go for now, but i do have more info for you.
    do us a favor and reply something back so i notice the "new post" indicator when i can get back on. sometimes i lose track of threads in this situation...
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • Users who have thanked rnd me for this post:

    blue642 (11-18-2009)

  • #9
    New Coder
    Join Date
    Nov 2009
    Location
    Tampa, Florida. US
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post
    Quote Originally Posted by rnd me View Post
    you could make it before you define any units:
    Code:
    var infantry = {};
    and add each unit to infantry as it's created:
    Code:
    var heavyGunner = new Soldier();
    infantry.heavyGunner = heavyGunner;
    ----------
    well, i have to go for now, but i do have more info for you.
    do us a favor and reply something back so i notice the "new post" indicator when i can get back on. sometimes i lose track of threads in this situation...
    Oh True! I didn't even think of creating it as empty to begin with...

    I tried the methodizing of the target1 like this...

    Code:
    rifleman.validTargets.target1 = function(){return infantry;}
    heavyGunner.validTargets.target1 = function(){return infantry;}
    sniper.validTargets.target1 = function(){return infantry;}
    demolitions.validTargets.target1 = function(){return infantry;}
    
    console.log(rifleman.validTargets.target1());
    which in console.log() gave me the infantry object, but then inside when I dug deeper in, each unit had a target1 of this.prototype.

  • #10
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,374
    Thanks
    11
    Thanked 592 Times in 572 Posts
    Quote Originally Posted by blue642 View Post
    Wouldn't it be possible to add the validTargets.target1 method to Soldier constructor (after infantry is built) in order to allow the units to all inherit the method as well?
    it's a perfect use-case for a static: a global variable's property.

    first, modify the constructor so that we can keep better track of things:
    Code:
    function Soldier(name){
       this.name=name;
       Soldier.infantry[name]=this;
       // ... rest of constructor is the same...
    having a name allows us to add to collections at construction-time.

    define a static for the constructor:
    Code:
    Soldier.infantry={};
    and simple a prototype getter method to fetch the static:
    Code:
    Soldier.prototype.getTarget=function(){
        return Soldier.infantry;
    }

    now, each time you create a unit, pass the name to the constructor:

    Code:
    var heavyGunner = new Soldier("heavyGunner");
    this is a bit repetitive, but the names and var names need not match.
    it also means you don't have to tack each target1 method on individually, so it eliminates some repetition as well. it's a good trade-off in my book.


    these modifications should yield the behavior you want if i understand the problem correctly.

    a few side notes:
    getTarget is basically the same thing as target1 in the code you posted.

    you can also access Soldier.infantry directly, with the aforementioned considerations.

    also, the console might curtail some javascript object infinite recursions for performance reasons.
    Last edited by rnd me; 11-18-2009 at 07:52 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • Users who have thanked rnd me for this post:

    blue642 (11-18-2009)

  • #11
    New Coder
    Join Date
    Nov 2009
    Location
    Tampa, Florida. US
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post
    I had some trouble getting your last advice applied and working, the first time finding the infantry object as target1 was no problem, but upon looking in each infantry units targets, I got a this.prototype response.

    I reverted back to just using the pointers, which seems to be working well.

    I have added most of my armor division and pointed to and from these as well.
    It seems to have added nicely and works quite well. (I am very happy with it so far.)

    here is the code I have so far.
    Code:
    $(function() {
    
    
    ///CREATING INFANTRY UNITS...
    
    function Soldier(){
    
    	this.pointsCost= 0;
    	this.movement= "1 Infantry Block";
    	this.validTargets= {};
    	this.weapons={
    		"Main Weapon": {
    		"Weapon Type": "M4 Carbine",
    		"Fire Range": 12
    		},
    		"Secondary Weapon": {
    			"Weapon Type": "JCP .45",
    			"Fire Range": 3
    		}
            
    	};
    }//end Soldier()
    
    var infantry = {}; //Empty wrapper for the infantry units...
    var armor = {}; // empty wrapper for armored units...
    lightArmor = {};
    heavyArmor = {};
    artillery = {};
    armor.lightArmor = lightArmor;
    armor.heavyArmor = heavyArmor;
    armor.artillery = artillery;
    
    Soldier.prototype.showGun = function(){
     alert("Weapon:"+
        this.weapons["Main Weapon"]["Weapon Type"]
     );
    } // method to show the Main Weapon of unit...
    
    var rifleman = new Soldier(); 
    rifleman.pointsCost += 10;
    rifleman.validTargets.target1 = infantry;
    rifleman.weapons["Secondary Weapon"] = "";
    infantry.rifleman = rifleman; // adds rifleman to the empty infantry wrapper above...
    
    var heavyGunner = new Soldier();
    heavyGunner.pointsCost += 20;
    heavyGunner.validTargets.target1 = infantry;
    heavyGunner.validTargets.target2 = lightArmor;
    heavyGunner.weapons["Main Weapon"]["Weapon Type"] = "SAW M249";
    heavyGunner.weapons["Main Weapon"]["Fire Range"] = 12;
    heavyGunner.weapons["Secondary Weapon"] = "";
    infantry.heavygunner = heavyGunner;
    
     
    var sniper = new Soldier();
    sniper.pointsCost += 30;
    sniper.validTargets.target1 = infantry;
    sniper.weapons["Main Weapon"]["Weapon Type"] = "Savage .308";
    sniper.weapons["Main Weapon"]["Fire Range"] = 20;
    sniper.weapons["Secondary Weapon"]["Weapon Type"] = "JCP .45";
    sniper.weapons["Secondary Weapon"]["Fire Range"] = 3;
    infantry.sniper = sniper;
    
     
    var demolitions = new Soldier();
    demolitions.pointsCost += 30;
    demolitions.validTargets.target1 = infantry;
    demolitions.validTargets.target2 = lightArmor;
    demolitions.validTargets.target3 = artillery;
    demolitions.validTargets.target4 = "Structures";
    demolitions.weapons["Main Weapon"]["Weapon Type"] = "SMAW MK153";
    demolitions.weapons["Main Weapon"]["Fire Range"] = 16;
    demolitions.weapons["Secondary Weapon"]["Weapon Type"] = "M1014 Combat Shotgun";
    demolitions.weapons["Secondary Weapon"]["Fire Range"] = 1; 
    infantry.demolitions = demolitions;
    
    
    console.log(rifleman.validTargets.target1); //returns the infantry object containing each infantry unit...
    
    // CREATING ARMOR...
    
    function ArmorUnit(){
          this.pointsCost= 0;
          this.movement= "1 Armor Block";
          this.validTargets= {};
          this.weapons={
                "Main Weapon": {
                    "Weapon Type": "M256 120mm Smooth-Bore Cannon",
                    "Fire Range": 20
                },
                "Secondary Weapon": {
                    "Weapon Type": ".50 Machine Gun",
                    "Fire Range": 16
                }
            
          };
    }//end ArmorUnit()
    
    
    var apc = new ArmorUnit();
    apc.pointsCost += 100;
    apc.movement = "2 Armor Blocks";
    apc.validTargets = "";
    apc.weapons = "";
    armor.lightArmor.apc = apc;
    
    var humvee = new ArmorUnit();
    humvee.pointsCost += 200;
    humvee.movement = "2 Armor Blocks";
    humvee.validTargets.target1 = infantry;
    humvee.validTargets.target2 = lightArmor;
    humvee.weapons["Main Weapon"]["Weapon Type"] = ".50 Machine Gun Turret";
    humvee.weapons["Main Weapon"]["Fire Range"] = 16;
    humvee.weapons["Secondary Weapon"] = "";
    armor.lightArmor.humvee = humvee;
    
    var sa17Grizzly = new ArmorUnit();
    sa17Grizzly.pointsCost += 300;
    sa17Grizzly.movement = "1 Armor Block";
    sa17Grizzly.validTargets.target1 = infantry;
    sa17Grizzly.validTargets.target2 = lightArmor;
    sa17Grizzly.validTargets.target3 = "aircraft";
    sa17Grizzly.weapons["Main Weapon"]["Weapon Type"] = "9M317 SAMs";
    sa17Grizzly.weapons["Main Weapon"]["Fire Range"] = 16;
    armor.heavyArmor.sa17Grizzly = sa17Grizzly;
    
    var m1a2 = new ArmorUnit();
    m1a2.pointsCost += 300;
    m1a2.movement = "1 Armor Block";
    m1a2.validTargets.target1 = infantry;
    m1a2.validTargets.target2 = armor;
    m1a2.validTargets.target3 = "structures";
    armor.heavyArmor.m1a2 = m1a2;
    
    console.log(armor); // returns the armor object containing each sub-armor type, which contain specific ArmorUnits
    
    });
    and live... http://tampa.dingledoodle.com/soldiers2/
    (I commented out console.log() so it doesn't break when viewing without Firebug.

    I still need to add in artillery, and then move onto structures (which will be buildings for base development like medic quarters, infantry barracks, machine shops, etc.)
    Once that is successful and everything points to and references itself/each other. I will add in some logic, for rolling dice, accumulating points, spending points, creating these units etc. Then i will work on porting it to DOM elements and make it a playable game (simple, but playable.)


    This is getting fun!

    Thanks again for all the help rnd me. I am marking this as resolved, (because it technically is) but if you have any other thoughts or opinions, I'd love to hear them, just post here or PM me. You've been a great help!

    Blue
    Last edited by blue642; 11-18-2009 at 05:52 PM. Reason: adding live link...

  • #12
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,374
    Thanks
    11
    Thanked 592 Times in 572 Posts
    this should create the same unit data structure as the code you posted, with a few tweaks to simplify and shorten coding.

    I try to avoid repeating myself whenever possible, and lazy javascript is fast javascript, so this work out well for everyone.

    here what i came up with. again, i didn't want to modify your structure, simply help you slimline the data entry:

    Code:
    function Soldier(name){
       this.name=name;
       Soldier.infantry[name]=this;
    	this.pointsCost= 0;
    	this.movement= "1 Infantry Block";
    	this.validTargets= {
                target1:Soldier.infantry,
                target2:Soldier.armor.lightArmor  
            };
    
    	this.weapons={
    		"Main Weapon": {
    		"Weapon Type": "M4 Carbine",
    		"Fire Range": 12
    		},
    		"Secondary Weapon": {
    			"Weapon Type": "JCP .45",
    			"Fire Range": 3
    		}
            
    	};
    }//end Soldier()
    Soldier.infantry={};
    
    Soldier.prototype.getInf=function(){
        return Soldier.infantry;
    }//getInf()
    
    var infantry = Soldier.infantry; //Empty wrapper for the infantry units...
    
    var lightArmor = {},
    heavyArmor = {},
    artillery = {};
    
    var armor=Soldier.armor = {
          lightArmor :lightArmor ,
          heavyArmor :heavyArmor ,
          artillery :artillery 
     }; //armored units...
    
    
    //soldier "factory" to preset props on a fresh Soldier object...
    function Soldier2(name,points,mwType,mwRange,sw){
     var unit=new Soldier(name);
        unit.pointsCost += (points||0);
        if(mwType!=null){unit.weapons["Main Weapon"]["Weapon Type"]=mwType;}
        if(mwRange!=null){unit.weapons["Main Weapon"]["Fire Range"]=mwRange;}
        if(sw!=null){ unit.weapons["Secondary Weapon"]=sw; }
      return unit;
    }//end Solder2() // shortcut wrapper for Soldier constructor...
    
    
    //############ end construction/collection related code ################
    
    
    
    var rifleman = Soldier2("rifleman", 10,"M4 Carbine",12,"");
      delete rifleman.validTargets.target2;
    
    var heavyGunner = Soldier2("heavyGunner",20,"SAW M249",12,"");
    
    var sniper = Soldier2("sniper", 30,"Savage .308", 20);
      delete sniper.validTargets.target2;
    
    var demolitions = Soldier2("demolitions", 30,"SMAW MK153", 16,{
         "Weapon Type":"M1014 Combat Shotgun",
         "Fire Range":1    } );
        demolitions.validTargets.target3 = artillery;
        demolitions.validTargets.target4 = "Structures";
    
    
    
    console.log(rifleman.getInf()); //returns the infantry object containing each infantry unit...
    i'll leave it up to you to convert the armor units, but you can see how compact soldier2 makes the code.

    you just pass the set of values for the common properties, it builds a soldier, and then you delete or set other properties as needed.
    Last edited by rnd me; 11-19-2009 at 07:27 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •