2

I am currently working on a multiplayer game in Javascript, and I seem to have a very peculiar problem with my PlayerList data-structure/object.

Here is the object:

var PlayerList = function(){
    this.list = {};
}

The object has several methods that I added by doing...

PlayerList.prototype.method = function(){...}

The methods are: addPlayer, removePlayer, playerInList, findPlayer, jsonify and unjsonify. I am having a huge problem with unjsonify. Here is the code:

PlayerList.prototype.unjsonify = function(jsonList){
    var object = JSON.parse(jsonList);
    var li = new PlayerList();
    console.log(li.list.x);
    console.log(li.list.y);
    console.log(li.list);
    //insert the fake player objects from the fake list into the new list as real player objects
    for(p in object.list){
        var pObj = object.list[p];
        //create real player object
        var player = new Player(pObj.name, pObj.x, pObj.y, pObj.velX, pObj.velY);
        li.addPlayer(player);
    }
    return li;
}

The reason for doing it this way is because if I just parse the jsonList object sent by the server, the resulting object has the correct structure, but none of the methods a PlayerList should have.

Here's the problem: I noticed later, when I go through the PlayerList.list and draw each player, I get this error:

Uncaught TypeError: Object NaN has no method 'getX'

As it turns out, for some reason when I created a new PlayerList in unjsonify it had two extra fields, x and y, both set to NaN. The problem occurs here:

PlayerList.prototype.unjsonify = function(jsonList){
    var object = JSON.parse(jsonList);
    var li = new PlayerList();

For some very odd reason, li is not a new empty PlayerList like it should be. It contains two extra variables, x and y, both set to NaN. Even weirder, not only is it not a new empty list, it contains all the players that are currently on the server - something that seems impossible to me because the first time the client gets the package containing the json player list it doesn't even have a past version of itself to go off of.

To top it off, if you look at the block of code for unjsonify, console.log(li.list.x) and console.log(li.list.y) both output undefined, but then console.log(li.list) outputs an Object that has (in addition to all players on the server) fields x and y set to NaN.

I am totally lost on how this could even happen. It seems like one of these bugs no one could solve because they just don't make any sense. But if someone has the slightest idea on how to help me that would be greatly appreciated!

I should note that before I had this PlayerList object, I simply used an object primitive without any methods and did everything manually (e.g. pList.username = player to add players, etc...) and everything worked (I could see other players move on my screen, etc.) But since this is getting pretty large at this point, I wanted to add some structure hence I created this PlayerList object that should make my code more structured and pretty but thus far has only caused more problems than anything else.

tborenst
  • 972
  • 2
  • 9
  • 18
  • Have you put a breakpoint in the PlayerList constructor to find out if maybe your constructor is called multiple times? – Ja͢ck Jun 04 '12 at 02:38
  • Good idea - oddly enough, it is only called once in another file, main.js, to create the initial var plist = new PlayerList() so I can later call unjsonify by doing plist.unjsonify(json). But it is only called once? How is this possible? – tborenst Jun 04 '12 at 02:47
  • From the code posted, I can't see why this would happen; if your constructor is really that short, the only way it can be populated with other stuff is via the prototype chain ... – Ja͢ck Jun 04 '12 at 02:52
  • The code seemed to work fine here: http://jsfiddle.net/slace/BL6Nq/ – Aaron Powell Jun 04 '12 at 03:08

1 Answers1

0

Your PlayerList has no .addPlay method.

While you're working with the code it is easier to name your variables where they're readable.

 function PlayerList() {
                this.list = [];
         };
            //
 PlayerList.prototype.unjsonify = function (jsonList) {
          var jsonLst = JSON.parse(jsonList),
                    myPlayerList = new PlayerList(),
                    player,
                    jsonItem;
                //
      for (var i = 0; i < jsonLst.list.length; i++) {
                    jsonItem = jsonLst.list[i];
                    //
                    player = new Player(jsonItem.name, jsonItem.x, jsonItem.y, jsonItem.velX, jsonItem.velY);

                    myPlayerList.list.push(player);

                };
                return myPlayerList;
            };

I've changed your Player.list from an object to an array.

Vinyl Windows
  • 503
  • 1
  • 7
  • 19
  • I'm a little confused, what do you mean PlayerList has no .addPlay method? Did you mean to write .addPlayer? Because it does have an .addPlayer method. Is this not what you meant? Otherwise, turning the list into an array is probably a good idea. The only problem is not being able to look up players by their username (what I used for the key). I will try it though. – tborenst Jun 04 '12 at 03:14
  • Wow... Even after I changed it to an array, the x and y pop up and are set to NaN. – tborenst Jun 04 '12 at 03:25
  • Can you post enough code for me to simulate what is going on? Some Playlist data will be nice as well. – Vinyl Windows Jun 04 '12 at 12:29
  • You know, it was so crazy I decided to rewrite that portion of the code and it worked. I have no idea what caused the problem, but I assume that I somehow managed to pollute the PlayerList object's prototype somehow. You have been helpful though, so thank you! – tborenst Jun 06 '12 at 14:38
  • That what makes forums so wonderful, is that your question may or may not be blurred, and your answer may or may not be exactly, but the posting, asking, and answering process always cast a new perspective onto the issue. – Vinyl Windows Jun 06 '12 at 16:16