Server and client code completed (with bugs).
This commit is contained in:
parent
916c50e162
commit
88a6195fe8
182
game-client.js
182
game-client.js
@ -3,6 +3,11 @@ var Player = require("./player.js");
|
||||
var renderer = require("./game-renderer.js");
|
||||
var consts = require("./game-consts.js");
|
||||
|
||||
var GRID_SIZE = consts.GRID_SIZE;
|
||||
var CELL_WIDTH = consts.CELL_WIDTH;
|
||||
|
||||
renderer.allowAnimation = true;
|
||||
|
||||
/**
|
||||
* Provides requestAnimationFrame in a cross browser way.
|
||||
* @author paulirish / http://paulirish.com/
|
||||
@ -22,81 +27,7 @@ if ( !window.requestAnimationFrame ) {
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
$(function() {
|
||||
var GRID_SIZE = consts.GRID_SIZE;
|
||||
var CELL_WIDTH = consts.CELL_WIDTH;
|
||||
|
||||
|
||||
var canvas = $("#main-ui")[0];
|
||||
var ctx2 = canvas.getContext('2d');
|
||||
|
||||
var grid = renderer.grid;
|
||||
renderer.allowAnimation = true;
|
||||
|
||||
//Load players.
|
||||
for (var p = 0; p < 9; p++)
|
||||
{
|
||||
//TODO: socket loading.
|
||||
var pRow = getRandomInt(0, GRID_SIZE);
|
||||
var pCol = getRandomInt(0, GRID_SIZE);
|
||||
var sdata = {
|
||||
posX: pCol * CELL_WIDTH,
|
||||
posY: pRow * CELL_WIDTH,
|
||||
currentHeading: getRandomInt(0, 4),
|
||||
//name: ...,
|
||||
num: p
|
||||
};
|
||||
|
||||
renderer.addPlayer(new Player(true, grid, sdata));
|
||||
|
||||
for (var dr = -1; dr <= 1; dr++)
|
||||
for (var dc = -1; dc <= 1; dc++)
|
||||
if (!grid.isOutOfBounds(dr + pRow, dc + pCol))
|
||||
grid.set(dr + pRow, dc + pCol, renderer.getPlayer(p));
|
||||
}
|
||||
|
||||
//Load grid.
|
||||
for (var r = 0; r < grid.size; r++)
|
||||
{
|
||||
for (var c = 0; c < grid.size; c++)
|
||||
{
|
||||
//TODO: load data.
|
||||
//if (Math.random() > .9)
|
||||
// grid.set(r, c, players[getRandomInt(0, players.length)]);
|
||||
}
|
||||
}
|
||||
|
||||
var frameCount = 0;
|
||||
|
||||
//TODO: current player index
|
||||
var user = renderer.getPlayer(0);
|
||||
renderer.initUser(user);
|
||||
|
||||
function update()
|
||||
{
|
||||
renderer.update();
|
||||
}
|
||||
|
||||
//Thanks to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
|
||||
function getRandomInt(min, max) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
|
||||
function paintLoop(ctx)
|
||||
{
|
||||
renderer.paint(ctx); //TODO: pre-rendering.
|
||||
|
||||
//TODO: sync each loop with server. (server will give frame count.)
|
||||
frameCount++;
|
||||
update();
|
||||
requestAnimationFrame(paintLoop);
|
||||
}
|
||||
|
||||
paintLoop(ctx2);
|
||||
|
||||
var user, socket, frame;
|
||||
|
||||
//Event listeners
|
||||
$(document).keydown(function(e) {
|
||||
@ -115,9 +46,108 @@ $(function() {
|
||||
if (newHeading === user.currentHeading || ((newHeading % 2 === 0) ^
|
||||
(user.currentHeading % 2 === 0)))
|
||||
{
|
||||
//TODO: notify server.
|
||||
user.heading = newHeading;
|
||||
if (socket)
|
||||
socket.emit("frame", {
|
||||
frame: frame,
|
||||
heading: newHeading
|
||||
}, function(success, msg) {
|
||||
if (!success)
|
||||
{
|
||||
//TODO: restore frames.
|
||||
console.error(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
$(function() {
|
||||
var grid = renderer.grid;
|
||||
|
||||
//Socket connection.
|
||||
socket = require('socket.io-client')('http://paper-io-thekidofarcrania.c9users.io:8081');
|
||||
socket.on('connect', function(){
|
||||
console.info("Connected to server.");
|
||||
socket.emit('hello', {
|
||||
name: 'Test player',
|
||||
type: 0, //Free-for-all
|
||||
gameid: -1 //Requested game-id, or -1 for anyone.
|
||||
}, function(success) {
|
||||
if (success) console.info("Connected to game!");
|
||||
else console.error("Unable to connect to game.");
|
||||
});
|
||||
});
|
||||
socket.on('game', function(data){
|
||||
//Initialize game.
|
||||
//TODO: display data.gameid --- game id #
|
||||
renderer.reset();
|
||||
|
||||
//Load players.
|
||||
data.players.forEach(function(p) {
|
||||
renderer.addPlayer(new Player(true, grid, p));
|
||||
});
|
||||
user = renderer.getPlayerFromNum(data.num);
|
||||
renderer.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 : renderer.getPlayer(ind));
|
||||
}
|
||||
|
||||
frame = data.frame;
|
||||
});
|
||||
|
||||
socket.on('notifyFrame', function(data) {
|
||||
if (data.frame - 1 !== frame)
|
||||
{
|
||||
console.error("Frames don't match up!");
|
||||
socket.emit('requestFrame'); //Restore data.
|
||||
return;
|
||||
}
|
||||
|
||||
frame++;
|
||||
if (data.newPlayers)
|
||||
{
|
||||
data.newPlayers.forEach(function(p) {
|
||||
renderer.addPlayer(new Player(true, grid, p));
|
||||
});
|
||||
}
|
||||
|
||||
data.moves.forEach(function(val, i) {
|
||||
if (renderer.getPlayer(val) !== user)
|
||||
renderer.getPlayer(i).heading = val.heading;
|
||||
});
|
||||
|
||||
paintLoop();
|
||||
});
|
||||
|
||||
socket.on('disconnect', function(){
|
||||
console.info("Server has disconnected. Creating new game.");
|
||||
});
|
||||
|
||||
var deadFrames = 0;
|
||||
function paintLoop()
|
||||
{
|
||||
renderer.paint();
|
||||
if (user.dead && deadFrames === 60) //One second of frames
|
||||
{
|
||||
//TODO: Show welcome screen.
|
||||
deadFrames = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
renderer.update();
|
||||
if (user.dead)
|
||||
{
|
||||
socket.disconnect();
|
||||
deadFrames++;
|
||||
requestAnimationFrame(paintLoop);
|
||||
}
|
||||
}
|
||||
});
|
@ -10,7 +10,8 @@ var consts = {
|
||||
GRID_SIZE: constant(80),
|
||||
CELL_WIDTH: constant(40),
|
||||
SPEED: constant(5),
|
||||
BORDER_WIDTH: constant(20)
|
||||
BORDER_WIDTH: constant(20),
|
||||
MAX_PLAYERS: constant(255)
|
||||
};
|
||||
|
||||
Object.defineProperties(module.exports, consts);
|
@ -28,7 +28,9 @@ exports.updateFrame = function(grid, players, newPlayerFrames, dead, notifyKill)
|
||||
if (newPlayerFrames[val.num] < ANIMATE_FRAMES)
|
||||
newPlayerFrames[val.num]++;
|
||||
else
|
||||
{
|
||||
val.move();
|
||||
}
|
||||
|
||||
if (val.dead)
|
||||
adead.push(val);
|
||||
|
@ -35,13 +35,12 @@ $(function () {
|
||||
gameHeight = canvasHeight - BAR_HEIGHT;
|
||||
});
|
||||
|
||||
var animateGrid = new Grid(GRID_SIZE);
|
||||
|
||||
var allowAnimation = true;
|
||||
var players = [];
|
||||
var allPlayers = [];
|
||||
var newPlayerFrames = [];
|
||||
var playerPortion = [];
|
||||
var grid = new Grid(GRID_SIZE, function(row, col, before, after) {
|
||||
var animateGrid, players, allPlayers, newPlayerFrames, playerPortion, grid,
|
||||
animateTo, offset, user, lagPortion, portionSpeed, zoom, kills, showedDead;
|
||||
|
||||
grid = new Grid(GRID_SIZE, function(row, col, before, after) {
|
||||
//Keep track of areas.
|
||||
if (before)
|
||||
playerPortion[before.num]--;
|
||||
@ -58,16 +57,27 @@ var grid = new Grid(GRID_SIZE, function(row, col, before, after) {
|
||||
});
|
||||
});
|
||||
|
||||
var animateTo = [0, 0];
|
||||
var offset = [0, 0];
|
||||
function init() {
|
||||
animateGrid = new Grid(GRID_SIZE);
|
||||
grid.reset();
|
||||
|
||||
var user;
|
||||
var lagPortion = 0;
|
||||
var portionSpeed = 0;
|
||||
var zoom = 1;
|
||||
var kills = 0;
|
||||
players = [];
|
||||
allPlayers = [];
|
||||
newPlayerFrames = [];
|
||||
playerPortion = [];
|
||||
|
||||
var showedDead = false;
|
||||
animateTo = [0, 0];
|
||||
offset = [0, 0];
|
||||
|
||||
user = null;
|
||||
lagPortion = 0;
|
||||
portionSpeed = 0;
|
||||
zoom = 1;
|
||||
kills = 0;
|
||||
showedDead = false;
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
//Paint methods.
|
||||
function paintGridBorder(ctx)
|
||||
@ -207,17 +217,17 @@ function paintUIBar(ctx)
|
||||
var barOffset;
|
||||
ctx.fillStyle = "white";
|
||||
ctx.font = "24px Changa";
|
||||
barOffset = ctx.measureText(user.name).width + 20;
|
||||
ctx.fillText(user.name, 5, CELL_WIDTH - 5);
|
||||
barOffset = ctx.measureText(user ? user.name : "").width + 20;
|
||||
ctx.fillText(user ? user.name : "", 5, CELL_WIDTH - 5);
|
||||
|
||||
//Draw filled bar.
|
||||
ctx.fillStyle = "rgba(180, 180, 180, .3)";
|
||||
ctx.fillRect(barOffset, 0, BAR_WIDTH, BAR_HEIGHT);
|
||||
|
||||
var barSize = Math.ceil((BAR_WIDTH - MIN_BAR_WIDTH) * lagPortion + MIN_BAR_WIDTH);
|
||||
ctx.fillStyle = user.baseColor.rgbString();
|
||||
ctx.fillStyle = user ? user.baseColor.rgbString() : "";
|
||||
ctx.fillRect(barOffset, 0, barSize, CELL_WIDTH);
|
||||
ctx.fillStyle = user.shadowColor.rgbString();
|
||||
ctx.fillStyle = user ? user.shadowColor.rgbString() : "";
|
||||
ctx.fillRect(barOffset, CELL_WIDTH, barSize, SHADOW_OFFSET);
|
||||
|
||||
//Percentage
|
||||
@ -274,7 +284,7 @@ function paint(ctx)
|
||||
ctx.restore();
|
||||
paintUIBar(ctx);
|
||||
|
||||
if (user.dead && !showedDead)
|
||||
if ((!user || user.dead) && !showedDead)
|
||||
{
|
||||
showedDead = true;
|
||||
console.log("You died!");
|
||||
@ -302,7 +312,10 @@ function update() {
|
||||
}
|
||||
|
||||
//Change area percentage
|
||||
var userPortion = playerPortion[user.num] / (GRID_SIZE * GRID_SIZE);
|
||||
var userPortion;
|
||||
if (user) userPortion = playerPortion[user.num] / (GRID_SIZE * GRID_SIZE);
|
||||
else userPortion = 0;
|
||||
|
||||
if (lagPortion !== userPortion)
|
||||
{
|
||||
delta = userPortion - lagPortion;
|
||||
@ -330,7 +343,7 @@ function update() {
|
||||
|
||||
//TODO: animate player is dead. (maybe explosion?), and tail rewinds itself.
|
||||
//TODO: show when this player is dead
|
||||
centerOnPlayer(user, animateTo);
|
||||
if (user) centerOnPlayer(user, animateTo);
|
||||
}
|
||||
|
||||
//Helper methods.
|
||||
@ -381,6 +394,8 @@ function getBounceOffset(frame)
|
||||
|
||||
module.exports = exports = {
|
||||
addPlayer: function(player) {
|
||||
if (allPlayers[player.num])
|
||||
return; //Already added.
|
||||
allPlayers[player.num] = players[players.length] = player;
|
||||
newPlayerFrames[player.num] = 0;
|
||||
playerPortion[player.num] = 0;
|
||||
@ -390,16 +405,22 @@ module.exports = exports = {
|
||||
getPlayer: function(ind) {
|
||||
return players[ind];
|
||||
},
|
||||
playerNum: function() {
|
||||
getPlayerFromNum: function(num) {
|
||||
return allPlayers[num];
|
||||
},
|
||||
playerSize: function() {
|
||||
return players.length;
|
||||
},
|
||||
initUser: function(player) {
|
||||
setUser: function(player) {
|
||||
user = player;
|
||||
centerOnPlayer(user, offset);
|
||||
},
|
||||
incrementKill: function() {
|
||||
kills++;
|
||||
},
|
||||
reset: function() {
|
||||
init();
|
||||
},
|
||||
paint: paintDoubleBuff,
|
||||
update: update
|
||||
};
|
||||
|
@ -1,10 +1,12 @@
|
||||
var GRID_SIZE = 80;
|
||||
var CELL_WIDTH = 40;
|
||||
var MAX_PLAYERS = 255;
|
||||
|
||||
var Grid = require("./grid.js");
|
||||
var Player = require("./player.js");
|
||||
var core = require("./game-core.js");
|
||||
var consts = require("./game-consts.js");
|
||||
|
||||
var GRID_SIZE = consts.GRID_SIZE;
|
||||
var CELL_WIDTH = consts.CELL_WIDTH;
|
||||
var MAX_PLAYERS = consts.MAX_PLAYERS;
|
||||
|
||||
function Game(id)
|
||||
{
|
||||
@ -50,7 +52,7 @@ function Game(id)
|
||||
newPlayers.push(p);
|
||||
newPlayerFrames.push(p);
|
||||
nextInd++;
|
||||
core.initPlayer(p);
|
||||
core.initPlayer(grid, p);
|
||||
|
||||
var splayers = players.map(function(val) {return val.serialData();});
|
||||
client.emit("game", {
|
||||
@ -60,11 +62,12 @@ function Game(id)
|
||||
"players": splayers,
|
||||
"grid": gridSerialData(grid, players)
|
||||
});
|
||||
console.log(p.name + " joined.");
|
||||
|
||||
//TODO: limit number of requests per frame.
|
||||
client.on("requestFrame", function (fn) {
|
||||
client.on("requestFrame", function () {
|
||||
var splayers = players.map(function(val) {return val.serialData();});
|
||||
fn({
|
||||
client.emit("game", {
|
||||
"num": p.num,
|
||||
"gameid": id,
|
||||
"frame": frame,
|
||||
@ -72,6 +75,7 @@ function Game(id)
|
||||
"grid": gridSerialData(grid, players)
|
||||
});
|
||||
});
|
||||
|
||||
client.on("frame", function(data, errorHan){
|
||||
if (typeof data === "function")
|
||||
{
|
||||
@ -86,8 +90,8 @@ function Game(id)
|
||||
errorHan(false, "No data supplied.");
|
||||
else if (!checkInt(data.frame, 0, Infinity))
|
||||
errorHan(false, "Requires a valid non-negative frame integer.");
|
||||
else if (data.frame < frame)
|
||||
errorHan(false, "Late frame received.");
|
||||
//else if (data.frame < frame)
|
||||
// errorHan(false, "Late frame received.");
|
||||
else if (data.frame > frame)
|
||||
errorHan(false, "Invalid frame received.");
|
||||
else
|
||||
@ -109,10 +113,11 @@ function Game(id)
|
||||
|
||||
|
||||
this.tickFrame = function() {
|
||||
//TODO: notify those that drop out.
|
||||
var snews = newPlayers.map(function(val) {return val.serialData();});
|
||||
var moves = players.map(function(val) {return {heading: val.heading};});
|
||||
|
||||
var data = {moves: moves};
|
||||
var data = {frame: frame + 1, moves: moves};
|
||||
if (snews.length > 0)
|
||||
{
|
||||
data.newPlayers = snews;
|
||||
@ -129,7 +134,10 @@ function Game(id)
|
||||
{
|
||||
var dead = [];
|
||||
core.updateFrame(grid, players, newPlayerFrames, dead);
|
||||
dead.forEach(function(val) { val.client.disconnect(true); });
|
||||
dead.forEach(function(val) {
|
||||
console.log(val.name + " died.");
|
||||
val.client.disconnect(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
10
grid.js
10
grid.js
@ -1,6 +1,7 @@
|
||||
function Grid(size, changeCallback)
|
||||
{
|
||||
var grid = new Array(size);
|
||||
var modified = false;
|
||||
|
||||
var data = {
|
||||
grid: grid,
|
||||
@ -26,8 +27,17 @@ function Grid(size, changeCallback)
|
||||
if (typeof changeCallback === "function")
|
||||
changeCallback(row, col, before, value);
|
||||
|
||||
modified = true;
|
||||
|
||||
return before;
|
||||
}
|
||||
this.reset = function() {
|
||||
if (modified)
|
||||
{
|
||||
grid = new Array(size);
|
||||
modified = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.isOutOfBounds = isOutOfBounds.bind(this, data);
|
||||
|
||||
|
15
player.js
15
player.js
@ -1,6 +1,10 @@
|
||||
var Stack = require("./stack.js");
|
||||
var Color = require("./color.js");
|
||||
var Grid = require("./grid.js");
|
||||
var consts = require("./game-consts.js");
|
||||
|
||||
var GRID_SIZE = consts.GRID_SIZE;
|
||||
var CELL_WIDTH = consts.CELL_WIDTH;
|
||||
|
||||
function defineGetter(getter) {
|
||||
return {
|
||||
@ -24,9 +28,6 @@ function defineAccessorProperties(thisobj, data /*, names...*/)
|
||||
Object.defineProperties(thisobj, descript);
|
||||
}
|
||||
|
||||
var CELL_WIDTH = 40;
|
||||
var GRID_SIZE = 80;
|
||||
|
||||
function TailMove(orientation)
|
||||
{
|
||||
this.move = 1;
|
||||
@ -53,7 +54,7 @@ function Tail(player, sdata)
|
||||
{
|
||||
data.startRow = data.prevRow = sdata.startRow || 0;
|
||||
data.startCol = data.prevCol = sdata.startCol || 0;
|
||||
sdata.forEach(function(val) {
|
||||
sdata.tail.forEach(function(val) {
|
||||
addTail(data, val.orientation, val.move);
|
||||
});
|
||||
}
|
||||
@ -68,11 +69,11 @@ function Tail(player, sdata)
|
||||
|
||||
//Instance methods.
|
||||
function serialData(data) {
|
||||
return JSON.serialize({
|
||||
return {
|
||||
tail: data.tail,
|
||||
startRow: data.startRow,
|
||||
startCol: data.startCol
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function setTailGrid(data, tailGrid, r, c)
|
||||
@ -430,7 +431,7 @@ Player.prototype.render = function(ctx, fade)
|
||||
var mid = CELL_WIDTH / 2;
|
||||
var grd = ctx.createRadialGradient(this.posX + mid, this.posY + mid - SHADOW_OFFSET, 1,
|
||||
this.posX + mid, this.posY + mid - SHADOW_OFFSET, CELL_WIDTH);
|
||||
grd.addColorStop(0, this.baseColor.rgbString().deriveAlpha(fade));
|
||||
grd.addColorStop(0, this.baseColor.deriveAlpha(fade).rgbString());
|
||||
grd.addColorStop(1, new Color(0, 0, 1, fade).rgbString());
|
||||
ctx.fillStyle = grd;
|
||||
ctx.fillRect(this.posX - 1, this.posY - SHADOW_OFFSET, CELL_WIDTH + 2, CELL_WIDTH);
|
||||
|
8253
public/bundle.js
8253
public/bundle.js
File diff suppressed because it is too large
Load Diff
3
public/socket.io.min.js
vendored
3
public/socket.io.min.js
vendored
File diff suppressed because one or more lines are too long
19
server.js
19
server.js
@ -8,17 +8,24 @@ var serve = serveStatic('public/', {'cacheControl': false});
|
||||
// Create server
|
||||
var server = http.createServer(function onRequest (req, res) {
|
||||
serve(req, res, finalhandler(req, res))
|
||||
})
|
||||
});
|
||||
|
||||
// Listen
|
||||
server.listen(8080);
|
||||
|
||||
var server = http.createServer();
|
||||
server = http.createServer();
|
||||
var io = require('socket.io')(server);
|
||||
var games = [];
|
||||
var Game = require('./game-server.js');
|
||||
var games = [new Game()];
|
||||
io.on('connection', function(socket){
|
||||
socket.emit('message', 'hello.'); // emit an event to the socket
|
||||
io.emit('message', 'new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.new person.'); // emit an event to all connected sockets
|
||||
socket.on('reply', function(){ /* */ }); // listen to the event
|
||||
socket.on("hello", function(data, fn) {
|
||||
//TODO: error checking.
|
||||
fn(true);
|
||||
games[0].addPlayer(socket, data.name);
|
||||
});
|
||||
});
|
||||
server.listen(8081);
|
||||
|
||||
setInterval(function() {
|
||||
games[0].tickFrame();
|
||||
}, 1000 / 60);
|
Loading…
Reference in New Issue
Block a user