Rename files

This commit is contained in:
StevenJoeZhang 2019-01-16 16:57:36 +08:00
parent 5c72a93605
commit bb6cb3171e
18 changed files with 460 additions and 448 deletions

View File

@ -20,13 +20,25 @@ After cloning this repository, run the follow commands to install dependencies a
npm start
```
## Bots
```bash
node src/bot/paper-io-bot-mode.js ws://localhost:8081
```
## Build
```bash
sudo npm install -g browserify uglify-es
browserify game-client.js | uglifyjs > public/bundle.js
browserify client.js | uglifyjs > public/bundle.js
```
## License
This is licensed under MIT. As such, please provide due credit and link back to this repository if possible.
Original Repo:
- Author: theKidOfArcrania
- Link: https://github.com/theKidOfArcrania/BlocklyIO

View File

@ -1,22 +0,0 @@
function Rolling(value, frames) {
var lag = 0;
if (!frames) frames = 24;
this.value = value;
Object.defineProperty(this, "lag", {
get: function() {
return lag;
},
enumerable: true
});
this.update = function() {
var delta = this.value - lag;
var dir = Math.sign(delta);
var speed = Math.abs(delta) / frames;
var mag = Math.min(Math.abs(speed), Math.abs(delta));
lag += mag * dir;
return lag;
}
}
module.exports = Rolling;

391
client.js
View File

@ -1,291 +1,100 @@
var core = require("./game-core");
var Player = core.Player;
var io = require("socket.io-client");
var GRID_SIZE = core.GRID_SIZE;
var CELL_WIDTH = core.CELL_WIDTH;
var running = false;
var user, socket, frame;
var players, allPlayers;
var kills;
var timeout = undefined;
var dirty = false;
var deadFrames = 0;
var requesting = -1; //frame that we are requesting at
var frameCache = []; //Frames after our request
var allowAnimation = true;
var grid = new core.Grid(core.GRID_SIZE, function(row, col, before, after) {
invokeRenderer("updateGrid", [row, col, before, after]);
});
var mimiRequestAnimationFrame = window && window.document
? window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function(callback) { window.setTimeout(callback, 1000 / 30) }
: function(callback) { window.setTimeout(callback, 1000 / 30) };
//Public API
function connectGame(url, name, callback) {
if (running) return; //Prevent multiple runs
running = true;
user = null;
deadFrames = 0;
//Socket connection
io.j = [];
io.sockets = [];
socket = io(url, {
"forceNew": true,
upgrade: false,
transports: ["websocket"]
});
socket.on("connect", function() {
console.info("Connected to server.");
});
socket.on("game", function(data) {
if (timeout != undefined) clearTimeout(timeout);
//Initialize game.
//TODO: display data.gameid --- game id #
frame = data.frame;
reset();
//Load players.
data.players.forEach(function(p) {
var pl = new Player(grid, p);
addPlayer(pl);
});
user = allPlayers[data.num];
if (!user) throw new Error();
setUser(user);
//Load grid.
var gridData = new Uint8Array(data.grid);
for (var r = 0; r < grid.size; r++) {
for (var c = 0; c < grid.size; c++) {
var ind = gridData[r * grid.size + c] - 1;
grid.set(r, c, ind === -1 ? null : players[ind]);
}
}
invokeRenderer("paint", []);
frame = data.frame;
if (requesting !== -1) {
//Update those cache frames after we updated game.
var minFrame = requesting;
requesting = -1;
while (frameCache.length > frame - minFrame) processFrame(frameCache[frame - minFrame]);
frameCache = [];
}
});
socket.on("notifyFrame", processFrame);
socket.on("dead", function() {
socket.disconnect(); //In case we didn"t get the disconnect call
});
socket.on("disconnect", function() {
if (!user) return;
console.info("Server has disconnected. Creating new game.");
socket.disconnect();
user.die();
dirty = true;
paintLoop();
running = false;
invokeRenderer("disconnect", []);
});
socket.emit("hello", {
name: name,
type: 0, //Free-for-all
gameid: -1 //Requested game-id, or -1 for anyone
}, function(success, msg) {
if (success) console.info("Connected to game!");
else {
console.error("Unable to connect to game: " + msg);
running = false;
}
if (callback) callback(success, msg);
});
}
function changeHeading(newHeading) {
if (!user || user.dead) return;
if (newHeading === user.currentHeading || ((newHeading % 2 === 0) ^ (user.currentHeading % 2 === 0))) {
//user.heading = newHeading;
if (socket) {
socket.emit("frame", {
frame: frame,
heading: newHeading
}, function(success, msg) {
if (!success) console.error(msg);
});
}
}
}
function getUser() {
return user;
}
function getOthers() {
var ret = [];
for (var p of players) {
if (p !== user) ret.push(p);
}
return ret;
}
function getPlayers() {
return players.slice();
}
//Private API
function addPlayer(player) {
if (allPlayers[player.num]) return; //Already added
allPlayers[player.num] = players[players.length] = player;
invokeRenderer("addPlayer", [player]);
return players.length - 1;
}
function invokeRenderer(name, args) {
var renderer = exports.renderer;
if (renderer && typeof renderer[name] === "function") renderer[name].apply(exports, args);
}
function processFrame(data) {
if (timeout != undefined) clearTimeout(timeout);
if (requesting !== -1 && requesting < data.frame) {
frameCache.push(data);
return;
}
if (data.frame - 1 !== frame) {
console.error("Frames don\"t match up!");
socket.emit("requestFrame"); //Restore data
requesting = data.frame;
frameCache.push(data);
return;
}
frame++;
if (data.newPlayers) {
data.newPlayers.forEach(function(p) {
if (p.num === user.num) return;
var pl = new Player(grid, p);
addPlayer(pl);
core.initPlayer(grid, pl);
});
}
var found = new Array(players.length);
data.moves.forEach(function(val, i) {
var player = allPlayers[val.num];
if (!player) return;
if (val.left) player.die();
found[i] = true;
player.heading = val.heading;
});
for (var i = 0; i < players.length; i++) {
//Implicitly leaving game
if (!found[i]) {
var player = players[i];
player && player.die();
}
}
update();
var locs = {};
for (var i = 0; i < players.length; i++) {
var p = players[i];
locs[p.num] = [p.posX, p.posY, p.waitLag];
}
/*
socket.emit("verify", {
frame: frame,
locs: locs
}, function(frame, success, adviceFix, msg) {
if (!success && requesting === -1) {
console.error(frame + ": " + msg);
if (adviceFix) socket.emit("requestFrame");
}
}.bind(this, frame));
*/
dirty = true;
mimiRequestAnimationFrame(function() {
paintLoop();
});
timeout = setTimeout(function() {
console.warn("Server has timed-out. Disconnecting.");
socket.disconnect();
}, 3000);
}
function paintLoop() {
if (!dirty) return;
invokeRenderer("paint", []);
dirty = false;
if (user && user.dead) {
if (timeout) clearTimeout(timeout);
if (deadFrames === 60) { //One second of frame
var before = allowAnimation;
allowAnimation = false;
update();
invokeRenderer("paint", []);
allowAnimation = before;
user = null;
deadFrames = 0;
return;
}
socket.disconnect();
deadFrames++;
dirty = true;
update();
mimiRequestAnimationFrame(paintLoop);
}
}
function reset() {
user = null;
grid.reset();
players = [];
allPlayers = [];
kills = 0;
invokeRenderer("reset");
}
function setUser(player) {
user = player;
invokeRenderer("setUser", [player]);
}
function update() {
var dead = [];
core.updateFrame(grid, players, dead, function addKill(killer, other) {
if (players[killer] === user && killer !== other) kills++;
});
dead.forEach(function(val) {
console.log((val.name || "Unnamed") + " is dead");
delete allPlayers[val.num];
invokeRenderer("removePlayer", [val]);
});
invokeRenderer("update", [frame]);
}
//Export stuff
var funcs = [connectGame, changeHeading, getOthers, getPlayers, getUser];
funcs.forEach(function(f) {
exports[f.name] = f;
});
exports.renderer = null;
Object.defineProperties(exports, {
allowAnimation: {
get: function() {
return allowAnimation;
},
set: function(val) {
allowAnimation = !!val;
},
enumerable: true
},
grid: {
get: function() {
return grid;
},
enumerable: true
},
kills: {
get: function() {
return kills;
},
enumerable: true
}
});
/* global $ */
var io = require("socket.io-client");
var client = require("./src/game-client");
client.allowAnimation = true;
client.renderer = require("./src/user-mode");
var core = require("./src/core");
var GRID_SIZE = core.GRID_SIZE;
var CELL_WIDTH = core.CELL_WIDTH;
var mimiRequestAnimationFrame = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function(callback) { window.setTimeout(callback, 1000 / 30) };
function run() {
var names = "Alice Bob Carol Dave Eve Francis Grace Hans Isabella Jason Kate Louis Margaret Nathan Olivia Paul Queen Richard Susan Thomas Uma Vivian Winnie Xander Yasmine Zach".split(" ");
var prefix = "Angry Baby Crazy Diligent Excited Fat Greedy Hungry Interesting Japanese Kind Little Magic Naïve Old Powerful Quiet Rich Superman THU Undefined Valuable Wifeless Xiangbuchulai Young Zombie".split(" ");
var name = $("#name").val() || [prefix[Math.floor(Math.random() * prefix.length)], names[Math.floor(Math.random() * names.length)]].join(" ");
$("#name").val(name);
client.connectGame("//" + window.location.hostname + ":8081", name, function(success, msg) {
if (success) {
$("#begin").fadeOut(1000);
$("#main-ui").fadeIn(1000);
}
else {
var error = $("#error");
error.text(msg);
}
});
}
$(function() {
var error = $("#error");
if (!window.WebSocket) {
error.text("Your browser does not support WebSockets!");
return;
}
error.text("Loading... Please wait"); //TODO: show loading screen
var socket = io("//" + window.location.hostname + ":8081", {
forceNew: true,
upgrade: false,
transports: ["websocket"]
});
socket.on("connect", function() {
socket.emit("pings");
});
socket.on("pongs", function() {
socket.disconnect();
error.text("All done, have fun!");
$("#name").keypress(function(evt) {
if (evt.which === 13) mimiRequestAnimationFrame(run);
});
$("#start").removeAttr("disabled").click(function(evt) {
mimiRequestAnimationFrame(run);
});
});
socket.on("connect_error", function() {
error.text("Cannot connect with server. This probably is due to misconfigured proxy server. (Try using a different browser)");
});
});
//Event listeners
$(document).keydown(function(e) {
var newHeading = -1;
switch (e.which) {
case 38: newHeading = 0; break; //UP
case 87: newHeading = 0; break; //UP (W)
case 39: newHeading = 1; break; //RIGHT
case 68: newHeading = 1; break; //RIGHT (D)
case 40: newHeading = 2; break; //DOWN
case 83: newHeading = 2; break; //DOWN (S)
case 37: newHeading = 3; break; //LEFT
case 65: newHeading = 3; break; //LEFT (A)
default: return; //Exit handler for other keys
}
client.changeHeading(newHeading);
//e.preventDefault();
});
$(document).on("touchmove", function(e) {
e.preventDefault();
});
$(document).on("touchstart", function (e1) {
var x1 = e1.targetTouches[0].pageX;
var y1 = e1.targetTouches[0].pageY;
$(document).one("touchend", function (e2) {
var x2 = e2.changedTouches[0].pageX;
var y2 = e2.changedTouches[0].pageY;
var deltaX = x2 - x1;
var deltaY = y2 - y1;
var newHeading = -1;
if (deltaY < 0 && Math.abs(deltaY) > Math.abs(deltaX)) newHeading = 0;
else if (deltaX > 0 && Math.abs(deltaY) < deltaX) newHeading = 1;
else if (deltaY > 0 && Math.abs(deltaX) < deltaY) newHeading = 2;
else if (deltaX < 0 && Math.abs(deltaX) > Math.abs(deltaY)) newHeading = 3;
client.changeHeading(newHeading);
});
});

View File

@ -1,102 +0,0 @@
/* global $ */
var client = require("./client");
var core = require("./game-core");
var io = require("socket.io-client");
var GRID_SIZE = core.GRID_SIZE;
var CELL_WIDTH = core.CELL_WIDTH;
client.allowAnimation = true;
client.renderer = require("./client-modes/user-mode");
var mimiRequestAnimationFrame = window && window.document
? window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function(callback) { window.setTimeout(callback, 1000 / 30) }
: function(callback) { window.setTimeout(callback, 1000 / 30) };
function run() {
var names = "Alice Bob Carol Dave Eve Francis Grace Hans Isabella Jason Kate Louis Margaret Nathan Olivia Paul Queen Richard Susan Thomas Uma Vivian Winnie Xander Yasmine Zach".split(" ");
var prefix = "Angry Baby Crazy Diligent Excited Fat Greedy Hungry Interesting Japanese Kind Little Magic Naïve Old Powerful Quiet Rich Superman THU Undefined Valuable Wifeless Xiangbuchulai Young Zombie".split(" ");
var name = $("#name").val() || [prefix[Math.floor(Math.random() * prefix.length)], names[Math.floor(Math.random() * names.length)]].join(" ");
$("#name").val(name);
client.connectGame("//" + window.location.hostname + ":8081", name, function(success, msg) {
if (success) {
$("#begin").fadeOut(1000);
$("#main-ui").fadeIn(1000);
}
else {
var error = $("#error");
error.text(msg);
}
});
}
$(function() {
var error = $("#error");
if (!window.WebSocket) {
error.text("Your browser does not support WebSockets!");
return;
}
error.text("Loading... Please wait"); //TODO: show loading screen
var socket = io("//" + window.location.hostname + ":8081", {
forceNew: true,
upgrade: false,
transports: ["websocket"]
});
socket.on("connect", function() {
socket.emit("pings");
});
socket.on("pongs", function() {
socket.disconnect();
error.text("All done, have fun!");
$("#name").keypress(function(evt) {
if (evt.which === 13) mimiRequestAnimationFrame(run);
});
$("#start").removeAttr("disabled").click(function(evt) {
mimiRequestAnimationFrame(run);
});
});
socket.on("connect_error", function() {
error.text("Cannot connect with server. This probably is due to misconfigured proxy server. (Try using a different browser)");
});
});
//Event listeners
$(document).keydown(function(e) {
var newHeading = -1;
switch (e.which) {
case 38: newHeading = 0; break; //UP
case 87: newHeading = 0; break; //UP (W)
case 39: newHeading = 1; break; //RIGHT
case 68: newHeading = 1; break; //RIGHT (D)
case 40: newHeading = 2; break; //DOWN
case 83: newHeading = 2; break; //DOWN (S)
case 37: newHeading = 3; break; //LEFT
case 65: newHeading = 3; break; //LEFT (A)
default: return; //Exit handler for other keys
}
client.changeHeading(newHeading);
//e.preventDefault();
});
$(document).on("touchmove", function(e) {
e.preventDefault();
});
$(document).on("touchstart", function (e1) {
var x1 = e1.targetTouches[0].pageX;
var y1 = e1.targetTouches[0].pageY;
$(document).one("touchend", function (e2) {
var x2 = e2.changedTouches[0].pageX;
var y2 = e2.changedTouches[0].pageY;
var deltaX = x2 - x1;
var deltaY = y2 - y1;
var newHeading = -1;
if (deltaY < 0 && Math.abs(deltaY) > Math.abs(deltaX)) newHeading = 0;
else if (deltaX > 0 && Math.abs(deltaY) < deltaX) newHeading = 1;
else if (deltaY > 0 && Math.abs(deltaX) < deltaY) newHeading = 2;
else if (deltaX < 0 && Math.abs(deltaX) > Math.abs(deltaY)) newHeading = 3;
client.changeHeading(newHeading);
});
});

File diff suppressed because one or more lines are too long

View File

@ -18,9 +18,10 @@ var server = http.createServer(function onRequest(req, res) {
// Listen
server.listen(port, hostname);
server = http.createServer();
var io = require("socket.io")(server);
io.set("transports", ["websocket"]);
var Game = require("./game-server.js");
var Game = require("./src/game-server.js");
var games = [new Game()];
io.on("connection", function(socket) {
socket.on("hello", function(data, fn) {

View File

@ -1,20 +1,15 @@
if (process.argv.length < 3) {
console.log("Usage: node game-client-bot.js <socket-url> [<name>]")
console.log("Usage: node bot-mode.js <socket-url> [<name>]")
process.exit(1);
}
var oldlog = console.log;
console.log = function(msg) {
return oldlog(`[${new Date()}] ${msg}`);
}
//TODO: add a land claiming algo (with coefficient parameters)
//TODO: add weight to the max land area and last land area, and also the number
//of kills
//TODO: genetic gene pooling
var core = require("../game-core");
var client = require("../client");
var core = require("../core");
var client = require("../game-client");
var GRID_SIZE = core.GRID_SIZE;
var CELL_WIDTH = core.CELL_WIDTH;
@ -26,7 +21,7 @@ var THRESHOLD = 10;
var startFrame = -1;
var endFrame = -1;
var coeffs = [0.6164220147940495, -2.519369747858328, 0.9198978109542851, -1.2158956330674564, -3.072901620397528, 5, 4];
var grid, others, user, playerPortion;
var grid, others, user, playerPortion = {};
var DIST_TYPES = {
land: {
check: function(loc) {
@ -64,6 +59,10 @@ var DIST_TYPES = {
}
};
function log(msg) {
return console.log(`[${new Date()}] ${msg}`);
}
function generateLandDirections() {
function mod(x) {
x %= 4;
@ -188,7 +187,7 @@ function printGrid() {
str += chars.get(r, c);
}
}
console.log(str);
log(str);
}
function update(frame) {
@ -211,7 +210,7 @@ function update(frame) {
weight += point;
str += distType + ": " + point + ", ";
}
//console.log(str);
//log(str);
weights[d] = weight;
}
@ -232,7 +231,7 @@ function update(frame) {
total++;
}
}
//console.log(weights)
//log(weights)
//Choose a random direction from the weighted list
var choice = Math.random() * total;
var d = 0;
@ -255,9 +254,9 @@ client.renderer = {
disconnect: function() {
var dt = (endFrame - startFrame);
startFrame = -1;
console.log("I died... (survived for " + dt + " frames.)");
console.log("I killed " + client.kills + " player(s).");
console.log("Coefficients: " + coeffs);
log("I died... (survived for " + dt + " frames.)");
log("I killed " + client.kills + " player(s).");
log("Coefficients: " + coeffs);
var mutation = Math.min(10, Math.pow(2, calcFavorability(params)));
for (var i = 0; i < coeffs.length; i++) {

View File

@ -1,15 +1,10 @@
if (process.argv.length < 3) {
console.log("Usage: node game-client-bot.js <socket-url> [<name>]")
console.log("Usage: node paper-io-bot-mode.js <socket-url> [<name>]")
process.exit(1);
}
var oldlog = console.log;
console.log = function(msg) {
return oldlog(`[${new Date()}] ${msg}`);
}
var core = require("../game-core");
var client = require("../client");
var core = require("../core");
var client = require("../game-client");
var GRID_SIZE = core.GRID_SIZE;
var CELL_WIDTH = core.CELL_WIDTH;
@ -19,6 +14,10 @@ var startFrame = -1;
var endFrame = -1;
var grid, others, user, playerPortion = {}, claim = [];
function log(msg) {
return console.log(`[${new Date()}] ${msg}`);
}
function mod(x) {
x %= 4;
if (x < 0) x += 4;
@ -189,8 +188,8 @@ client.renderer = {
var dt = (endFrame - startFrame);
startFrame = -1;
console.log("I died... (survived for " + dt + " frames.)");
console.log("I killed " + client.kills + " player(s).");
log("I died... (survived for " + dt + " frames.)");
log("I killed " + client.kills + " player(s).");
connect();
},
removePlayer: function(player) {

View File

@ -1,4 +1,4 @@
var core = require("./game-core");
var core = require("./core");
var consts = require("./game-consts");
exports.Color = require("./color");

296
src/game-client.js Normal file
View File

@ -0,0 +1,296 @@
var io = require("socket.io-client");
var core = require("./core");
var Player = core.Player;
var GRID_SIZE = core.GRID_SIZE;
var CELL_WIDTH = core.CELL_WIDTH;
var running = false;
var user, socket, frame;
var players, allPlayers;
var kills;
var timeout = undefined;
var dirty = false;
var deadFrames = 0;
var requesting = -1; //frame that we are requesting at
var frameCache = []; //Frames after our request
var allowAnimation = true;
var grid = new core.Grid(core.GRID_SIZE, function(row, col, before, after) {
invokeRenderer("updateGrid", [row, col, before, after]);
});
var mimiRequestAnimationFrame;
try {
if (window && window.document) {
mimiRequestAnimationFrame = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function(callback) { window.setTimeout(callback, 1000 / 30) };
}
}
catch (e) {
mimiRequestAnimationFrame = function(callback) { setTimeout(callback, 1000 / 30) };
}
//Public API
function connectGame(url, name, callback) {
if (running) return; //Prevent multiple runs
running = true;
user = null;
deadFrames = 0;
//Socket connection
io.j = [];
io.sockets = [];
socket = io(url, {
"forceNew": true,
upgrade: false,
transports: ["websocket"]
});
socket.on("connect", function() {
console.info("Connected to server.");
});
socket.on("game", function(data) {
if (timeout != undefined) clearTimeout(timeout);
//Initialize game.
//TODO: display data.gameid --- game id #
frame = data.frame;
reset();
//Load players.
data.players.forEach(function(p) {
var pl = new Player(grid, p);
addPlayer(pl);
});
user = allPlayers[data.num];
if (!user) throw new Error();
setUser(user);
//Load grid.
var gridData = new Uint8Array(data.grid);
for (var r = 0; r < grid.size; r++) {
for (var c = 0; c < grid.size; c++) {
var ind = gridData[r * grid.size + c] - 1;
grid.set(r, c, ind === -1 ? null : players[ind]);
}
}
invokeRenderer("paint", []);
frame = data.frame;
if (requesting !== -1) {
//Update those cache frames after we updated game.
var minFrame = requesting;
requesting = -1;
while (frameCache.length > frame - minFrame) processFrame(frameCache[frame - minFrame]);
frameCache = [];
}
});
socket.on("notifyFrame", processFrame);
socket.on("dead", function() {
socket.disconnect(); //In case we didn"t get the disconnect call
});
socket.on("disconnect", function() {
if (!user) return;
console.info("Server has disconnected. Creating new game.");
socket.disconnect();
user.die();
dirty = true;
paintLoop();
running = false;
invokeRenderer("disconnect", []);
});
socket.emit("hello", {
name: name,
type: 0, //Free-for-all
gameid: -1 //Requested game-id, or -1 for anyone
}, function(success, msg) {
if (success) console.info("Connected to game!");
else {
console.error("Unable to connect to game: " + msg);
running = false;
}
if (callback) callback(success, msg);
});
}
function changeHeading(newHeading) {
if (!user || user.dead) return;
if (newHeading === user.currentHeading || ((newHeading % 2 === 0) ^ (user.currentHeading % 2 === 0))) {
//user.heading = newHeading;
if (socket) {
socket.emit("frame", {
frame: frame,
heading: newHeading
}, function(success, msg) {
if (!success) console.error(msg);
});
}
}
}
function getUser() {
return user;
}
function getOthers() {
var ret = [];
for (var p of players) {
if (p !== user) ret.push(p);
}
return ret;
}
function getPlayers() {
return players.slice();
}
//Private API
function addPlayer(player) {
if (allPlayers[player.num]) return; //Already added
allPlayers[player.num] = players[players.length] = player;
invokeRenderer("addPlayer", [player]);
return players.length - 1;
}
function invokeRenderer(name, args) {
var renderer = exports.renderer;
if (renderer && typeof renderer[name] === "function") renderer[name].apply(exports, args);
}
function processFrame(data) {
if (timeout != undefined) clearTimeout(timeout);
if (requesting !== -1 && requesting < data.frame) {
frameCache.push(data);
return;
}
if (data.frame - 1 !== frame) {
console.error("Frames don\"t match up!");
socket.emit("requestFrame"); //Restore data
requesting = data.frame;
frameCache.push(data);
return;
}
frame++;
if (data.newPlayers) {
data.newPlayers.forEach(function(p) {
if (p.num === user.num) return;
var pl = new Player(grid, p);
addPlayer(pl);
core.initPlayer(grid, pl);
});
}
var found = new Array(players.length);
data.moves.forEach(function(val, i) {
var player = allPlayers[val.num];
if (!player) return;
if (val.left) player.die();
found[i] = true;
player.heading = val.heading;
});
for (var i = 0; i < players.length; i++) {
//Implicitly leaving game
if (!found[i]) {
var player = players[i];
player && player.die();
}
}
update();
var locs = {};
for (var i = 0; i < players.length; i++) {
var p = players[i];
locs[p.num] = [p.posX, p.posY, p.waitLag];
}
/*
socket.emit("verify", {
frame: frame,
locs: locs
}, function(frame, success, adviceFix, msg) {
if (!success && requesting === -1) {
console.error(frame + ": " + msg);
if (adviceFix) socket.emit("requestFrame");
}
}.bind(this, frame));
*/
dirty = true;
mimiRequestAnimationFrame(paintLoop);
timeout = setTimeout(function() {
console.warn("Server has timed-out. Disconnecting.");
socket.disconnect();
}, 3000);
}
function paintLoop() {
if (!dirty) return;
invokeRenderer("paint", []);
dirty = false;
if (user && user.dead) {
if (timeout) clearTimeout(timeout);
if (deadFrames === 60) { //One second of frame
var before = allowAnimation;
allowAnimation = false;
update();
invokeRenderer("paint", []);
allowAnimation = before;
user = null;
deadFrames = 0;
return;
}
socket.disconnect();
deadFrames++;
dirty = true;
update();
mimiRequestAnimationFrame(paintLoop);
}
}
function reset() {
user = null;
grid.reset();
players = [];
allPlayers = [];
kills = 0;
invokeRenderer("reset");
}
function setUser(player) {
user = player;
invokeRenderer("setUser", [player]);
}
function update() {
var dead = [];
core.updateFrame(grid, players, dead, function addKill(killer, other) {
if (players[killer] === user && killer !== other) kills++;
});
dead.forEach(function(val) {
console.log((val.name || "Unnamed") + " is dead");
delete allPlayers[val.num];
invokeRenderer("removePlayer", [val]);
});
invokeRenderer("update", [frame]);
}
//Export stuff
var funcs = [connectGame, changeHeading, getOthers, getPlayers, getUser];
funcs.forEach(function(f) {
exports[f.name] = f;
});
exports.renderer = null;
Object.defineProperties(exports, {
allowAnimation: {
get: function() {
return allowAnimation;
},
set: function(val) {
allowAnimation = !!val;
},
enumerable: true
},
grid: {
get: function() {
return grid;
},
enumerable: true
},
kills: {
get: function() {
return kills;
},
enumerable: true
}
});

View File

@ -1,4 +1,4 @@
var core = require("./game-core");
var core = require("./core");
var GRID_SIZE = core.GRID_SIZE;
var CELL_WIDTH = core.CELL_WIDTH;
var MAX_PLAYERS = core.MAX_PLAYERS;

View File

@ -1,8 +1,7 @@
/* global $ */
var core = require("../game-core");
var client = require("../client");
var Rolling = require("./rolling");
var core = require("./core");
var client = require("./game-client");
var GRID_SIZE = core.GRID_SIZE;
var CELL_WIDTH = core.CELL_WIDTH;
@ -320,6 +319,27 @@ function getBounceOffset(frame) {
}
}
function Rolling(value, frames) {
var lag = 0;
if (!frames) frames = 24;
this.value = value;
Object.defineProperty(this, "lag", {
get: function() {
return lag;
},
enumerable: true
});
this.update = function() {
var delta = this.value - lag;
var dir = Math.sign(delta);
var speed = Math.abs(delta) / frames;
var mag = Math.min(Math.abs(speed), Math.abs(delta));
lag += mag * dir;
return lag;
}
}
module.exports = exports = {
addPlayer: function(player) {
playerPortion[player.num] = 0;