Let's see if back-of-the-napkin drawings might help. This is what happens to me when I enter a room in my (fab) game when another player ("Bob") is already there:
The left side of that diagram describes the initialization process of me as a
Roomobject, and the
PlayerList. Since everything in raphaël.js is drawn on a "paper" (the
Roomhas to draw the player's avatar, which then needs to be attached to the player. Finally, label shadowing and other callbacks need to be added to my characters.
That is a bit complex, but overall OK (I think). The room creates the drawable / raphaël element, which is then added to the
Playerobject. It might seem a little weird that the
PlayerListis responsible for telling the
Roomto draw the player and telling the
Playerabout its raphaël representation, but that is its responsibility. The
PlayerListkeeps track of players currently in the room, adding and removing them as needed.
Regardless, I think my woes originate on the other side of that diagram. The right side starts with a call to an
<iframe>comet session, which uses the
PlayerListto animate other users in the room. The most obvious problem that I see in here is that the
PlayerListmight be accessed before it is even defined (if the
<iframe>returns really, really fast). That is just silly.
The other problem on the right side of the diagram is that it tells the
PlayerListto instruct players to walk. It does this by first stopping the player, storing current location information, calculating where to go next and then animating the player along the way. Quite aside from the potential race condition on the player's position between left side / right side, I have to recognize that it is silly to be telling players to walk at all. This is when I first log in. Existing players do not need to walk to the right spot—they are already there.
So, I refactor the code such that the
<iframe>/ comet stuff that adds players comes after all of the initialization (especially after the
PlayerListis initialized) and so that no walking calculations are done until a player actually moves. This makes for a much cleaner path for drawing players:
With that, my bug is resolved (drawing certain players in the wrong location). More importantly, I have put myself in a much better position moving forward.