OK. Let's see if I can get state remembered properly in my (fab) game. Last night I got the fab.js backend ready to accept iframe query parameters describing a player. The first order of business tonight is to get the iframe actually sending said query parameters.
Easy enough. Currently the iframe resource is requested on page load:
<iframe src="/comet_view"></iframe>I switch to a no-
src
iframe:<iframe id="iframe"></iframe>I only assign a
src
once the player is identified and when I do so I pass query parameter information that the server can use to link the player with the connection:if (kv[0] == 'player' && kv[1]) {To associate both position and connections with players, I convert the player list to a hash:
// There is a player
$('#login').hide();
var me = new Player(kv[1]);
$('#iframe')[0].src = '/comet_view?player=' + me.id + '&x=' + me.x + '&y=' + me.y;
player_list = new PlayerList(me);
new Room($("#canvas")[0], player_list);
}
var players = {};I then add players in the fab.js backend (taking advantage of the query-params-to-object app that I wrote last night):
function init_comet (app) {With that working, I would like to keep track of players movements. In the
return function () {
var out = this;
return app.call( function listener(obj) {
if (obj && obj.body) {
out({ headers: { "content-type": "text/html" },
body: "<html><body>\n" })
( // other comet connection initialization );
puts("adding: " + obj.body.id);
players[obj.body.id] = {status: obj.body, listener: out};
}
return listener;
});
};
}
/move
app, I add:( /move/ )Right after I broadcast the new position to all clients, I record it in the fab.js backend with
( function() {
var out = this;
return function listener( obj ) {
if ( !obj ) out();
else if ( obj.body ) {
broadcast(obj.body);
var status = JSON.parse(obj.body);
update_player_status(status);
}
return listener;
};
} )
update_player_status
. Except I don't. My fab.js server crashes when my player moves:cstrom@whitefall:~/repos/my_fab_game$ node game.jsThat is not too helpful, but I would speculate that the
HTTPParser.onBody (http:92:23)
Stream.ondata (http:524:30)
IOWatcher.callback (net:307:31)
node.js:748:9
HTTPParse
in the stacktrace indicates that my JSON.parse is failing. With the help of print-stderr debugging, I eventually determine that the obj.body
is not a string (although it behaves very much like one). This debugging code:puts("typeof"+typeof(obj.body));...outputs the following:
puts("id: " + obj.body.id);
for (var prop in obj.body) {
puts("["+prop+"] " + obj.body[prop]);
}
typeofobjectSo
id: undefined
[0] 123
[1] 34
[2] 105
[3] 100
[4] 34
[5] 58
[6] 34
[7] 98
[8] 111
...
obj.body
is an object. It is an object but not a player object because it does not respond to id
. It also looks like an array... of characters. That is odd. Ultimately, I can cast it into a real string by concatenating it with an empty string:( /move/ )That is a good stopping point for today. Tomorrow, I think I may explore raphaël.js a bit to make the room a bit nicer.
( function() {
var out = this;
return function listener( obj ) {
if ( !obj ) out();
else if ( obj.body ) {
broadcast(obj.body);
var status = JSON.parse("" + obj.body);
update_player_status(status);
}
return listener;
};
} )
Day #103
No comments:
Post a Comment