Some UI touches, start experimenting with node.js
This commit is contained in:
parent
8ddee5cabf
commit
8e152bd33c
202
game.js
202
game.js
@ -12,9 +12,9 @@ if (!Grid)
|
||||
* Provides requestAnimationFrame in a cross browser way.
|
||||
* @author paulirish / http://paulirish.com/
|
||||
*/
|
||||
window.requestAnimationFrame = function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
|
||||
window.setTimeout( callback, 1000 / 60 );
|
||||
};
|
||||
// window.requestAnimationFrame = function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
|
||||
// window.setTimeout( callback, 1000 / 60 );
|
||||
// };
|
||||
if ( !window.requestAnimationFrame ) {
|
||||
window.requestAnimationFrame = ( function() {
|
||||
return window.webkitRequestAnimationFrame ||
|
||||
@ -30,24 +30,41 @@ if ( !window.requestAnimationFrame ) {
|
||||
|
||||
$(function() {
|
||||
var BORDER_WIDTH = 20;
|
||||
var GRID_SIZE = 200;
|
||||
var CELL_WIDTH = 30;
|
||||
var GRID_SIZE = 80;
|
||||
var CELL_WIDTH = 40;
|
||||
var SPEED = 5;
|
||||
var SHADOW_OFFSET = 5;
|
||||
var MAX_FRAMES = 16;
|
||||
var DROP_HEIGHT = 16;
|
||||
var BOUNCE_FRAMES = 8;
|
||||
var ANIMATE_FRAMES = 24;
|
||||
var BOUNCE_FRAMES = [8, 4];
|
||||
var DROP_HEIGHT = 24;
|
||||
var DROP_SPEED = 2;
|
||||
var MIN_BAR_WIDTH = 65;
|
||||
var BAR_HEIGHT = SHADOW_OFFSET + CELL_WIDTH;
|
||||
var BAR_WIDTH = 400;
|
||||
var canvas = $("#main-ui")[0];
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
var width = canvas.width = window.innerWidth - 20;
|
||||
var height = canvas.height = window.innerHeight - 20;
|
||||
var canvasWidth = canvas.width = window.innerWidth;
|
||||
var canvasHeight = canvas.height = window.innerHeight - 20;
|
||||
canvas.style.marginTop = 20 / 2;
|
||||
|
||||
var gameWidth = canvasWidth;
|
||||
var gameHeight = canvasHeight - BAR_HEIGHT;
|
||||
|
||||
var newPlayerFrames = [];
|
||||
var playerPortion = [];
|
||||
var allPlayers = [];
|
||||
var players = [];
|
||||
var animateOff = true;
|
||||
var animateOff = false;
|
||||
var animateGrid = new Grid(GRID_SIZE);
|
||||
var grid = new Grid(GRID_SIZE, function(row, col, before, after) {
|
||||
//Keep track of areas.
|
||||
if (before)
|
||||
playerPortion[before.num]--;
|
||||
if (after)
|
||||
playerPortion[after.num]++;
|
||||
|
||||
//Queue animation
|
||||
if (before === after || animateOff)
|
||||
return;
|
||||
animateGrid.set(row, col, {
|
||||
@ -61,7 +78,16 @@ $(function() {
|
||||
for (var p = 0; p < 9; p++)
|
||||
{
|
||||
//TODO: socket loading.
|
||||
players[p] = new Player(null, grid, p, getRandomInt(0, GRID_SIZE), getRandomInt(0, GRID_SIZE));
|
||||
var pRow = getRandomInt(0, GRID_SIZE);
|
||||
var pCol = getRandomInt(0, GRID_SIZE);
|
||||
|
||||
playerPortion[p] = 0;
|
||||
allPlayers[p] = players[p] = new Player(null, grid, p, pRow, pCol);
|
||||
|
||||
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, players[p]);
|
||||
}
|
||||
|
||||
//Load grid.
|
||||
@ -70,8 +96,8 @@ $(function() {
|
||||
for (var c = 0; c < grid.size; c++)
|
||||
{
|
||||
//TODO: load data.
|
||||
if (Math.random() > .9)
|
||||
grid.set(r, c, players[getRandomInt(0, players.length)]);
|
||||
//if (Math.random() > .9)
|
||||
// grid.set(r, c, players[getRandomInt(0, players.length)]);
|
||||
}
|
||||
}
|
||||
animateOff = false;
|
||||
@ -80,8 +106,13 @@ $(function() {
|
||||
var animateTo = [0, 0];
|
||||
var offset = [0, 0];
|
||||
|
||||
var userPortion = 0;
|
||||
var lagPortion = 0;
|
||||
var portionSpeed = 0;
|
||||
|
||||
//TODO: current player index
|
||||
var user = players[0];
|
||||
|
||||
centerOnPlayer(user, offset);
|
||||
|
||||
function update()
|
||||
@ -98,11 +129,26 @@ $(function() {
|
||||
}
|
||||
}
|
||||
|
||||
//Change area percentage
|
||||
if (lagPortion !== userPortion)
|
||||
{
|
||||
delta = userPortion - lagPortion;
|
||||
dir = Math.sign(delta);
|
||||
mag = Math.min(Math.abs(portionSpeed), Math.abs(delta));
|
||||
lagPortion += dir * mag;
|
||||
}
|
||||
|
||||
//Move players.
|
||||
var dead = [];
|
||||
players = players.filter(function(val) {
|
||||
val.move();
|
||||
if (!newPlayerFrames[val.num])
|
||||
newPlayerFrames[val.num] = 0;
|
||||
|
||||
if (newPlayerFrames[val.num] < ANIMATE_FRAMES)
|
||||
newPlayerFrames[val.num]++;
|
||||
else
|
||||
val.move();
|
||||
|
||||
if (val.dead)
|
||||
dead.push(val);
|
||||
return !val.dead;
|
||||
@ -158,6 +204,7 @@ $(function() {
|
||||
|
||||
dead.forEach(function(val) {
|
||||
console.log(val.name + " is dead");
|
||||
allPlayers[val.num] = undefined;
|
||||
});
|
||||
for (var r = 0; r < grid.size; r++)
|
||||
{
|
||||
@ -168,16 +215,21 @@ $(function() {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: animate dead, and if this player is dead.
|
||||
//Update user's portions and top ranks.
|
||||
userPortion = playerPortion[user.num] / (GRID_SIZE * GRID_SIZE);
|
||||
portionSpeed = Math.abs(userPortion - lagPortion) / ANIMATE_FRAMES;
|
||||
|
||||
//TODO: animate player is dead. (maybe explosion?)
|
||||
//TODO: show when this player is dead
|
||||
centerOnPlayer(user, animateTo);
|
||||
}
|
||||
|
||||
function centerOnPlayer(player, pos)
|
||||
{
|
||||
var xOff = Math.floor(player.posX - (width - CELL_WIDTH) / 2);
|
||||
var yOff = Math.floor(player.posY - (height - CELL_WIDTH) / 2);
|
||||
pos[0] = Math.max(Math.min(xOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - width), 0);
|
||||
pos[1] = Math.max(Math.min(yOff, grid.size * CELL_WIDTH + BORDER_WIDTH * 2 - height), 0);
|
||||
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);
|
||||
}
|
||||
|
||||
function area(player)
|
||||
@ -221,15 +273,15 @@ $(function() {
|
||||
{
|
||||
ctx.fillStyle = 'lightgray';
|
||||
ctx.beginPath();
|
||||
for (var x = modRotate(-offset[0], CELL_WIDTH); x < width; x += CELL_WIDTH)
|
||||
for (var x = modRotate(-offset[0], CELL_WIDTH); x < gameWidth; x += CELL_WIDTH)
|
||||
{
|
||||
ctx.moveTo(x, 0);
|
||||
ctx.lineTo(x, height);
|
||||
ctx.lineTo(x, gameHeight);
|
||||
}
|
||||
for (var y = modRotate(-offset[1], CELL_WIDTH); y < height; y+= CELL_WIDTH)
|
||||
for (var y = modRotate(-offset[1], CELL_WIDTH); y < gameHeight; y+= CELL_WIDTH)
|
||||
{
|
||||
ctx.moveTo(0, y);
|
||||
ctx.lineTo(width, y);
|
||||
ctx.lineTo(gameWidth, y);
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
@ -245,7 +297,9 @@ $(function() {
|
||||
|
||||
function paintGrid()
|
||||
{
|
||||
ctx.translate(BORDER_WIDTH, BORDER_WIDTH);
|
||||
//Paint background.
|
||||
ctx.fillStyle = "#e2ebf3";
|
||||
ctx.fillRect(0, 0, CELL_WIDTH * GRID_SIZE, CELL_WIDTH * GRID_SIZE);
|
||||
|
||||
paintGridBorder();
|
||||
//paintGridLines();
|
||||
@ -253,8 +307,8 @@ $(function() {
|
||||
//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] + height) / CELL_WIDTH), grid.size);
|
||||
var maxCol = Math.min(Math.ceil((offset[0] + width) / CELL_WIDTH), grid.size);
|
||||
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);
|
||||
|
||||
//Paint occupied areas. (and fading ones).
|
||||
for (var r = minRow; r < maxRow; r++)
|
||||
@ -269,7 +323,7 @@ $(function() {
|
||||
{
|
||||
if (animateSpec.before) //fading animation
|
||||
{
|
||||
var alpha = 1 - (animateSpec.frame / MAX_FRAMES);
|
||||
var alpha = 1 - (animateSpec.frame / ANIMATE_FRAMES);
|
||||
baseColor = animateSpec.before.baseColor.deriveAlpha(alpha);
|
||||
shadowColor = animateSpec.before.shadowColor.deriveAlpha(alpha);
|
||||
}
|
||||
@ -284,7 +338,10 @@ $(function() {
|
||||
else //No animation nor is this player owned.
|
||||
continue;
|
||||
|
||||
if (!grid.isOutOfBounds(r + 1, c) && !grid.get(r + 1, c) && !animateGrid.get(r + 1, c))
|
||||
var hasBottom = !grid.isOutOfBounds(r + 1, c);
|
||||
var bottomAnimate = hasBottom && animateGrid.get(r + 1, c);
|
||||
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);
|
||||
@ -311,19 +368,7 @@ $(function() {
|
||||
if (animateSpec.after && viewable)
|
||||
{
|
||||
//Bouncing the squares.
|
||||
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;
|
||||
|
||||
var offsetBounce = getBounceOffset(animateSpec.frame);
|
||||
y -= offsetBounce;
|
||||
|
||||
shadowColor = animateSpec.after.shadowColor;
|
||||
@ -336,26 +381,89 @@ $(function() {
|
||||
}
|
||||
|
||||
animateSpec.frame++;
|
||||
if (animateSpec.frame >= MAX_FRAMES)
|
||||
if (animateSpec.frame >= ANIMATE_FRAMES)
|
||||
animateGrid.set(r, c, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getBounceOffset(frame)
|
||||
{
|
||||
var offsetBounce = ANIMATE_FRAMES;
|
||||
var bounceNum = BOUNCE_FRAMES.length - 1;
|
||||
while (bounceNum >= 0 && frame < offsetBounce - BOUNCE_FRAMES[bounceNum])
|
||||
{
|
||||
offsetBounce -= BOUNCE_FRAMES[bounceNum];
|
||||
bounceNum--;
|
||||
}
|
||||
|
||||
if (bounceNum === -1)
|
||||
{
|
||||
return (offsetBounce - frame) * DROP_SPEED;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetBounce -= BOUNCE_FRAMES[bounceNum];
|
||||
frame = frame - offsetBounce;
|
||||
var midFrame = BOUNCE_FRAMES[bounceNum] / 2;
|
||||
if (frame >= midFrame)
|
||||
return (BOUNCE_FRAMES[bounceNum] - frame) * DROP_SPEED;
|
||||
else
|
||||
return frame * DROP_SPEED;
|
||||
}
|
||||
}
|
||||
|
||||
var showedDead = false;
|
||||
function paintLoop()
|
||||
{
|
||||
ctx.fillStyle = 'whitesmoke';
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
||||
|
||||
ctx.translate(-offset[0], -offset[1]);
|
||||
//Draw the grid items.
|
||||
ctx.save();
|
||||
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.clip();
|
||||
paintGrid();
|
||||
players.forEach(function (p) {
|
||||
p.render(ctx);
|
||||
var fr = newPlayerFrames[p.num] || 0;
|
||||
if (fr < ANIMATE_FRAMES)
|
||||
p.render(ctx, fr / ANIMATE_FRAMES);
|
||||
else
|
||||
p.render(ctx);
|
||||
});
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0); //Reset transform.
|
||||
|
||||
|
||||
|
||||
//Reset transform to paint fixed UI elements
|
||||
ctx.restore();
|
||||
|
||||
//UI Bar background
|
||||
ctx.fillStyle = "#24422c";
|
||||
ctx.fillRect(0, 0, canvasWidth, BAR_HEIGHT);
|
||||
|
||||
var barOffset;
|
||||
ctx.fillStyle = "white";
|
||||
ctx.font = "24px Arial";
|
||||
barOffset = ctx.measureText(user.name).width + 10;
|
||||
ctx.fillText(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.fillRect(barOffset, 0, barSize, CELL_WIDTH);
|
||||
ctx.fillStyle = user.shadowColor.rgbString();
|
||||
ctx.fillRect(barOffset, CELL_WIDTH, barSize, SHADOW_OFFSET);
|
||||
|
||||
//Percentage
|
||||
ctx.fillStyle = "white";
|
||||
ctx.font = "18px Arial";
|
||||
ctx.fillText((lagPortion * 100).toFixed(3) + "%", 5 + barOffset, CELL_WIDTH - 5);
|
||||
|
||||
if (user.dead && !showedDead)
|
||||
{
|
||||
|
23
player.js
23
player.js
@ -7,8 +7,8 @@ if (!Color)
|
||||
throw new Error("Requre color.js");
|
||||
|
||||
var Tail = (function() {
|
||||
var CELL_WIDTH = 30;
|
||||
var GRID_SIZE = 200;
|
||||
var CELL_WIDTH = 40;
|
||||
var GRID_SIZE = 80;
|
||||
|
||||
function TailMove(orientation)
|
||||
{
|
||||
@ -111,7 +111,7 @@ var Tail = (function() {
|
||||
var prevOrient = -1;
|
||||
var start = [data.startRow, data.startCol];
|
||||
|
||||
fillTailRect(ctx, start, start);
|
||||
//fillTailRect(ctx, start, start);
|
||||
data.tail.forEach(function(tail) {
|
||||
var negDir = tail.orientation === 0 || tail.orientation === 3;
|
||||
|
||||
@ -293,14 +293,15 @@ var Tail = (function() {
|
||||
|
||||
function hitsTail(data, other)
|
||||
{
|
||||
return (data.prevRow !== other.row || data.prevCol !== other.col) &&
|
||||
return (data.prevRow !== other.row || data.prevCol !== other.col) &&
|
||||
(data.startRow !== other.row || data.startCol !== other.col) &&
|
||||
!!(data.tailGrid[other.row] && data.tailGrid[other.row][other.col]);
|
||||
}
|
||||
|
||||
return Tail;
|
||||
}());
|
||||
this.Player = (function() {
|
||||
var CELL_WIDTH = 30;
|
||||
var CELL_WIDTH = 40;
|
||||
var SPEED = 5;
|
||||
var SHADOW_OFFSET = 10;
|
||||
|
||||
@ -345,22 +346,28 @@ this.Player = (function() {
|
||||
}
|
||||
|
||||
//Instance methods
|
||||
Player.prototype.render = function(ctx)
|
||||
Player.prototype.render = function(ctx, fade)
|
||||
{
|
||||
//Render tail.
|
||||
this.tail.render(ctx);
|
||||
|
||||
//Render player.
|
||||
ctx.fillStyle = this.shadowColor.rgbString();
|
||||
fade = fade || 1;
|
||||
ctx.fillStyle = this.shadowColor.deriveAlpha(fade).rgbString();
|
||||
ctx.fillRect(this.posX, this.posY, CELL_WIDTH, CELL_WIDTH);
|
||||
|
||||
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());
|
||||
grd.addColorStop(0, this.baseColor.deriveAlpha(fade).rgbString());
|
||||
grd.addColorStop(1, "white");
|
||||
ctx.fillStyle = grd;
|
||||
ctx.fillRect(this.posX, this.posY - SHADOW_OFFSET, CELL_WIDTH, CELL_WIDTH);
|
||||
|
||||
//Render name
|
||||
ctx.fillStyle = this.shadowColor.deriveAlpha(fade).rgbString();
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText(this.name, this.posX + CELL_WIDTH / 2, this.posY - SHADOW_OFFSET * 2);
|
||||
};
|
||||
|
||||
function move(data)
|
||||
|
5
server.js
Normal file
5
server.js
Normal file
@ -0,0 +1,5 @@
|
||||
io.on('connection', function(socket){
|
||||
socket.emit('request', /* */); // emit an event to the socket
|
||||
io.emit('broadcast', /* */); // emit an event to all connected sockets
|
||||
socket.on('reply', function(){ /* */ }); // listen to the event
|
||||
});
|
28
test.html
28
test.html
@ -1,7 +1,21 @@
|
||||
<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="player.js"></script>
|
||||
<script src="game.js"></script>
|
||||
<canvas id="main-ui"></canvas>
|
||||
<head>
|
||||
<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="player.js"></script>
|
||||
<script src="game.js"></script>
|
||||
<style>
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="main-ui"></canvas>
|
||||
</body>
|
Loading…
Reference in New Issue
Block a user