forked from ilikecats/papercats
Animations work! (albeit laggy)
This commit is contained in:
parent
30023a7f3c
commit
3ce7ba97cf
49
Grid.js
Normal file
49
Grid.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
this.Grid = (function()
|
||||||
|
{
|
||||||
|
function Grid(size, changeCallback)
|
||||||
|
{
|
||||||
|
var grid = new Array(size);
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
grid: grid,
|
||||||
|
size: size
|
||||||
|
};
|
||||||
|
|
||||||
|
this.get = function(row, col)
|
||||||
|
{
|
||||||
|
if (isOutOfBounds(data, row, col))
|
||||||
|
throw new RangeError("Row or Column value out of bounds");
|
||||||
|
return grid[row] && grid[row][col];
|
||||||
|
}
|
||||||
|
this.set = function(row, col, value)
|
||||||
|
{
|
||||||
|
if (isOutOfBounds(data, row, col))
|
||||||
|
throw new RangeError("Row or Column value out of bounds");
|
||||||
|
|
||||||
|
if (!grid[row])
|
||||||
|
grid[row] = new Array(size);
|
||||||
|
var before = grid[row][col];
|
||||||
|
grid[row][col] = value;
|
||||||
|
|
||||||
|
if (typeof changeCallback === "function")
|
||||||
|
changeCallback(row, col, before, value);
|
||||||
|
|
||||||
|
return before;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isOutOfBounds = isOutOfBounds.bind(this, data);
|
||||||
|
|
||||||
|
Object.defineProperty(this, "size", {
|
||||||
|
get: function() {return size; },
|
||||||
|
enumerable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOutOfBounds(data, row, col)
|
||||||
|
{
|
||||||
|
return row < 0 || row >= data.size || col < 0 || col >= data.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Grid;
|
||||||
|
})()
|
87
color.js
Normal file
87
color.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
this.Color = function()
|
||||||
|
{
|
||||||
|
|
||||||
|
function Color(h, s, l, a)
|
||||||
|
{
|
||||||
|
verifyRange(h, s, l);
|
||||||
|
if (a === undefined) a = 1;
|
||||||
|
else verifyRange(a);
|
||||||
|
|
||||||
|
Object.defineProperties(this, {
|
||||||
|
"hue": {value: h, enumerable: true},
|
||||||
|
"sat": {value: s, enumerable: true},
|
||||||
|
"lum": {value: l, enumerable: true},
|
||||||
|
"alpha": {value: a, enumerable: true},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyRange()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < arguments.length; i++)
|
||||||
|
{
|
||||||
|
if (arguments[i] < 0 || arguments[i] > 1)
|
||||||
|
throw new RangeError("H, S, L, and A parameters must be between the range [0, 1]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Color.prototype.deriveLumination = function(amount)
|
||||||
|
{
|
||||||
|
var lum = this.lum + amount;
|
||||||
|
lum = Math.min(Math.max(lum, 0), 1);
|
||||||
|
return new Color(this.hue, this.sat, lum, this.alpha);
|
||||||
|
};
|
||||||
|
|
||||||
|
Color.prototype.deriveHue = function(amount)
|
||||||
|
{
|
||||||
|
var hue = this.hue - amount;
|
||||||
|
return new Color(hue - Math.floor(hue), this.sat, this.lum, this.alpha);
|
||||||
|
};
|
||||||
|
|
||||||
|
Color.prototype.deriveSaturation = function(amount)
|
||||||
|
{
|
||||||
|
var sat = this.sat + amount;
|
||||||
|
sat = Math.min(Math.max(sat, 0), 1);
|
||||||
|
return new Color(this.hue, sat, this.lum, this.alpha);
|
||||||
|
};
|
||||||
|
|
||||||
|
Color.prototype.deriveAlpha = function(newAlpha)
|
||||||
|
{
|
||||||
|
verifyRange(newAlpha);
|
||||||
|
return new Color(this.hue, this.sat, this.lum, newAlpha);
|
||||||
|
};
|
||||||
|
|
||||||
|
Color.prototype.rgbString = function() {
|
||||||
|
var rgb = hslToRgb(this.hue, this.sat, this.lum);
|
||||||
|
rgb[3] = this.a;
|
||||||
|
return 'rgba(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ', ' + this.alpha + ')';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//http://stackoverflow.com/a/9493060/7344257
|
||||||
|
function hslToRgb(h, s, l){
|
||||||
|
var r, g, b;
|
||||||
|
|
||||||
|
if(s == 0){
|
||||||
|
r = g = b = l; // achromatic
|
||||||
|
}else{
|
||||||
|
var hue2rgb = function hue2rgb(p, q, t){
|
||||||
|
if(t < 0) t += 1;
|
||||||
|
if(t > 1) t -= 1;
|
||||||
|
if(t < 1/6) return p + (q - p) * 6 * t;
|
||||||
|
if(t < 1/2) return q;
|
||||||
|
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
|
||||||
|
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||||
|
var p = 2 * l - q;
|
||||||
|
r = hue2rgb(p, q, h + 1/3);
|
||||||
|
g = hue2rgb(p, q, h);
|
||||||
|
b = hue2rgb(p, q, h - 1/3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Color;
|
||||||
|
}()
|
216
game.js
216
game.js
@ -1,14 +1,12 @@
|
|||||||
var Player;
|
var Player;
|
||||||
|
|
||||||
if (!Player)
|
if (!Player)
|
||||||
throw new Error("Requires player.js");
|
throw new Error("Requires player.js");
|
||||||
|
|
||||||
//Thanks to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
|
var Grid;
|
||||||
function getRandomInt(min, max) {
|
if (!Grid)
|
||||||
min = Math.ceil(min);
|
throw new Error("Requires grid.js");
|
||||||
max = Math.floor(max);
|
|
||||||
return Math.floor(Math.random() * (max - min)) + min;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides requestAnimationFrame in a cross browser way.
|
* Provides requestAnimationFrame in a cross browser way.
|
||||||
@ -35,36 +33,47 @@ $(function() {
|
|||||||
var CELL_WIDTH = 30;
|
var CELL_WIDTH = 30;
|
||||||
var SPEED = 5;
|
var SPEED = 5;
|
||||||
var SHADOW_OFFSET = 5;
|
var SHADOW_OFFSET = 5;
|
||||||
|
var MAX_FRAMES = 16;
|
||||||
|
var DROP_HEIGHT = 16;
|
||||||
|
var BOUNCE_FRAMES = 8;
|
||||||
|
var DROP_SPEED = 2;
|
||||||
var canvas = $("#main-ui")[0];
|
var canvas = $("#main-ui")[0];
|
||||||
var ctx = canvas.getContext('2d');
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
var width = canvas.width = window.innerWidth - 20;
|
var width = canvas.width = window.innerWidth - 20;
|
||||||
var height = canvas.height = window.innerHeight - 20;
|
var height = canvas.height = window.innerHeight - 20;
|
||||||
|
|
||||||
var players = [];
|
var players = [];
|
||||||
var grid = [];
|
var animateOff = true;
|
||||||
|
var animateGrid = new Grid(GRID_SIZE);
|
||||||
|
var grid = new Grid(GRID_SIZE, function(row, col, before, after) {
|
||||||
|
if (before === after || animateOff)
|
||||||
|
return;
|
||||||
|
animateGrid.set(row, col, {
|
||||||
|
before: before,
|
||||||
|
after: after,
|
||||||
|
frame: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
//Load players.
|
//Load players.
|
||||||
for (var p = 0; p < 1; p++)
|
for (var p = 0; p < 9; p++)
|
||||||
{
|
{
|
||||||
//TODO: socket loading.
|
//TODO: socket loading.
|
||||||
players[p] = new Player(null, grid, p);
|
players[p] = new Player(null, grid, p, getRandomInt(0, GRID_SIZE), getRandomInt(0, GRID_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Load grid.
|
//Load grid.
|
||||||
for (var r = 0; r < GRID_SIZE; r++)
|
for (var r = 0; r < grid.size; r++)
|
||||||
{
|
{
|
||||||
grid[r] = [];
|
for (var c = 0; c < grid.size; c++)
|
||||||
for (var c = 0; c < GRID_SIZE; c++)
|
|
||||||
{
|
{
|
||||||
//TODO: load data.
|
//TODO: load data.
|
||||||
if (Math.random() < .9)
|
if (Math.random() > .9)
|
||||||
grid[r][c] = -1;
|
grid.set(r, c, players[getRandomInt(0, players.length)]);
|
||||||
else
|
|
||||||
grid[r][c] = players[getRandomInt(0, players.length)];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
animateOff = false;
|
||||||
|
|
||||||
var frameCount = 0;
|
var frameCount = 0;
|
||||||
var animateTo = [0, 0];
|
var animateTo = [0, 0];
|
||||||
@ -72,6 +81,7 @@ $(function() {
|
|||||||
|
|
||||||
//TODO: current player index
|
//TODO: current player index
|
||||||
var user = players[0];
|
var user = players[0];
|
||||||
|
centerOnPlayer(user, offset);
|
||||||
|
|
||||||
function update()
|
function update()
|
||||||
{
|
{
|
||||||
@ -115,9 +125,9 @@ $(function() {
|
|||||||
squaresIntersect(players[i].startY, players[j].startY))
|
squaresIntersect(players[i].startY, players[j].startY))
|
||||||
{
|
{
|
||||||
//...if one player is own his own territory, the other is out.
|
//...if one player is own his own territory, the other is out.
|
||||||
if (grid[players[i].row][players[i].col] === players[i])
|
if (grid.get(players[i].row, players[i].col) === players[i])
|
||||||
removing[j] = true;
|
removing[j] = true;
|
||||||
else if (grid[players[j].row][players[j].col] === players[j])
|
else if (grid.get(players[j].row, players[j].col) === players[j])
|
||||||
removing[i] = true;
|
removing[i] = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -148,13 +158,25 @@ $(function() {
|
|||||||
dead.forEach(function(val) {
|
dead.forEach(function(val) {
|
||||||
console.log(val.name + " is dead");
|
console.log(val.name + " is dead");
|
||||||
});
|
});
|
||||||
|
for (var r = 0; r < grid.size; r++)
|
||||||
|
{
|
||||||
|
for (var c = 0; c < grid.size; c++)
|
||||||
|
{
|
||||||
|
if (dead.indexOf(grid.get(r, c)) !== -1)
|
||||||
|
grid.set(r, c, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: animate dead, and if this player is dead.
|
//TODO: animate dead, and if this player is dead.
|
||||||
var xOff = Math.floor(user.posX - (width - CELL_WIDTH) / 2);
|
centerOnPlayer(user, animateTo);
|
||||||
var yOff = Math.floor(user.posY - (height - CELL_WIDTH) / 2);
|
}
|
||||||
|
|
||||||
animateTo[0] = Math.min(Math.max(xOff, 0), GRID_SIZE * CELL_WIDTH);
|
function centerOnPlayer(player, pos)
|
||||||
animateTo[1] = Math.min(Math.max(yOff, 0), GRID_SIZE * CELL_WIDTH);
|
{
|
||||||
|
var xOff = Math.floor(player.posX - (width - CELL_WIDTH) / 2);
|
||||||
|
var yOff = Math.floor(player.posY - (height - CELL_WIDTH) / 2);
|
||||||
|
pos[0] = Math.min(Math.max(xOff, 0), grid.size * CELL_WIDTH - width / 2);
|
||||||
|
pos[1] = Math.min(Math.max(yOff, 0), grid.size * CELL_WIDTH - width / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function area(player)
|
function area(player)
|
||||||
@ -168,6 +190,13 @@ $(function() {
|
|||||||
return Math.abs(player.startX - xDest);
|
return Math.abs(player.startX - xDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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 squaresIntersect(a, b)
|
function squaresIntersect(a, b)
|
||||||
{
|
{
|
||||||
if (a < b)
|
if (a < b)
|
||||||
@ -176,44 +205,122 @@ $(function() {
|
|||||||
return a < b + CELL_WIDTH;
|
return a < b + CELL_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function paintGridLines()
|
||||||
|
{
|
||||||
|
ctx.fillStyle = 'lightgray';
|
||||||
|
ctx.beginPath();
|
||||||
|
for (var x = modRotate(-offset[0], CELL_WIDTH); x < width; x += CELL_WIDTH)
|
||||||
|
{
|
||||||
|
ctx.moveTo(x, 0);
|
||||||
|
ctx.lineTo(x, height);
|
||||||
|
}
|
||||||
|
for (var y = modRotate(-offset[1], CELL_WIDTH); y < height; y+= CELL_WIDTH)
|
||||||
|
{
|
||||||
|
ctx.moveTo(0, y);
|
||||||
|
ctx.lineTo(width, y);
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
function modRotate(val, mod)
|
||||||
|
{
|
||||||
|
var res = val % mod;
|
||||||
|
if (res >= 0)
|
||||||
|
return res;
|
||||||
|
else
|
||||||
|
return mod + res;
|
||||||
|
}
|
||||||
|
|
||||||
function paintGrid()
|
function paintGrid()
|
||||||
{
|
{
|
||||||
//Paint bottom grid lines.
|
//Paint bottom grid lines.
|
||||||
//ctx.fillStyle = 'lightgray';
|
//paintGridLines();
|
||||||
//ctx.beginPath();
|
|
||||||
//for (var x = modRotate(-offset[0], CELL_WIDTH); x < width; x += CELL_WIDTH)
|
|
||||||
//{
|
|
||||||
// ctx.moveTo(x, 0);
|
|
||||||
// ctx.lineTo(x, height);
|
|
||||||
//}
|
|
||||||
//for (var y = modRotate(-offset[1], CELL_WIDTH); y < height; y+= CELL_WIDTH)
|
|
||||||
//{
|
|
||||||
// ctx.moveTo(0, y);
|
|
||||||
// ctx.lineTo(width, y);
|
|
||||||
//}
|
|
||||||
//ctx.stroke();
|
|
||||||
|
|
||||||
//Paint occupied areas.
|
//Paint occupied areas. (and fading ones).
|
||||||
for (var r = Math.floor(offset[1] / CELL_WIDTH); r * CELL_WIDTH - offset[1] < height; r++)
|
for (var r = Math.floor(offset[1] / CELL_WIDTH); r < grid.size && r * CELL_WIDTH - offset[1] < height; r++)
|
||||||
{
|
{
|
||||||
for (var c = Math.floor(offset[0] / CELL_WIDTH); c * CELL_WIDTH - offset[0] < width; c++)
|
for (var c = Math.floor(offset[0] / CELL_WIDTH); c < grid.size && c * CELL_WIDTH - offset[0] < width; c++)
|
||||||
{
|
{
|
||||||
if (grid[r][c] !== -1)
|
var p = grid.get(r, c);
|
||||||
|
var x = c * CELL_WIDTH, y = r * CELL_WIDTH, baseColor, shadowColor;
|
||||||
|
|
||||||
|
var animateSpec = animateGrid.get(r, c);
|
||||||
|
if (!animateOff && animateSpec)
|
||||||
{
|
{
|
||||||
var x = c * CELL_WIDTH,
|
if (animateSpec.before) //fading animation
|
||||||
y = r * CELL_WIDTH,
|
{
|
||||||
p = grid[r][c];
|
var alpha = 1 - (animateSpec.frame / MAX_FRAMES);
|
||||||
ctx.fillStyle = p.shadowColor;
|
baseColor = animateSpec.before.baseColor.deriveAlpha(alpha);
|
||||||
ctx.fillRect(x, y + SHADOW_OFFSET, CELL_WIDTH, CELL_WIDTH);
|
shadowColor = animateSpec.before.shadowColor.deriveAlpha(alpha);
|
||||||
ctx.fillStyle = p.baseColor;
|
}
|
||||||
ctx.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (p)
|
||||||
|
{
|
||||||
|
baseColor = p.baseColor;
|
||||||
|
shadowColor = p.shadowColor;
|
||||||
|
}
|
||||||
|
else //No animation nor is this player owned.
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ctx.fillStyle = shadowColor.rgbString();
|
||||||
|
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH, SHADOW_OFFSET);
|
||||||
|
ctx.fillStyle = baseColor.rgbString();
|
||||||
|
ctx.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animateOff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Paint squares with drop in animation.
|
||||||
|
for (var r = 0; r < grid.size; r++)
|
||||||
|
{
|
||||||
|
for (var c = 0; c < grid.size; c++)
|
||||||
|
{
|
||||||
|
animateSpec = animateGrid.get(r, c);
|
||||||
|
x = c * CELL_WIDTH, y = r * CELL_WIDTH;
|
||||||
|
|
||||||
|
if (animateSpec && !animateOff)
|
||||||
|
{
|
||||||
|
if (animateSpec.after)
|
||||||
|
{
|
||||||
|
|
||||||
|
var offsetBounce = 0;
|
||||||
|
if (animateSpec.frame >= MAX_FRAMES - BOUNCE_FRAMES)
|
||||||
|
{
|
||||||
|
var bounce = animateSpec.frame - MAX_FRAMES + BOUNCE_FRAMES;
|
||||||
|
var bounceHeight = BOUNCE_FRAMES / 2 * DROP_SPEED;
|
||||||
|
if (bounce >= BOUNCE_FRAMES / 2)
|
||||||
|
offsetBounce = bounceHeight - (bounce - BOUNCE_FRAMES / 2) * DROP_SPEED;
|
||||||
|
else
|
||||||
|
offsetBounce = bounce * DROP_SPEED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
offsetBounce = DROP_HEIGHT - DROP_SPEED * animateSpec.frame;
|
||||||
|
|
||||||
|
y -= offsetBounce;
|
||||||
|
|
||||||
|
shadowColor = animateSpec.after.shadowColor;
|
||||||
|
baseColor = animateSpec.after.baseColor.deriveLumination(-(offsetBounce / DROP_HEIGHT) * .1);
|
||||||
|
|
||||||
|
ctx.fillStyle = shadowColor.rgbString();
|
||||||
|
ctx.fillRect(x, y + SHADOW_OFFSET, CELL_WIDTH, CELL_WIDTH);
|
||||||
|
ctx.fillStyle = baseColor.rgbString();
|
||||||
|
ctx.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
animateSpec.frame++;
|
||||||
|
if (animateSpec.frame >= MAX_FRAMES)
|
||||||
|
animateGrid.set(r, c, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var showedDead = false;
|
||||||
function paintLoop()
|
function paintLoop()
|
||||||
{
|
{
|
||||||
ctx.fillStyle = 'whitesmoke';
|
ctx.fillStyle = 'whitesmoke';
|
||||||
@ -226,10 +333,11 @@ $(function() {
|
|||||||
});
|
});
|
||||||
ctx.setTransform(1, 0, 0, 1, 0, 0); //Reset transform.
|
ctx.setTransform(1, 0, 0, 1, 0, 0); //Reset transform.
|
||||||
|
|
||||||
if (user.dead)
|
if (user.dead && !showedDead)
|
||||||
{
|
{
|
||||||
|
showedDead = true;
|
||||||
console.log("You died!");
|
console.log("You died!");
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: sync each loop with server. (server will give frame count.)
|
//TODO: sync each loop with server. (server will give frame count.)
|
||||||
@ -242,6 +350,8 @@ $(function() {
|
|||||||
|
|
||||||
//Event listeners
|
//Event listeners
|
||||||
$(document).keydown(function(e) {
|
$(document).keydown(function(e) {
|
||||||
|
if (user.dead)
|
||||||
|
return;
|
||||||
var newHeading = -1;
|
var newHeading = -1;
|
||||||
switch (e.which)
|
switch (e.which)
|
||||||
{
|
{
|
||||||
|
93
player.js
93
player.js
@ -2,6 +2,10 @@ var Stack;
|
|||||||
if (!Stack)
|
if (!Stack)
|
||||||
throw new Error("Require stack.js");
|
throw new Error("Require stack.js");
|
||||||
|
|
||||||
|
var Color;
|
||||||
|
if (!Color)
|
||||||
|
throw new Error("Requre color.js");
|
||||||
|
|
||||||
var Tail = (function() {
|
var Tail = (function() {
|
||||||
var CELL_WIDTH = 30;
|
var CELL_WIDTH = 30;
|
||||||
var GRID_SIZE = 200;
|
var GRID_SIZE = 200;
|
||||||
@ -44,7 +48,6 @@ var Tail = (function() {
|
|||||||
if (!tailGrid[r])
|
if (!tailGrid[r])
|
||||||
tailGrid[r] = [];
|
tailGrid[r] = [];
|
||||||
tailGrid[r][c] = true;
|
tailGrid[r][c] = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTail(data, orientation)
|
function addTail(data, orientation)
|
||||||
@ -87,7 +90,7 @@ var Tail = (function() {
|
|||||||
|
|
||||||
function render2(data, ctx)
|
function render2(data, ctx)
|
||||||
{
|
{
|
||||||
ctx.fillStyle = data.player.tailColor;
|
ctx.fillStyle = data.player.tailColor.rgbString();
|
||||||
for (var r = 0; r < data.tailGrid.length; r++)
|
for (var r = 0; r < data.tailGrid.length; r++)
|
||||||
{
|
{
|
||||||
if (!data.tailGrid[r])
|
if (!data.tailGrid[r])
|
||||||
@ -100,7 +103,10 @@ var Tail = (function() {
|
|||||||
|
|
||||||
function render(data, ctx)
|
function render(data, ctx)
|
||||||
{
|
{
|
||||||
ctx.fillStyle = data.player.tailColor;
|
if (data.tail.length === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ctx.fillStyle = data.player.tailColor.rgbString();
|
||||||
|
|
||||||
var prevOrient = -1;
|
var prevOrient = -1;
|
||||||
var start = [data.startRow, data.startCol];
|
var start = [data.startRow, data.startCol];
|
||||||
@ -203,7 +209,7 @@ var Tail = (function() {
|
|||||||
function onTail(c) { return data.tailGrid[c[0]] && data.tailGrid[c[0]][c[1]]; }
|
function onTail(c) { return data.tailGrid[c[0]] && data.tailGrid[c[0]][c[1]]; }
|
||||||
|
|
||||||
var start = [data.startRow, data.startCol];
|
var start = [data.startRow, data.startCol];
|
||||||
var been = new Array(grid.length);
|
var been = new Grid(grid.size);
|
||||||
var coords = [];
|
var coords = [];
|
||||||
|
|
||||||
coords.push(start);
|
coords.push(start);
|
||||||
@ -213,18 +219,16 @@ var Tail = (function() {
|
|||||||
var r = coord[0];
|
var r = coord[0];
|
||||||
var c = coord[1];
|
var c = coord[1];
|
||||||
|
|
||||||
if (r < 0 || c < 0 || r >= grid.length || c >= grid[r].length)
|
if (grid.isOutOfBounds(r, c))
|
||||||
continue; //Out of bounds!
|
continue;
|
||||||
|
|
||||||
if (been[r] && been[r][c])
|
if (been.get(r, c))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (onTail(coord)) //on the tail.
|
if (onTail(coord)) //on the tail.
|
||||||
{
|
{
|
||||||
if (!been[r])
|
been.set(r, c, true);
|
||||||
been[r] = new Array(grid[r].length);
|
grid.set(r, c, data.player);
|
||||||
been[r][c] = true;
|
|
||||||
grid[r][c] = data.player;
|
|
||||||
|
|
||||||
//Find all spots that this tail encloses.
|
//Find all spots that this tail encloses.
|
||||||
floodFill(data, grid, r + 1, c, been);
|
floodFill(data, grid, r + 1, c, been);
|
||||||
@ -255,19 +259,17 @@ var Tail = (function() {
|
|||||||
var r = coord[0];
|
var r = coord[0];
|
||||||
var c = coord[1];
|
var c = coord[1];
|
||||||
|
|
||||||
if (r < 0 || c < 0 || r >= grid.length || c >= grid[r].length)
|
if (grid.isOutOfBounds(r, c))
|
||||||
{
|
{
|
||||||
surrounded = false;
|
surrounded = false;
|
||||||
continue; //Out of bounds!
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//End this traverse on boundaries (where we been, on the tail, and when we enter our territory)
|
//End this traverse on boundaries (where we been, on the tail, and when we enter our territory)
|
||||||
if ((been[r] && been[r][c]) || onTail(coord) || grid[r][c] === data.player)
|
if (been.get(r, c) || onTail(coord) || grid.get(r, c) === data.player)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!been[r])
|
been.set(r, c, true);
|
||||||
been[r] = new Array(grid[r].length);
|
|
||||||
been[r][c] = true;
|
|
||||||
|
|
||||||
if (surrounded)
|
if (surrounded)
|
||||||
filled.push(coord);
|
filled.push(coord);
|
||||||
@ -282,7 +284,7 @@ var Tail = (function() {
|
|||||||
while (!filled.isEmpty())
|
while (!filled.isEmpty())
|
||||||
{
|
{
|
||||||
coord = filled.pop();
|
coord = filled.pop();
|
||||||
grid[coord[0]][coord[1]] = data.player;
|
grid.set(coord[0], coord[1], data.player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,24 +304,23 @@ this.Player = (function() {
|
|||||||
var SPEED = 5;
|
var SPEED = 5;
|
||||||
var SHADOW_OFFSET = 10;
|
var SHADOW_OFFSET = 10;
|
||||||
|
|
||||||
function Player(socket, grid, num) {
|
function Player(socket, grid, num, row, col) {
|
||||||
var data = {};
|
var data = {};
|
||||||
|
|
||||||
//TODO: load player data and color.
|
//TODO: load player data and color.
|
||||||
|
|
||||||
var hue = Math.random();
|
var hue = Math.random();
|
||||||
var base = hslToRgb(hue, .8, .5);
|
var base = new Color(hue, .8, .5);
|
||||||
this.baseColor = rgbString(base);
|
this.baseColor = base;
|
||||||
this.shadowColor = rgbString(hslToRgb(hue, .8, .2));
|
this.shadowColor = base.deriveLumination(-.3);
|
||||||
base[3] = .5;
|
this.tailColor = base.deriveLumination(.2).deriveAlpha(.5);
|
||||||
this.tailColor = rgbaString(base);
|
|
||||||
|
|
||||||
this.name = 'Player ' + (num + 1);
|
this.name = 'Player ' + (num + 1);
|
||||||
|
|
||||||
data.grid = grid;
|
data.grid = grid;
|
||||||
data.curHeading = 2;
|
data.curHeading = 2;
|
||||||
data.row = Math.floor(Math.random() * 10) + 10;
|
data.row = row || 0;
|
||||||
data.col = 10;//num;
|
data.col = col || 0;
|
||||||
data.dead = false;
|
data.dead = false;
|
||||||
|
|
||||||
data.tail = new Tail(this);
|
data.tail = new Tail(this);
|
||||||
@ -350,13 +351,13 @@ this.Player = (function() {
|
|||||||
this.tail.render(ctx);
|
this.tail.render(ctx);
|
||||||
|
|
||||||
//Render player.
|
//Render player.
|
||||||
ctx.fillStyle = this.shadowColor;
|
ctx.fillStyle = this.shadowColor.rgbString();
|
||||||
ctx.fillRect(this.posX, this.posY, CELL_WIDTH, CELL_WIDTH);
|
ctx.fillRect(this.posX, this.posY, CELL_WIDTH, CELL_WIDTH);
|
||||||
|
|
||||||
var mid = CELL_WIDTH / 2;
|
var mid = CELL_WIDTH / 2;
|
||||||
var grd = ctx.createRadialGradient(this.posX + mid, this.posY + mid - SHADOW_OFFSET, 1,
|
var grd = ctx.createRadialGradient(this.posX + mid, this.posY + mid - SHADOW_OFFSET, 1,
|
||||||
this.posX + mid, this.posY + mid - SHADOW_OFFSET, CELL_WIDTH);
|
this.posX + mid, this.posY + mid - SHADOW_OFFSET, CELL_WIDTH);
|
||||||
grd.addColorStop(0, this.baseColor);
|
grd.addColorStop(0, this.baseColor.rgbString());
|
||||||
grd.addColorStop(1, "white");
|
grd.addColorStop(1, "white");
|
||||||
ctx.fillStyle = grd;
|
ctx.fillStyle = grd;
|
||||||
ctx.fillRect(this.posX, this.posY - SHADOW_OFFSET, CELL_WIDTH, CELL_WIDTH);
|
ctx.fillRect(this.posX, this.posY - SHADOW_OFFSET, CELL_WIDTH, CELL_WIDTH);
|
||||||
@ -394,13 +395,13 @@ this.Player = (function() {
|
|||||||
data.row = row;
|
data.row = row;
|
||||||
data.col = col;
|
data.col = col;
|
||||||
|
|
||||||
if (row < 0 || row > data.grid.length || col < 0 || col > data.grid[row].length)
|
if (data.grid.isOutOfBounds(row, col))
|
||||||
{
|
{
|
||||||
data.dead = true;
|
data.dead = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.grid[row][col] === this)
|
if (data.grid.get(row, col) === this)
|
||||||
{
|
{
|
||||||
//Safe zone!
|
//Safe zone!
|
||||||
this.tail.fillTail(data.grid);
|
this.tail.fillTail(data.grid);
|
||||||
@ -423,39 +424,7 @@ this.Player = (function() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//http://stackoverflow.com/a/9493060/7344257
|
|
||||||
function hslToRgb(h, s, l){
|
|
||||||
var r, g, b;
|
|
||||||
|
|
||||||
if(s == 0){
|
|
||||||
r = g = b = l; // achromatic
|
|
||||||
}else{
|
|
||||||
var hue2rgb = function hue2rgb(p, q, t){
|
|
||||||
if(t < 0) t += 1;
|
|
||||||
if(t > 1) t -= 1;
|
|
||||||
if(t < 1/6) return p + (q - p) * 6 * t;
|
|
||||||
if(t < 1/2) return q;
|
|
||||||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
|
||||||
return p;
|
|
||||||
};
|
|
||||||
|
|
||||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
||||||
var p = 2 * l - q;
|
|
||||||
r = hue2rgb(p, q, h + 1/3);
|
|
||||||
g = hue2rgb(p, q, h);
|
|
||||||
b = hue2rgb(p, q, h - 1/3);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
|
|
||||||
}
|
|
||||||
|
|
||||||
function rgbString(rgb) {
|
|
||||||
return 'rgb(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
function rgbaString(rgb) {
|
|
||||||
return 'rgba(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ', ' + rgb[3] + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
return Player;
|
return Player;
|
||||||
})();
|
})();
|
@ -1,4 +1,6 @@
|
|||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||||
|
<script src="color.js"></script>
|
||||||
|
<script src="Grid.js"></script>
|
||||||
<script src="stack.js"></script>
|
<script src="stack.js"></script>
|
||||||
<script src="player.js"></script>
|
<script src="player.js"></script>
|
||||||
<script src="game.js"></script>
|
<script src="game.js"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user