render arena
This commit is contained in:
@@ -0,0 +1,561 @@
|
||||
var gorobots_init = function gorobots(my, webgl){
|
||||
my.width = null;
|
||||
my.height = null;
|
||||
my.server = "ws://localhost:8666/ws/";
|
||||
my.websocket = null;
|
||||
my.id = null;
|
||||
my.connection_retry = 3000;
|
||||
my.state = null;
|
||||
my.spectator = false;
|
||||
|
||||
my.debug = false;
|
||||
my.debug_draw = true;
|
||||
|
||||
var grey = "#999999";
|
||||
|
||||
var colors = [
|
||||
"#222222", // Grey
|
||||
"#000099",
|
||||
"#009900",
|
||||
"#990000",
|
||||
"#009999",
|
||||
"#990099",
|
||||
"#999900",
|
||||
"#000044",
|
||||
"#004400",
|
||||
"#440000",
|
||||
"#004444",
|
||||
"#440044",
|
||||
"#444400",
|
||||
"#0000cc",
|
||||
"#00cc00",
|
||||
"#cc0000",
|
||||
"#00cccc",
|
||||
"#cc00cc",
|
||||
"#cccc00"
|
||||
];
|
||||
|
||||
|
||||
|
||||
my.connect = function(server){
|
||||
connection = new WebSocket(server, null);
|
||||
my.websocket = connection;
|
||||
console.log(connection);
|
||||
connection.onerror = function (error) {
|
||||
console.log('WebSocket Error ' + error);
|
||||
};
|
||||
|
||||
connection.onopen = function(){
|
||||
console.log("Connected to " + server);
|
||||
my.send_game_request();
|
||||
};
|
||||
|
||||
connection.onclose = function(){
|
||||
my.id = null;
|
||||
my.state = null;
|
||||
my.renderer.reset();
|
||||
console.log("Connection Closed");
|
||||
|
||||
if (my.connection_retry > 0){
|
||||
// Retry every few seconds
|
||||
console.log("Lost Connection: " + server);
|
||||
setTimeout(function(){
|
||||
my.websocket = my.connect(my.server);
|
||||
}, my.connection_retry);
|
||||
}
|
||||
};
|
||||
|
||||
connection.onmessage = function (e) {
|
||||
|
||||
// Handshake protocol, we must establish a game ID and send
|
||||
// the robot config for approval before we can play
|
||||
|
||||
new_data = JSON.parse(e.data);
|
||||
|
||||
if (my.state === null) {
|
||||
if (new_data.type == "idreq") {
|
||||
if ('id' in new_data){
|
||||
my.id = new_data['id'];
|
||||
console.log("Assigned ID " + my.id + " by server");
|
||||
} else {
|
||||
console.log("server failed to send us an id");
|
||||
}
|
||||
my.send_client_id();
|
||||
my.state = "gameparam";
|
||||
// send supported encodings
|
||||
my.websocket.send(JSON.stringify(["json"]));
|
||||
}
|
||||
} else if (my.state == "gameparam"){
|
||||
if (new_data.type == "gameparam") {
|
||||
// > [OK | FULL | NOT AUTH], board size, game params
|
||||
my.parse_game_params(new_data);
|
||||
my.state = "handshake";
|
||||
my.setup_robot();
|
||||
}
|
||||
} else if (my.state == "handshake") {
|
||||
// We have game details, make the render target
|
||||
console.log("completed handshake");
|
||||
console.log(new_data);
|
||||
if('success' in new_data) {
|
||||
if (!new_data.success){
|
||||
alert("Your Robot Config is not valid, adjust your point distributions and try again");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
my.renderer.setup_render_target(my.width, my.height, my.width, my.height);
|
||||
my.state = "play";
|
||||
} else if(my.state == "play") {
|
||||
if (new_data.type == "handshake") {
|
||||
// This is the handshake response, we've been assigned an ID
|
||||
// and are in the game (or TODO: in a lobby).
|
||||
console.log("we got a handshake when we expect a boardstate packet");
|
||||
} else if (new_data.type == "stats") {
|
||||
// XXX: need to actually assign this to the player/robots
|
||||
// ...
|
||||
console.log("\\o/ we have stats: " + JSON.stringify(new_data));
|
||||
} else if (new_data.type == "boardstate") {
|
||||
my.renderer.begin_frame(new_data['turn']);
|
||||
var draw_list = my.process_gameplay_packet(new_data);
|
||||
my.renderer.render(draw_list);
|
||||
my.renderer.end_frame();
|
||||
} else if (new_data.type == "gameover") {
|
||||
my.renderer.reset();
|
||||
} else {
|
||||
console.error("unexpected state ...");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return connection;
|
||||
};
|
||||
|
||||
my.prepare_data = function(data){
|
||||
|
||||
// get all the robot id's in the scanner list and find them in the
|
||||
// overall robot list so we can pass them to the robot code
|
||||
if (data['my_robots']){
|
||||
for (var i=0; i < data['my_robots'].length; i++){
|
||||
var bot = data['my_robots'][i];
|
||||
bot.messages = data.messages;
|
||||
|
||||
for(var p in bot['scanners']){
|
||||
var bot_id = bot['scanners'][p]['id'];
|
||||
|
||||
// find the scanner object in the pool of objects
|
||||
if (bot['scanners'][p]['type'] == 'robot'){
|
||||
|
||||
for (var b in data['robots']){
|
||||
if (data['robots'][b]['id'] == bot_id){
|
||||
bot['scanners'][p] = data['robots'][b];
|
||||
bot['scanners'][p].type = "robot";
|
||||
bot['scanners'][p].friend = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (var mybot in data['my_robots']){
|
||||
if (data['my_robots'][mybot].id == bot['scanners'][p].id){
|
||||
bot['scanners'][p].friend = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bot['scanners'][p]['type'] == 'projectile'){
|
||||
for (var b in data['projectiles']){
|
||||
if (data['projectiles'][b]['id'] == bot_id){
|
||||
bot['scanners'][p] = data['projectiles'][b];
|
||||
bot['scanners'][p].type = "projectile";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
my.process_gameplay_packet = function(new_data){
|
||||
|
||||
my.stats.begin();
|
||||
my.renderer.clear_debug();
|
||||
|
||||
var draw_list = [];
|
||||
|
||||
if (new_data.reset){
|
||||
// my.setup_robot();
|
||||
my.renderer.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!my.paused) {
|
||||
var debug_div = document.getElementById("raw-debug");
|
||||
if (debug_div){
|
||||
debug_div.innerHTML = JSON.stringify(new_data, undefined, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Prep the data
|
||||
new_data = my.prepare_data(new_data);
|
||||
|
||||
// Dump the contents of the message from the server
|
||||
if (!my.paused) {
|
||||
var debug_div = document.getElementById("debug");
|
||||
if (debug_div){
|
||||
debug_div.innerHTML = JSON.stringify(new_data, undefined, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the robots and build a list of what to draw
|
||||
var my_robots = new_data['my_robots'];
|
||||
var robots = new_data['robots'];
|
||||
var all_bots = new_data['all_bots'];
|
||||
|
||||
my.all_bots = [];
|
||||
my.my_bots = my_robots;
|
||||
// Set the list of players and assign colors
|
||||
var players = "";
|
||||
|
||||
var col = 2;
|
||||
for (i=0; i < all_bots.length; i++){
|
||||
my.all_bots.push(all_bots[i]['robot_id']);
|
||||
|
||||
// I hate javascript
|
||||
var health_str = "";
|
||||
if (all_bots[i]['health'] < 0) {
|
||||
health_str = "000";
|
||||
all_bots[i]['color'] = grey;
|
||||
}
|
||||
else if (all_bots[i]['health'] < 10) {
|
||||
health_str = "00" + all_bots[i]['health'];
|
||||
all_bots[i]['color'] = colors[col];
|
||||
}
|
||||
else if (all_bots[i]['health'] < 100){
|
||||
health_str = "0" + all_bots[i]['health'];
|
||||
all_bots[i]['color'] = colors[col];
|
||||
}
|
||||
else{
|
||||
health_str = all_bots[i]['health'];
|
||||
all_bots[i]['color'] = colors[col];
|
||||
}
|
||||
|
||||
var mine = false;
|
||||
for (var mybot in my.my_bots){
|
||||
if (my.my_bots[mybot].id == all_bots[i]['robot_id']){
|
||||
mine = true;
|
||||
all_bots[i]['color'] = colors[1];
|
||||
}
|
||||
}
|
||||
if (!mine){
|
||||
col++;
|
||||
}
|
||||
|
||||
players += ("<span style='color: " +
|
||||
all_bots[i]['color'] +
|
||||
";'>  " +
|
||||
all_bots[i]['robot_id'] +
|
||||
" [" + health_str + "]</span>");
|
||||
}
|
||||
|
||||
var players_div = document.getElementById("players");
|
||||
if (players_div){
|
||||
players_div.innerHTML = players;
|
||||
}
|
||||
|
||||
// Now let's deal with all the things in the world
|
||||
var i = 0;
|
||||
if (my_robots){
|
||||
instructions = {};
|
||||
for (i=0; i < my_robots.length; i++){
|
||||
if (my_robots[i].health > 0) {
|
||||
instructions[my_robots[i]['id']] = my.update_robot(my_robots[i], new_data['obj']);
|
||||
}
|
||||
|
||||
for (var bot in all_bots){
|
||||
if (all_bots[bot]['robot_id'] == my_robots[i]['id']){
|
||||
col = all_bots[bot]['color'];
|
||||
}
|
||||
}
|
||||
|
||||
if (my_robots[i].health <= 0){
|
||||
col = grey;
|
||||
}
|
||||
|
||||
if ("position" in my_robots[i]){
|
||||
my_robots[i]['color'] = col;
|
||||
my_robots[i]['type'] = 'robot';
|
||||
draw_list.push(my_robots[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (my.websocket){
|
||||
var payload = JSON.stringify(instructions);
|
||||
// console.log(payload);
|
||||
my.websocket.send(payload);
|
||||
}
|
||||
|
||||
if (my.target < 0 && !my.spectator){
|
||||
console.log("Watching " + my.my_bots[0].id);
|
||||
my.renderer.set_focus_robot(my.my_bots[0].id);
|
||||
my.target = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (robots){
|
||||
for (i=0; i < robots.length; i++){
|
||||
|
||||
// Get the color from all_bots
|
||||
var col = grey;
|
||||
for (var bot in all_bots){
|
||||
if (all_bots[bot]['robot_id'] == robots[i]['id']){
|
||||
col = all_bots[bot]['color'];
|
||||
}
|
||||
}
|
||||
|
||||
if (robots[i].health <= 0){
|
||||
col = grey;
|
||||
}
|
||||
|
||||
if ("position" in robots[i]){
|
||||
robots[i]['color'] = col;
|
||||
robots[i]['type'] = 'robot';
|
||||
draw_list.push(robots[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the projecticles
|
||||
var projectiles = new_data['projectiles'];
|
||||
if (projectiles){
|
||||
for (i=0; i < projectiles.length; i++){
|
||||
|
||||
if ("position" in projectiles[i]){
|
||||
projectiles[i]['type'] = 'bullet';
|
||||
draw_list.push(projectiles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the projecticles
|
||||
var splosions = new_data['splosions'];
|
||||
if (splosions){
|
||||
for (i=0; i < splosions.length; i++){
|
||||
if ("position" in splosions[i]){
|
||||
splosions[i]['type'] = 'explosion';
|
||||
draw_list.push(splosions[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the objects
|
||||
var obj = new_data['objects'];
|
||||
if (obj){
|
||||
for (i=0; i < obj.length; i++){
|
||||
var o = {
|
||||
bounds : obj[i]
|
||||
};
|
||||
o['type'] = "object";
|
||||
o['position'] = {x: obj[i][0], y: obj[i][1]};
|
||||
draw_list.push(o);
|
||||
}
|
||||
}
|
||||
my.stats.end();
|
||||
|
||||
return draw_list;
|
||||
};
|
||||
|
||||
my.eval_input = function( input, output ){
|
||||
var theResult, evalSucceeded;
|
||||
|
||||
try{
|
||||
theResult = eval( input );
|
||||
evalSucceeded = true;
|
||||
}
|
||||
catch(e){
|
||||
output.innerHTML = e;
|
||||
}
|
||||
|
||||
if ( evalSucceeded ) {
|
||||
output.innerHTML = "";
|
||||
// console.log("OK");
|
||||
}
|
||||
|
||||
return theResult;
|
||||
};
|
||||
|
||||
my.get_robot_code = function(){
|
||||
var robot_code = editor.getSession().getValue();
|
||||
var output = document.getElementById('output');
|
||||
|
||||
var code = "( " + robot_code + " )";
|
||||
var rc = my.eval_input(code, output);
|
||||
|
||||
return rc.call(this);
|
||||
};
|
||||
|
||||
my.send_game_request = function() {
|
||||
game = {
|
||||
"id": my.game_id,
|
||||
};
|
||||
console.log(my.websocket.readyState);
|
||||
my.websocket.send(JSON.stringify(game));
|
||||
console.log("sent clientid: " + JSON.stringify(game));
|
||||
};
|
||||
|
||||
my.send_client_id = function() {
|
||||
client_id = {
|
||||
"type": my.spectator ? "spectator" : "robot",
|
||||
"name": "dummy",
|
||||
"id": "24601",
|
||||
"useragent": "gorobots.js",
|
||||
};
|
||||
my.websocket.send(JSON.stringify(client_id));
|
||||
};
|
||||
|
||||
my.parse_game_params = function(params) {
|
||||
// TODO: flesh out validation?
|
||||
my.width = new_data.boardsize.width;
|
||||
my.height = new_data.boardsize.height;
|
||||
return true;
|
||||
};
|
||||
|
||||
my.setup_robot = function(){
|
||||
var robot = my.get_robot_code();
|
||||
if ('setup' in robot){
|
||||
var map = {"width": my.width, "height": my.height};
|
||||
var config = {
|
||||
"stats": robot.setup(map),
|
||||
"id": my.id
|
||||
};
|
||||
// console.log(config);
|
||||
if (!my.spectator) {
|
||||
my.websocket.send(JSON.stringify(config));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
my.update_robot = function(data, objects){
|
||||
var robot = my.get_robot_code();
|
||||
var map = {"width": my.width, "height": my.height, "obj": objects};
|
||||
|
||||
var instructions = null;
|
||||
if ('update' in robot){
|
||||
|
||||
var dbg = {
|
||||
"msg" : function(x, y, msg){
|
||||
my.renderer.debug_label(x,y,msg);
|
||||
},
|
||||
"msg_screen" : function(x, y, msg){
|
||||
my.renderer.debug_label_screen(x,y,msg);
|
||||
},
|
||||
"line" : function(x, y, x2, y2){
|
||||
my.renderer.debug_line(x,y,x2,y2);
|
||||
},
|
||||
};
|
||||
|
||||
instructions = robot.update(data, map, dbg);
|
||||
}
|
||||
return instructions;
|
||||
};
|
||||
|
||||
my.set_spectator = function(s){
|
||||
my.spectator = s;
|
||||
my.target=-1;
|
||||
$('body').keypress(function(e){
|
||||
if (my.renderer && my.renderer.canvas.clientWidth === 0){
|
||||
// dont respond to key events when canvas is not in view
|
||||
return;
|
||||
}
|
||||
|
||||
if(e.which == 116){
|
||||
// t
|
||||
if (my.spectator){
|
||||
my.target++;
|
||||
if( my.target < my.all_bots.length){
|
||||
console.log("Watching " + my.all_bots[my.target]);
|
||||
my.renderer.set_focus_robot(my.all_bots[my.target]);
|
||||
}
|
||||
else {
|
||||
my.target = -1;
|
||||
my.renderer.set_focus_robot(null);
|
||||
}
|
||||
} else {
|
||||
my.target++;
|
||||
if( my.target < my.my_bots.length){
|
||||
console.log(my.my_bots);
|
||||
console.log(my.my_bots[my.target].id);
|
||||
console.log("Watching " + my.my_bots[my.target].id);
|
||||
my.renderer.set_focus_robot(my.my_bots[my.target].id);
|
||||
}
|
||||
else {
|
||||
my.target = -1;
|
||||
my.renderer.set_focus_robot(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
my.set_server = function(server_name, game_id){
|
||||
my.server = server_name;
|
||||
my.game_id = game_id;
|
||||
my.state = null;
|
||||
if (my.websocket){
|
||||
console.log("Switching Server: " + my.server);
|
||||
my.websocket.close();
|
||||
my.renderer.shutdown();
|
||||
}
|
||||
else{
|
||||
console.log("Setting Server: " + my.server);
|
||||
my.websocket = my.connect(my.server);
|
||||
}
|
||||
};
|
||||
|
||||
my.init = function(){
|
||||
console.log("Welcome to GoRobots");
|
||||
if (webgl){
|
||||
my.renderer = gorobots_render_webgl();
|
||||
}
|
||||
else{
|
||||
my.renderer = gorobots_render_canvas();
|
||||
}
|
||||
|
||||
my.renderer.init("battlefield");
|
||||
|
||||
my.stats = new Stats();
|
||||
my.stats.setMode(0); // 0: fps, 1: ms
|
||||
|
||||
// Align top-left
|
||||
my.stats.domElement.style.position = 'absolute';
|
||||
|
||||
my.stats.domElement.style.left = '5px';
|
||||
my.stats.domElement.style.top = '120px';
|
||||
|
||||
document.body.appendChild( my.stats.domElement );
|
||||
$(my.stats.domElement).hide();
|
||||
|
||||
my.paused = false;
|
||||
$('body').keypress(function(e){
|
||||
|
||||
// alert(e.which);
|
||||
if(e.which == 112){
|
||||
// p
|
||||
my.paused = !my.paused;
|
||||
}
|
||||
|
||||
if (my.renderer && my.renderer.canvas.clientWidth === 0){
|
||||
// dont respond to key events when canvas is not in view
|
||||
return;
|
||||
}
|
||||
|
||||
if(e.which == 100){
|
||||
// d
|
||||
$(my.stats.domElement).toggle();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
my.init();
|
||||
return my;
|
||||
};
|
||||
Reference in New Issue
Block a user