$o.keys(rawCities).forEach(function(cityKey) { var $c = rawCities[cityKey]; $c.continent = $o.keys(this.continents).filter(function(continentKey) { return $(continentKey).indexOf(cityKey) > -1; })[0]; $c.infections = {}; $c.adjacent = []; $o.keys(this.continents).forEach(function(continent) { $c.infections[continent] = 0; }); this.cities[cityKey] = $c; }, this);
var Pickups = exports.Pickups = function() { var centers = {}; var image = gamejs.image.load('images/star.png'); var radius = image.rect.width/2; function k(p) { return p[0] + '.' + p[1]; } this.draw = function(display) { objects.keys(centers).forEach(function(k) { var c = centers[k].pos; display.blit(image, [c[0] + radius, c[1] + radius]); }); }; this.remove = function(pos) { gbox2d.destroyBody(centers[k(pos)].body); delete centers[k(pos)]; return; }; /** * constructors */ var tries = 0; for (var i=0;i<10;i++) { tries++; var pos = [ parseInt((Math.random() * conf.SCREEN_WIDTH * 0.5) + conf.SCREEN_WIDTH * 0.2, 10), parseInt((Math.random() * conf.SCREEN_HEIGHT * 0.8) + conf.SCREEN_HEIGHT * 0.05, 10) ]; var hit = false; objects.keys(centers).forEach(function(key) { var pc = centers[key].pos; if ($v.len($v.substract(pc, pos)) < radius * 2) { hit = true; } }); if (hit || tries > 20) { i--; continue; } tries = 0 ; centers[k(pos)] = { pos: pos, body: gbox2d.createStaticCircle(pos, radius, true), }; } return this; };
update: function(msDuration) { var dt = msDuration; // FIXME we need this for particle.isAlive() but particles too // should depend on msDuration as passed by gamejs var now = Date.now(); var removeList = []; // update particles objects.keys(this.particles).forEach(function(key) { var particle = this.particles[key]; if (!particle.isAlive(now)) { removeList.push(particle.id); } else { particle.update(dt); } }, this); this.removeDeadParticles(removeList); },
this.draw = function(display) { objects.keys(centers).forEach(function(k) { var c = centers[k].pos; display.blit(image, [c[0] + radius, c[1] + radius]); }); };
gamejs.ready(function() { // prepare client view var playerContinent = document.location.hash && document.location.hash.substring(1) || 'eu'; var display = gamejs.display.setMode(gamejs.image.load('images/worldmap.png').getSize()); var yview = new YView(playerContinent); var sounds = new SoundManager(playerContinent); var clientWorld = yview.getWorldReference(); // setup statistic gathering unit var statGatherer = window.statGatherer = new StatisticGatherer(clientWorld, playerContinent); // setup ai players // they re-use the client's world but read-only (hopefully) to determin // what to do var aiPlayers = arrays.shuffle(objects.keys(clientWorld.continents)).filter(function(continent) { return continent !== playerContinent; }).map(function(continent) { return (new Player(clientWorld, continent)); }); // create server var yserver = window.yserver = new YServer(); var isRunning = true; var isForwarded = false; function tick(msDuration) { if (!isRunning) { if (!isForwarded) { var statData = statGatherer.toJSON(); statGatherer.render(); var statImageData = statGatherer.image._canvas.toDataURL(); document.location.href = "./stats.html#data=" + encodeURIComponent(JSON.stringify(statData)) + "&image=" +encodeURIComponent(statImageData); isForwarded = true; } return; } yview.update(msDuration); statGatherer.update(msDuration); // game loop yserver.update(msDuration); gamejs.event.get().forEach(function(event) { if (event.type === server.GAMESTATE) { if (event.data.gameOver) { isRunning = false; statGatherer.render(); return; } } if (event.type === server.ORDER) { yserver.handle(event); } else { if (event.type === server.RESULT) { statGatherer.handle(event); } yserver.handle(event); yview.handle(event); sounds.handle(event); aiPlayers.forEach(function(aiPlayer) { aiPlayer.handle(event); }); } }); display.clear(); yview.draw(display); return; }; gamejs.time.fpsCallback(tick, this, 26); });
var YWorld = exports.YWorld = function() { var self = this; this.agents = gamejs.http.load('./data/agents.json'); this.continents = gamejs.http.load('./data/continents.json'); this.connections = gamejs.http.load('./data/connections.json'); // FIXME store adjacent in extra 'connections' and resolve it here // at load time for easy indexOf() lookup var rawCities = gamejs.http.load('./data/cities.json'); this.cities = {}; this.populations = {}; $o.keys(this.continents).forEach(function(continent) { this.populations[continent] = 10000000; }, this); var $ = function(title) { return self.cities[title] || self.agents[title] || self.continents[title]; }; // convert raw cities into this.cities object $o.keys(rawCities).forEach(function(cityKey) { var $c = rawCities[cityKey]; $c.continent = $o.keys(this.continents).filter(function(continentKey) { return $(continentKey).indexOf(cityKey) > -1; })[0]; $c.infections = {}; $c.adjacent = []; $o.keys(this.continents).forEach(function(continent) { $c.infections[continent] = 0; }); this.cities[cityKey] = $c; }, this); // resolve connections this.connections.forEach(function(con) { var a = con[0]; var b = con[1]; if (!$(a) || !$(b)) return; $(a).adjacent.push(b); $(b).adjacent.push(a); }); /** * the resolves, create by the server, modify the world */ var APPLY = { setagentlocation: function(data) { $(data.agent).city = data.city; }, increaseinfection: function(data) { var $city = $(data.city); $city.infections[data.strain]++; }, decreaseinfection: function(data) { var $city = $(data.city); $city.infections[data.strain]--; if ($city.infections[data.strain] < 0) { gamejs.log('[World.apply] warning! infections < 0', data.strain,$city.infections[data.strain]); $city.infections[data.strain] = 0; } }, setpopulation: function(data) { this.populations[data.continent] = data.count; }, } /** * uses resolves to modify the world */ this.handle = function(event) { if (event.type === server.RESULT) { APPLY[event.data.type].apply(this, [event.data]); gamejs.info('[YWorld.handle]', event); if (event.data.agent) { $(event.data.agent).currentAction = null; } } else if (event.type === server.ACTION) { if (event.data.agent) { $(event.data.agent).currentAction = event.data; } } } return this; };
draw: function(display, offset) { // FIXME special source/in out blending objects.keys(this.particles).forEach(function(key) { this.particles[key].draw(display, offset); }, this); },