forked from ilikecats/papercats
Zoom depending on player's area. Not done
This commit is contained in:
parent
4a0bd33a44
commit
7e6f2505b4
11
color.js
11
color.js
@ -23,6 +23,17 @@ function verifyRange()
|
||||
}
|
||||
}
|
||||
|
||||
Color.prototype.interpolateToString = function(color, amount)
|
||||
{
|
||||
var rgbThis = hslToRgb(this.hue, this.sat, this.lum);
|
||||
var rgbThat = hslToRgb(color.hue, color.sat, color.lum);
|
||||
var rgb = [];
|
||||
|
||||
for (var i = 0; i < 3; i++)
|
||||
rgb[i] = Math.floor((rgbThat[i] - rgbThis[i]) * amount + rgbThis[i]);
|
||||
return {rgbString: function() {return 'rgb(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ')'}};
|
||||
}
|
||||
|
||||
Color.prototype.deriveLumination = function(amount)
|
||||
{
|
||||
var lum = this.lum + amount;
|
||||
|
@ -1,5 +1,6 @@
|
||||
var Player = require("./player.js");
|
||||
var Grid = require("./grid.js");
|
||||
var Color = require("./color.js");
|
||||
|
||||
/**
|
||||
* Provides requestAnimationFrame in a cross browser way.
|
||||
@ -109,6 +110,7 @@ $(function() {
|
||||
var userPortion = 0;
|
||||
var lagPortion = 0;
|
||||
var portionSpeed = 0;
|
||||
var zoom = 1;
|
||||
|
||||
//TODO: current player index
|
||||
var user = players[0];
|
||||
@ -226,10 +228,10 @@ $(function() {
|
||||
|
||||
function centerOnPlayer(player, pos)
|
||||
{
|
||||
var xOff = Math.floor(player.posX - (gameWidth - CELL_WIDTH) / 2);
|
||||
var yOff = Math.floor(player.posY - (gameHeight - CELL_WIDTH) / 2);
|
||||
pos[0] = Math.max(Math.min(xOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - gameWidth), 0);
|
||||
pos[1] = Math.max(Math.min(yOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - gameHeight), 0);
|
||||
var xOff = Math.floor(player.posX - (gameWidth / zoom - CELL_WIDTH) / 2);
|
||||
var yOff = Math.floor(player.posY - (gameHeight / zoom - CELL_WIDTH) / 2);
|
||||
pos[0] = Math.max(Math.min(xOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - gameWidth / zoom), 0);
|
||||
pos[1] = Math.max(Math.min(yOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - gameHeight / zoom), 0);
|
||||
}
|
||||
|
||||
function area(player)
|
||||
@ -305,10 +307,13 @@ $(function() {
|
||||
//paintGridLines();
|
||||
|
||||
//Get viewing limits
|
||||
var minRow = Math.max(Math.floor((offset[1] - BORDER_WIDTH) / CELL_WIDTH), 0);
|
||||
var minCol = Math.max(Math.floor((offset[0] - BORDER_WIDTH) / CELL_WIDTH), 0);
|
||||
var maxRow = Math.min(Math.ceil((offset[1] + gameHeight) / CELL_WIDTH), grid.size);
|
||||
var maxCol = Math.min(Math.ceil((offset[0] + gameWidth) / CELL_WIDTH), grid.size);
|
||||
var offsetX = (offset[0] - BORDER_WIDTH);
|
||||
var offsetY = (offset[1] - BORDER_WIDTH);
|
||||
|
||||
var minRow = Math.max(Math.floor(offsetY / CELL_WIDTH), 0);
|
||||
var minCol = Math.max(Math.floor(offsetX / CELL_WIDTH), 0);
|
||||
var maxRow = Math.min(Math.ceil((offsetY + gameHeight / zoom) / CELL_WIDTH), grid.size);
|
||||
var maxCol = Math.min(Math.ceil((offsetX + gameWidth / zoom) / CELL_WIDTH), grid.size);
|
||||
|
||||
//Paint occupied areas. (and fading ones).
|
||||
for (var r = minRow; r < maxRow; r++)
|
||||
@ -319,13 +324,16 @@ $(function() {
|
||||
var x = c * CELL_WIDTH, y = r * CELL_WIDTH, baseColor, shadowColor;
|
||||
|
||||
var animateSpec = animateGrid.get(r, c);
|
||||
var adjust = 1;
|
||||
if (!animateOff && animateSpec)
|
||||
{
|
||||
if (animateSpec.before) //fading animation
|
||||
{
|
||||
var alpha = 1 - (animateSpec.frame / ANIMATE_FRAMES);
|
||||
baseColor = animateSpec.before.baseColor.deriveAlpha(alpha);
|
||||
shadowColor = animateSpec.before.shadowColor.deriveAlpha(alpha);
|
||||
var frac = (animateSpec.frame / ANIMATE_FRAMES);
|
||||
var back = new Color(.58, .41, .92, 1);
|
||||
baseColor = animateSpec.before.baseColor.interpolateToString(back, frac);
|
||||
shadowColor = animateSpec.before.shadowColor.interpolateToString(back, frac);
|
||||
adjust = 0;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
@ -343,11 +351,12 @@ $(function() {
|
||||
var bottomEmpty = !bottomAnimate || (bottomAnimate.after && bottomAnimate.before);
|
||||
if (hasBottom && ((!!bottomAnimate ^ !!animateSpec) || bottomEmpty))
|
||||
{
|
||||
|
||||
ctx.fillStyle = shadowColor.rgbString();
|
||||
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH, SHADOW_OFFSET);
|
||||
ctx.fillRect(x, y + CELL_WIDTH + 1, CELL_WIDTH + 1, SHADOW_OFFSET);
|
||||
}
|
||||
ctx.fillStyle = baseColor.rgbString();
|
||||
ctx.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
|
||||
ctx.fillRect(x, y, CELL_WIDTH + 1, CELL_WIDTH + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,9 +384,9 @@ $(function() {
|
||||
baseColor = animateSpec.after.baseColor.deriveLumination(-(offsetBounce / DROP_HEIGHT) * .1);
|
||||
|
||||
ctx.fillStyle = shadowColor.rgbString();
|
||||
ctx.fillRect(x, y + SHADOW_OFFSET, CELL_WIDTH, CELL_WIDTH);
|
||||
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH, SHADOW_OFFSET);
|
||||
ctx.fillStyle = baseColor.rgbString();
|
||||
ctx.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
|
||||
ctx.fillRect(x, y, CELL_WIDTH + 1, CELL_WIDTH + 1);
|
||||
}
|
||||
|
||||
animateSpec.frame++;
|
||||
@ -420,12 +429,17 @@ $(function() {
|
||||
ctx.fillStyle = 'whitesmoke';
|
||||
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
||||
|
||||
//Draw the grid items.
|
||||
//Move grid to viewport as said with the offsets, below the stats
|
||||
ctx.save();
|
||||
ctx.translate(0, BAR_HEIGHT);
|
||||
ctx.beginPath();
|
||||
ctx.translate(-offset[0] + BORDER_WIDTH, -offset[1] + BORDER_WIDTH + BAR_HEIGHT);
|
||||
ctx.rect(offset[0] - BORDER_WIDTH, offset[1] - BORDER_WIDTH, canvasWidth, canvasHeight);
|
||||
ctx.rect(0, 0, gameWidth, gameHeight);
|
||||
ctx.clip();
|
||||
|
||||
//Zoom in/out based on player stats.
|
||||
ctx.scale(zoom, zoom);
|
||||
ctx.translate(-offset[0] + BORDER_WIDTH, -offset[1] + BORDER_WIDTH);
|
||||
|
||||
paintGrid();
|
||||
players.forEach(function (p) {
|
||||
var fr = newPlayerFrames[p.num] || 0;
|
||||
@ -435,8 +449,6 @@ $(function() {
|
||||
p.render(ctx);
|
||||
});
|
||||
|
||||
|
||||
|
||||
//Reset transform to paint fixed UI elements
|
||||
ctx.restore();
|
||||
|
||||
@ -450,6 +462,8 @@ $(function() {
|
||||
barOffset = ctx.measureText(user.name).width + 10;
|
||||
ctx.fillText(user.name, 5, CELL_WIDTH - 5);
|
||||
|
||||
zoom = .0014 / lagPortion;
|
||||
|
||||
//Draw filled bar.
|
||||
ctx.fillStyle = "rgba(180, 180, 180, .3)";
|
||||
ctx.fillRect(barOffset, 0, BAR_WIDTH, BAR_HEIGHT);
|
||||
|
@ -1,20 +1,79 @@
|
||||
var Player = require("./player-server.js");
|
||||
var GRID_SIZE = 80;
|
||||
var CELL_WIDTH = 40;
|
||||
var Player = require("./player.js");
|
||||
|
||||
function Game(id)
|
||||
{
|
||||
|
||||
var players = [];
|
||||
var newPlayers = [];
|
||||
var frame = 0;
|
||||
|
||||
var filled = 0;
|
||||
var grid = new Grid(GRID_SIZE, function(row, col, before, after) {
|
||||
if (!!after ^ !!before)
|
||||
{
|
||||
if (after)
|
||||
filled++;
|
||||
else
|
||||
filled--;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.id = id;
|
||||
|
||||
this.addPlayer = function(client) {
|
||||
var p = {num: players.length, client: client};
|
||||
players.push(p);
|
||||
newPlayers.push(p);
|
||||
this.addPlayer = function(client, name) {
|
||||
var start = findEmpty(grid);
|
||||
if (!start)
|
||||
return false;
|
||||
|
||||
var params = {
|
||||
posX: start.col * CELL_WIDTH,
|
||||
posY: start.row * CELL_WIDTH,
|
||||
currentHeading: getRandomInt(0, 4),
|
||||
name: name,
|
||||
num: players.length
|
||||
}
|
||||
|
||||
var p = new Player(false, grid, params);
|
||||
p.client = client;
|
||||
player.push(p);
|
||||
newPlayer.push(p);
|
||||
|
||||
|
||||
client.emit("game", {players, })
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function findEmpty(grid)
|
||||
{
|
||||
var available = [];
|
||||
|
||||
for (var r = 1; r < grid.size - 1; r++)
|
||||
for (var c = 1; c < grid.size - 1; c++)
|
||||
{
|
||||
var cluttered = false;
|
||||
checkclutter: for (var dr = -1; dr <= 1; dr++)
|
||||
{
|
||||
for (var dc = -1; dc <= 1; dc++)
|
||||
{
|
||||
if (grid.get(r + dr, c + dc))
|
||||
{
|
||||
cluttered = true;
|
||||
break checkclutter;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cluttered)
|
||||
available.push({row: r, col: c});
|
||||
}
|
||||
|
||||
if (available.length === 0)
|
||||
return null;
|
||||
else
|
||||
return available[Math.floor(available.length * Math.random())];
|
||||
}
|
||||
|
||||
module.exports = Game;
|
11
player.js
11
player.js
@ -386,7 +386,16 @@ function Player(isClient, grid, sdata) {
|
||||
//Instance methods.
|
||||
this.move = move.bind(this, data);
|
||||
this.die = function() {data.dead = true;};
|
||||
|
||||
this.serialData = function() {
|
||||
return {
|
||||
num: data.num,
|
||||
name: data.name,
|
||||
posX: data.posX,
|
||||
posY: data.posY,
|
||||
currentHeading: data.currentHeading,
|
||||
tail: data.tail.serialData()
|
||||
};
|
||||
}
|
||||
//Read-only Properties.
|
||||
defineAccessorProperties(this, data, "currentHeading", "dead", "name", "num", "posX", "posY", "tail");
|
||||
Object.defineProperties(this, {
|
||||
|
@ -24,6 +24,17 @@ function verifyRange()
|
||||
}
|
||||
}
|
||||
|
||||
Color.prototype.interpolateToString = function(color, amount)
|
||||
{
|
||||
var rgbThis = hslToRgb(this.hue, this.sat, this.lum);
|
||||
var rgbThat = hslToRgb(color.hue, color.sat, color.lum);
|
||||
var rgb = [];
|
||||
|
||||
for (var i = 0; i < 3; i++)
|
||||
rgb[i] = Math.floor((rgbThat[i] - rgbThis[i]) * amount + rgbThis[i]);
|
||||
return {rgbString: function() {return 'rgb(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ')'}};
|
||||
}
|
||||
|
||||
Color.prototype.deriveLumination = function(amount)
|
||||
{
|
||||
var lum = this.lum + amount;
|
||||
@ -87,6 +98,7 @@ module.exports = Color;
|
||||
},{}],2:[function(require,module,exports){
|
||||
var Player = require("./player.js");
|
||||
var Grid = require("./grid.js");
|
||||
var Color = require("./color.js");
|
||||
|
||||
/**
|
||||
* Provides requestAnimationFrame in a cross browser way.
|
||||
@ -196,6 +208,7 @@ $(function() {
|
||||
var userPortion = 0;
|
||||
var lagPortion = 0;
|
||||
var portionSpeed = 0;
|
||||
var zoom = 1;
|
||||
|
||||
//TODO: current player index
|
||||
var user = players[0];
|
||||
@ -313,10 +326,10 @@ $(function() {
|
||||
|
||||
function centerOnPlayer(player, pos)
|
||||
{
|
||||
var xOff = Math.floor(player.posX - (gameWidth - CELL_WIDTH) / 2);
|
||||
var yOff = Math.floor(player.posY - (gameHeight - CELL_WIDTH) / 2);
|
||||
pos[0] = Math.max(Math.min(xOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - gameWidth), 0);
|
||||
pos[1] = Math.max(Math.min(yOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - gameHeight), 0);
|
||||
var xOff = Math.floor(player.posX - (gameWidth / zoom - CELL_WIDTH) / 2);
|
||||
var yOff = Math.floor(player.posY - (gameHeight / zoom - CELL_WIDTH) / 2);
|
||||
pos[0] = Math.max(Math.min(xOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - gameWidth / zoom), 0);
|
||||
pos[1] = Math.max(Math.min(yOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - gameHeight / zoom), 0);
|
||||
}
|
||||
|
||||
function area(player)
|
||||
@ -392,10 +405,13 @@ $(function() {
|
||||
//paintGridLines();
|
||||
|
||||
//Get viewing limits
|
||||
var minRow = Math.max(Math.floor((offset[1] - BORDER_WIDTH) / CELL_WIDTH), 0);
|
||||
var minCol = Math.max(Math.floor((offset[0] - BORDER_WIDTH) / CELL_WIDTH), 0);
|
||||
var maxRow = Math.min(Math.ceil((offset[1] + gameHeight) / CELL_WIDTH), grid.size);
|
||||
var maxCol = Math.min(Math.ceil((offset[0] + gameWidth) / CELL_WIDTH), grid.size);
|
||||
var offsetX = (offset[0] - BORDER_WIDTH);
|
||||
var offsetY = (offset[1] - BORDER_WIDTH);
|
||||
|
||||
var minRow = Math.max(Math.floor(offsetY / CELL_WIDTH), 0);
|
||||
var minCol = Math.max(Math.floor(offsetX / CELL_WIDTH), 0);
|
||||
var maxRow = Math.min(Math.ceil((offsetY + gameHeight / zoom) / CELL_WIDTH), grid.size);
|
||||
var maxCol = Math.min(Math.ceil((offsetX + gameWidth / zoom) / CELL_WIDTH), grid.size);
|
||||
|
||||
//Paint occupied areas. (and fading ones).
|
||||
for (var r = minRow; r < maxRow; r++)
|
||||
@ -406,13 +422,16 @@ $(function() {
|
||||
var x = c * CELL_WIDTH, y = r * CELL_WIDTH, baseColor, shadowColor;
|
||||
|
||||
var animateSpec = animateGrid.get(r, c);
|
||||
var adjust = 1;
|
||||
if (!animateOff && animateSpec)
|
||||
{
|
||||
if (animateSpec.before) //fading animation
|
||||
{
|
||||
var alpha = 1 - (animateSpec.frame / ANIMATE_FRAMES);
|
||||
baseColor = animateSpec.before.baseColor.deriveAlpha(alpha);
|
||||
shadowColor = animateSpec.before.shadowColor.deriveAlpha(alpha);
|
||||
var frac = (animateSpec.frame / ANIMATE_FRAMES);
|
||||
var back = new Color(.58, .41, .92, 1);
|
||||
baseColor = animateSpec.before.baseColor.interpolateToString(back, frac);
|
||||
shadowColor = animateSpec.before.shadowColor.interpolateToString(back, frac);
|
||||
adjust = 0;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
@ -430,11 +449,12 @@ $(function() {
|
||||
var bottomEmpty = !bottomAnimate || (bottomAnimate.after && bottomAnimate.before);
|
||||
if (hasBottom && ((!!bottomAnimate ^ !!animateSpec) || bottomEmpty))
|
||||
{
|
||||
|
||||
ctx.fillStyle = shadowColor.rgbString();
|
||||
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH, SHADOW_OFFSET);
|
||||
ctx.fillRect(x, y + CELL_WIDTH + 1, CELL_WIDTH + 1, SHADOW_OFFSET);
|
||||
}
|
||||
ctx.fillStyle = baseColor.rgbString();
|
||||
ctx.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
|
||||
ctx.fillRect(x, y, CELL_WIDTH + 1, CELL_WIDTH + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -462,9 +482,9 @@ $(function() {
|
||||
baseColor = animateSpec.after.baseColor.deriveLumination(-(offsetBounce / DROP_HEIGHT) * .1);
|
||||
|
||||
ctx.fillStyle = shadowColor.rgbString();
|
||||
ctx.fillRect(x, y + SHADOW_OFFSET, CELL_WIDTH, CELL_WIDTH);
|
||||
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH, SHADOW_OFFSET);
|
||||
ctx.fillStyle = baseColor.rgbString();
|
||||
ctx.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
|
||||
ctx.fillRect(x, y, CELL_WIDTH + 1, CELL_WIDTH + 1);
|
||||
}
|
||||
|
||||
animateSpec.frame++;
|
||||
@ -507,12 +527,17 @@ $(function() {
|
||||
ctx.fillStyle = 'whitesmoke';
|
||||
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
||||
|
||||
//Draw the grid items.
|
||||
//Move grid to viewport as said with the offsets, below the stats
|
||||
ctx.save();
|
||||
ctx.translate(0, BAR_HEIGHT);
|
||||
ctx.beginPath();
|
||||
ctx.translate(-offset[0] + BORDER_WIDTH, -offset[1] + BORDER_WIDTH + BAR_HEIGHT);
|
||||
ctx.rect(offset[0] - BORDER_WIDTH, offset[1] - BORDER_WIDTH, canvasWidth, canvasHeight);
|
||||
ctx.rect(0, 0, gameWidth, gameHeight);
|
||||
ctx.clip();
|
||||
|
||||
//Zoom in/out based on player stats.
|
||||
ctx.scale(zoom, zoom);
|
||||
ctx.translate(-offset[0] + BORDER_WIDTH, -offset[1] + BORDER_WIDTH);
|
||||
|
||||
paintGrid();
|
||||
players.forEach(function (p) {
|
||||
var fr = newPlayerFrames[p.num] || 0;
|
||||
@ -522,8 +547,6 @@ $(function() {
|
||||
p.render(ctx);
|
||||
});
|
||||
|
||||
|
||||
|
||||
//Reset transform to paint fixed UI elements
|
||||
ctx.restore();
|
||||
|
||||
@ -537,6 +560,8 @@ $(function() {
|
||||
barOffset = ctx.measureText(user.name).width + 10;
|
||||
ctx.fillText(user.name, 5, CELL_WIDTH - 5);
|
||||
|
||||
zoom = .0014 / lagPortion;
|
||||
|
||||
//Draw filled bar.
|
||||
ctx.fillStyle = "rgba(180, 180, 180, .3)";
|
||||
ctx.fillRect(barOffset, 0, BAR_WIDTH, BAR_HEIGHT);
|
||||
@ -591,7 +616,7 @@ $(function() {
|
||||
});
|
||||
});
|
||||
|
||||
},{"./grid.js":3,"./player.js":4}],3:[function(require,module,exports){
|
||||
},{"./color.js":1,"./grid.js":3,"./player.js":4}],3:[function(require,module,exports){
|
||||
function Grid(size, changeCallback)
|
||||
{
|
||||
var grid = new Array(size);
|
||||
@ -1027,7 +1052,16 @@ function Player(isClient, grid, sdata) {
|
||||
//Instance methods.
|
||||
this.move = move.bind(this, data);
|
||||
this.die = function() {data.dead = true;};
|
||||
|
||||
this.serialData = function() {
|
||||
return {
|
||||
num: data.num,
|
||||
name: data.name,
|
||||
posX: data.posX,
|
||||
posY: data.posY,
|
||||
currentHeading: data.currentHeading,
|
||||
tail: data.tail.serialData()
|
||||
};
|
||||
}
|
||||
//Read-only Properties.
|
||||
defineAccessorProperties(this, data, "currentHeading", "dead", "name", "num", "posX", "posY", "tail");
|
||||
Object.defineProperties(this, {
|
||||
|
@ -11,6 +11,15 @@
|
||||
overflow: hidden;
|
||||
background: black;
|
||||
}
|
||||
|
||||
canvas {
|
||||
image-rendering: optimizeSpeed; /* Older versions of FF */
|
||||
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
|
||||
image-rendering: -webkit-optimize-contrast; /* Safari */
|
||||
image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */
|
||||
image-rendering: pixelated; /* Awesome future-browsers */
|
||||
-ms-interpolation-mode: nearest-neighbor; /* IE */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
Loading…
Reference in New Issue
Block a user