Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
317570fe9d | ||
|
7ff47d8efc | ||
|
8d50dc1d54 | ||
|
075b55d5ec |
@@ -1,6 +1,6 @@
|
|||||||
# Blockly.IO
|
# Blockly.IO
|
||||||
|
|
||||||
This is a clone of the original Paper-IO released by Voodoo, except for one aspect. This will attempt to implement a multi-player aspect of the game (like a real IO game). Currently this has a playground at this [link] (https://thekidofarcrania.github.io/PaperIO-Web). It's a demo version of what to come. Hopefully by that time, the necessary server infrastructure could be obtained.
|
This is a clone of the original Paper-IO released by Voodoo, except for one aspect. This will attempt to implement a multi-player aspect of the game (like a real IO game). Currently this has a playground at this [link](https://thekidofarcrania.github.io/BlocklyIO). It's a demo version of what to come. Hopefully by that time, the necessary server infrastructure could be obtained.
|
||||||
|
|
||||||
This is just a fun side-project for me. If you would want to use this code, it would be nice to let me know.
|
This is just a fun side-project for me. If you would want to use this code, it would be nice to let me know.
|
||||||
|
|
||||||
|
2
compile
2
compile
@@ -1,2 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
browserify game-client.js | uglifyjs -c > public/bundle.min.js
|
|
@@ -1,5 +1,6 @@
|
|||||||
/* global $ */
|
/* global $ */
|
||||||
var Player = require("./player.js");
|
var Player = require("./player.js");
|
||||||
|
var client = require("./player-client.js");
|
||||||
var renderer = require("./game-renderer.js");
|
var renderer = require("./game-renderer.js");
|
||||||
var consts = require("./game-consts.js");
|
var consts = require("./game-consts.js");
|
||||||
var core = require("./game-core.js");
|
var core = require("./game-core.js");
|
||||||
@@ -29,23 +30,8 @@ if ( !window.requestAnimationFrame ) {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
var norun = false;
|
|
||||||
function run() {
|
function run() {
|
||||||
if (norun)
|
client.connect(function(success, msg) {
|
||||||
return; //Prevent multiple clicks.
|
|
||||||
norun = true;
|
|
||||||
|
|
||||||
user = null;
|
|
||||||
deadFrames = 0;
|
|
||||||
|
|
||||||
//Socket connection.
|
|
||||||
//, {transports: ['websocket'], upgrade: false}
|
|
||||||
connectServer();
|
|
||||||
socket.emit('hello', {
|
|
||||||
name: $("#name").val(),
|
|
||||||
type: 0, //Free-for-all
|
|
||||||
gameid: -1 //Requested game-id, or -1 for anyone.
|
|
||||||
}, function(success, msg) {
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
console.info("Connected to game!");
|
console.info("Connected to game!");
|
||||||
@@ -109,47 +95,6 @@ $(function() {
|
|||||||
var user, socket, frame;
|
var user, socket, frame;
|
||||||
|
|
||||||
//Event listeners
|
//Event listeners
|
||||||
//Used from http://stackoverflow.com/a/23230280/7344257
|
|
||||||
document.addEventListener('touchstart', handleTouchStart, false);
|
|
||||||
document.addEventListener('touchmove', handleTouchMove, false);
|
|
||||||
|
|
||||||
var xDown = null;
|
|
||||||
var yDown = null;
|
|
||||||
|
|
||||||
function handleTouchStart(evt) {
|
|
||||||
xDown = evt.touches[0].clientX;
|
|
||||||
yDown = evt.touches[0].clientY;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTouchMove(evt) {
|
|
||||||
if ( xDown === null || yDown === null )
|
|
||||||
return;
|
|
||||||
|
|
||||||
var xUp = evt.touches[0].clientX;
|
|
||||||
var yUp = evt.touches[0].clientY;
|
|
||||||
|
|
||||||
var xDiff = xDown - xUp;
|
|
||||||
var yDiff = yDown - yUp;
|
|
||||||
|
|
||||||
//Set new heading.
|
|
||||||
var newHeading;
|
|
||||||
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) /*most significant*/
|
|
||||||
{
|
|
||||||
if ( xDiff > 0 ) newHeading = 3; /* left swipe */
|
|
||||||
else newHeading = 1; /* right swipe */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( yDiff > 0 ) newHeading = 0; /* up swipe */
|
|
||||||
else newHeading = 2; /* down swipe */
|
|
||||||
}
|
|
||||||
setHeading(newHeading);
|
|
||||||
|
|
||||||
/* reset values */
|
|
||||||
xDown = null;
|
|
||||||
yDown = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document).keydown(function(e) {
|
$(document).keydown(function(e) {
|
||||||
if (!user || user.dead)
|
if (!user || user.dead)
|
||||||
return;
|
return;
|
||||||
@@ -162,12 +107,7 @@ $(document).keydown(function(e) {
|
|||||||
case 40: newHeading = 2; break; //DOWN
|
case 40: newHeading = 2; break; //DOWN
|
||||||
default: return; //exit handler for other keys.
|
default: return; //exit handler for other keys.
|
||||||
}
|
}
|
||||||
setHeading(newHeading);
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
function setHeading(newHeading)
|
|
||||||
{
|
|
||||||
if (newHeading === user.currentHeading || ((newHeading % 2 === 0) ^
|
if (newHeading === user.currentHeading || ((newHeading % 2 === 0) ^
|
||||||
(user.currentHeading % 2 === 0)))
|
(user.currentHeading % 2 === 0)))
|
||||||
{
|
{
|
||||||
@@ -181,7 +121,10 @@ function setHeading(newHeading)
|
|||||||
console.error(msg);
|
console.error(msg);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var grid = renderer.grid;
|
var grid = renderer.grid;
|
||||||
var timeout = undefined;
|
var timeout = undefined;
|
||||||
@@ -190,7 +133,6 @@ var deadFrames = 0;
|
|||||||
var requesting = -1; //frame that we are requesting at.
|
var requesting = -1; //frame that we are requesting at.
|
||||||
var frameCache = []; //Frames after our request.
|
var frameCache = []; //Frames after our request.
|
||||||
|
|
||||||
//TODO: check if we can connect to server.
|
|
||||||
function connectServer() {
|
function connectServer() {
|
||||||
io.j = [];
|
io.j = [];
|
||||||
io.sockets = [];
|
io.sockets = [];
|
||||||
@@ -258,15 +200,14 @@ function connectServer() {
|
|||||||
dirty = true;
|
dirty = true;
|
||||||
paintLoop();
|
paintLoop();
|
||||||
|
|
||||||
showStats();
|
|
||||||
//TODO: Show score stats.
|
//TODO: Show score stats.
|
||||||
//Show score stats.
|
//Show score stats.
|
||||||
// $("#stats").removeClass("hidden");
|
$("#stats").removeClass("hidden");
|
||||||
// $("#stats").animate({
|
$("#stats").animate({
|
||||||
// opacity: .9999
|
opacity: .9999
|
||||||
// }, 3000, function() {
|
}, 3000, function() {
|
||||||
|
showStats();
|
||||||
// });
|
});
|
||||||
|
|
||||||
//Then fade back into the login screen.
|
//Then fade back into the login screen.
|
||||||
|
|
||||||
@@ -274,8 +215,6 @@ function connectServer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showStats() {
|
function showStats() {
|
||||||
var stats =
|
|
||||||
|
|
||||||
$("#begin").removeClass("hidden");
|
$("#begin").removeClass("hidden");
|
||||||
$("#begin").animate({
|
$("#begin").animate({
|
||||||
opacity: .9999
|
opacity: .9999
|
||||||
|
104
game-renderer.js
104
game-renderer.js
@@ -19,25 +19,22 @@ var BAR_HEIGHT = SHADOW_OFFSET + CELL_WIDTH;
|
|||||||
var BAR_WIDTH = 400;
|
var BAR_WIDTH = 400;
|
||||||
|
|
||||||
|
|
||||||
var canvasWidth, canvasHeight, gameWidth, gameHeight, ctx, offctx, offscreenCanvas, initZoom;
|
var canvas, canvasWidth, canvasHeight, gameWidth, gameHeight, ctx, offctx, offscreenCanvas;
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
var canvas = $("#main-ui")[0];
|
canvas = $("#main-ui")[0];
|
||||||
ctx = canvas.getContext('2d');
|
ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
offscreenCanvas = document.createElement("canvas");
|
offscreenCanvas = document.createElement("canvas");
|
||||||
offctx = offscreenCanvas.getContext('2d');
|
offctx = offscreenCanvas.getContext('2d');
|
||||||
|
|
||||||
canvasWidth = offscreenCanvas.width = canvas.width = window.innerWidth;
|
canvas.style.marginTop = 10;
|
||||||
canvasHeight = offscreenCanvas.height = canvas.height = window.innerHeight - 20;
|
updateSize();
|
||||||
zoom = initZoom = (canvasWidth / 1280);
|
|
||||||
canvas.style.marginTop = 20 / 2;
|
|
||||||
|
|
||||||
gameWidth = canvasWidth;
|
|
||||||
gameHeight = canvasHeight - BAR_HEIGHT;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var allowAnimation = true;
|
var allowAnimation = true;
|
||||||
var animateGrid, players, allPlayers, playerPortion, portionsRolling,
|
var animateGrid, players, allPlayers, playerPortion, portionsRolling,
|
||||||
barProportionRolling, grid, animateTo, offset, user, zoom, kills, showedDead;
|
barProportionRolling, grid, animateTo, offset, user, zoom, kills, showedDead;
|
||||||
@@ -59,6 +56,26 @@ grid = new Grid(GRID_SIZE, function(row, col, before, after) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateSize()
|
||||||
|
{
|
||||||
|
var changed = false;
|
||||||
|
if (canvasWidth != window.innerWidth)
|
||||||
|
{
|
||||||
|
gameWidth = canvasWidth = offscreenCanvas.width = canvas.width = window.innerWidth;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canvasHeight != window.innerHeight - 20)
|
||||||
|
{
|
||||||
|
canvasHeight = offscreenCanvas.height = canvas.height = window.innerHeight - 20;
|
||||||
|
gameHeight = canvasHeight - BAR_HEIGHT;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed && user)
|
||||||
|
centerOnPlayer(user, offset);
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
animateGrid = new Grid(GRID_SIZE);
|
animateGrid = new Grid(GRID_SIZE);
|
||||||
grid.reset();
|
grid.reset();
|
||||||
@@ -95,7 +112,7 @@ function paintGridBorder(ctx)
|
|||||||
function paintGrid(ctx)
|
function paintGrid(ctx)
|
||||||
{
|
{
|
||||||
//Paint background.
|
//Paint background.
|
||||||
ctx.fillStyle = "#e2ebf3";
|
ctx.fillStyle = "rgb(211, 225, 237)";
|
||||||
ctx.fillRect(0, 0, CELL_WIDTH * GRID_SIZE, CELL_WIDTH * GRID_SIZE);
|
ctx.fillRect(0, 0, CELL_WIDTH * GRID_SIZE, CELL_WIDTH * GRID_SIZE);
|
||||||
|
|
||||||
paintGridBorder(ctx);
|
paintGridBorder(ctx);
|
||||||
@@ -125,7 +142,7 @@ function paintGrid(ctx)
|
|||||||
{
|
{
|
||||||
var frac = (animateSpec.frame / ANIMATE_FRAMES);
|
var frac = (animateSpec.frame / ANIMATE_FRAMES);
|
||||||
var back = new Color(.58, .41, .92, 1);
|
var back = new Color(.58, .41, .92, 1);
|
||||||
baseColor = animateSpec.before.baseColor.interpolateToString(back, frac);
|
baseColor = animateSpec.before.lightBaseColor.interpolateToString(back, frac);
|
||||||
shadowColor = animateSpec.before.shadowColor.interpolateToString(back, frac);
|
shadowColor = animateSpec.before.shadowColor.interpolateToString(back, frac);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -133,7 +150,7 @@ function paintGrid(ctx)
|
|||||||
}
|
}
|
||||||
else if (p)
|
else if (p)
|
||||||
{
|
{
|
||||||
baseColor = p.baseColor;
|
baseColor = p.lightBaseColor;
|
||||||
shadowColor = p.shadowColor;
|
shadowColor = p.shadowColor;
|
||||||
}
|
}
|
||||||
else //No animation nor is this player owned.
|
else //No animation nor is this player owned.
|
||||||
@@ -148,10 +165,10 @@ function paintGrid(ctx)
|
|||||||
{
|
{
|
||||||
|
|
||||||
ctx.fillStyle = shadowColor.rgbString();
|
ctx.fillStyle = shadowColor.rgbString();
|
||||||
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH + 1 / zoom, SHADOW_OFFSET);
|
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH + 1, SHADOW_OFFSET);
|
||||||
}
|
}
|
||||||
ctx.fillStyle = baseColor.rgbString();
|
ctx.fillStyle = baseColor.rgbString();
|
||||||
ctx.fillRect(x, y, CELL_WIDTH + 1 / zoom, CELL_WIDTH + 1 / zoom);
|
ctx.fillRect(x, y, CELL_WIDTH + 1, CELL_WIDTH + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,12 +193,12 @@ function paintGrid(ctx)
|
|||||||
y -= offsetBounce;
|
y -= offsetBounce;
|
||||||
|
|
||||||
shadowColor = animateSpec.after.shadowColor;
|
shadowColor = animateSpec.after.shadowColor;
|
||||||
baseColor = animateSpec.after.baseColor.deriveLumination(-(offsetBounce / DROP_HEIGHT) * .1);
|
baseColor = animateSpec.after.lightBaseColor.deriveLumination(-(offsetBounce / DROP_HEIGHT) * .1);
|
||||||
|
|
||||||
ctx.fillStyle = shadowColor.rgbString();
|
ctx.fillStyle = shadowColor.rgbString();
|
||||||
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH, SHADOW_OFFSET);
|
ctx.fillRect(x, y + CELL_WIDTH, CELL_WIDTH, SHADOW_OFFSET);
|
||||||
ctx.fillStyle = baseColor.rgbString();
|
ctx.fillStyle = baseColor.rgbString();
|
||||||
ctx.fillRect(x, y, CELL_WIDTH + 1 / zoom, CELL_WIDTH + 1 / zoom);
|
ctx.fillRect(x, y, CELL_WIDTH + 1, CELL_WIDTH + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
animateSpec.frame++;
|
animateSpec.frame++;
|
||||||
@@ -192,46 +209,40 @@ function paintGrid(ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: mobile-friendly UI bar and mobile-friendly ranks
|
|
||||||
function paintUIBar(ctx)
|
function paintUIBar(ctx)
|
||||||
{
|
{
|
||||||
var Z_CELL_WIDTH = CELL_WIDTH * initZoom;
|
|
||||||
var Z_BAR_HEIGHT = BAR_HEIGHT * initZoom;
|
|
||||||
var L_PADDING = 20 * initZoom;
|
|
||||||
var PADDING = 10 * initZoom;
|
|
||||||
var S_PADDING = 5 * initZoom;
|
|
||||||
|
|
||||||
//UI Bar background
|
//UI Bar background
|
||||||
ctx.fillStyle = "#24422c";
|
ctx.fillStyle = "#24422c";
|
||||||
ctx.fillRect(0, 0, canvasWidth, Z_BAR_HEIGHT);
|
ctx.fillRect(0, 0, canvasWidth, BAR_HEIGHT);
|
||||||
|
|
||||||
var barOffset;
|
var barOffset;
|
||||||
ctx.fillStyle = "white";
|
ctx.fillStyle = "white";
|
||||||
ctx.font = "24px Changa";
|
ctx.font = "24px Changa";
|
||||||
barOffset = (user && user.name) ? (ctx.measureText(user.name).width + L_PADDING) : 0;
|
barOffset = (user && user.name) ? (ctx.measureText(user.name).width + 20) : 0;
|
||||||
ctx.fillText(user ? user.name : "", S_PADDING, Z_CELL_WIDTH - S_PADDING);
|
ctx.fillText(user ? user.name : "", 5, CELL_WIDTH - 5);
|
||||||
|
|
||||||
//Draw filled bar.
|
//Draw filled bar.
|
||||||
ctx.fillStyle = "rgba(180, 180, 180, .3)";
|
ctx.fillStyle = "rgba(180, 180, 180, .3)";
|
||||||
ctx.fillRect(barOffset, 0, BAR_WIDTH * initZoom, Z_BAR_HEIGHT);
|
ctx.fillRect(barOffset, 0, BAR_WIDTH, BAR_HEIGHT);
|
||||||
|
|
||||||
var userPortions = portionsRolling[user.num] ? portionsRolling[user.num].lag : 0;
|
var userPortions = portionsRolling[user.num] ? portionsRolling[user.num].lag : 0;
|
||||||
var barSize = Math.ceil(((BAR_WIDTH - MIN_BAR_WIDTH) * userPortions + MIN_BAR_WIDTH) * initZoom);
|
var barSize = Math.ceil((BAR_WIDTH - MIN_BAR_WIDTH) * userPortions + MIN_BAR_WIDTH);
|
||||||
ctx.fillStyle = user ? user.baseColor.rgbString() : "";
|
ctx.fillStyle = user ? user.baseColor.rgbString() : "";
|
||||||
ctx.fillRect(barOffset, 0, barSize, Z_CELL_WIDTH);
|
ctx.fillRect(barOffset, 0, barSize, CELL_WIDTH);
|
||||||
ctx.fillStyle = user ? user.shadowColor.rgbString() : "";
|
ctx.fillStyle = user ? user.shadowColor.rgbString() : "";
|
||||||
ctx.fillRect(barOffset, Z_CELL_WIDTH, barSize, SHADOW_OFFSET * initZoom);
|
ctx.fillRect(barOffset, CELL_WIDTH, barSize, SHADOW_OFFSET);
|
||||||
|
|
||||||
//TODO: dont reset kill count and zoom when we request frames.
|
//TODO: dont reset kill count and zoom when we request frames.
|
||||||
//Percentage
|
//Percentage
|
||||||
ctx.fillStyle = "white";
|
ctx.fillStyle = "white";
|
||||||
ctx.font = "18px Changa";
|
ctx.font = "18px Changa";
|
||||||
ctx.fillText((userPortions * 100).toFixed(3) + "%", S_PADDING + barOffset, Z_CELL_WIDTH - S_PADDING);
|
ctx.fillText((userPortions * 100).toFixed(3) + "%", 5 + barOffset, CELL_WIDTH - 5);
|
||||||
|
|
||||||
//Number of kills
|
//Number of kills
|
||||||
var killsText = "Kills: " + kills;
|
var killsText = "Kills: " + kills;
|
||||||
var killsOffset = L_PADDING + BAR_WIDTH + barOffset;
|
var killsOffset = 20 + BAR_WIDTH + barOffset;
|
||||||
ctx.fillText(killsText, killsOffset, Z_CELL_WIDTH - S_PADDING);
|
ctx.fillText(killsText, killsOffset, CELL_WIDTH - 5);
|
||||||
|
|
||||||
//Calcuate rank
|
//Calcuate rank
|
||||||
var sorted = [];
|
var sorted = [];
|
||||||
@@ -245,7 +256,7 @@ function paintUIBar(ctx)
|
|||||||
|
|
||||||
var rank = sorted.findIndex(function(val) {return val.player === user});
|
var rank = sorted.findIndex(function(val) {return val.player === user});
|
||||||
ctx.fillText("Rank: " + (rank === -1 ? "--" : rank + 1) + " of " + sorted.length,
|
ctx.fillText("Rank: " + (rank === -1 ? "--" : rank + 1) + " of " + sorted.length,
|
||||||
ctx.measureText(killsText).width + killsOffset + L_PADDING, Z_CELL_WIDTH - S_PADDING);
|
ctx.measureText(killsText).width + killsOffset + 20, CELL_WIDTH - 5);
|
||||||
|
|
||||||
//Rolling the leaderboard bars.
|
//Rolling the leaderboard bars.
|
||||||
if (sorted.length > 0)
|
if (sorted.length > 0)
|
||||||
@@ -268,31 +279,31 @@ function paintUIBar(ctx)
|
|||||||
var portion = barProportionRolling[player.num].lag;
|
var portion = barProportionRolling[player.num].lag;
|
||||||
|
|
||||||
var nameWidth = ctx.measureText(name).width;
|
var nameWidth = ctx.measureText(name).width;
|
||||||
barSize = Math.ceil(((BAR_WIDTH - MIN_BAR_WIDTH) * portion + MIN_BAR_WIDTH) * initZoom);
|
barSize = Math.ceil((BAR_WIDTH - MIN_BAR_WIDTH) * portion + MIN_BAR_WIDTH);
|
||||||
var barX = canvasWidth - barSize;
|
var barX = canvasWidth - barSize;
|
||||||
var barY = Z_BAR_HEIGHT * (i + 1) * initZoom;
|
var barY = BAR_HEIGHT * (i + 1);
|
||||||
var offset = i == 0 ? PADDING : 0;
|
var offset = i == 0 ? 10 : 0;
|
||||||
|
|
||||||
ctx.fillStyle = 'rgba(10, 10, 10, .3)';
|
ctx.fillStyle = 'rgba(10, 10, 10, .3)';
|
||||||
ctx.fillRect(barX - PADDING, barY + PADDING - offset, barSize + PADDING, Z_BAR_HEIGHT + offset);
|
ctx.fillRect(barX - 10, barY + 10 - offset, barSize + 10, BAR_HEIGHT + offset);
|
||||||
ctx.fillStyle = player.baseColor.rgbString();
|
ctx.fillStyle = player.baseColor.rgbString();
|
||||||
ctx.fillRect(barX, barY, barSize, CELL_WIDTH * initZoom);
|
ctx.fillRect(barX, barY, barSize, CELL_WIDTH);
|
||||||
ctx.fillStyle = player.shadowColor.rgbString();
|
ctx.fillStyle = player.shadowColor.rgbString();
|
||||||
ctx.fillRect(barX, barY + CELL_WIDTH * initZoom, barSize, SHADOW_OFFSET * initZoom);
|
ctx.fillRect(barX, barY + CELL_WIDTH, barSize, SHADOW_OFFSET);
|
||||||
|
|
||||||
ctx.fillStyle = "black";
|
ctx.fillStyle = "black";
|
||||||
ctx.fillText(name, barX - nameWidth - 15 * initZoom, barY + 27 * initZoom);
|
ctx.fillText(name, barX - nameWidth - 15, barY + 27);
|
||||||
|
|
||||||
var percentage = (portionsRolling[player.num].lag * 100).toFixed(3) + "%";
|
var percentage = (portionsRolling[player.num].lag * 100).toFixed(3) + "%";
|
||||||
ctx.fillStyle = "white";
|
ctx.fillStyle = "white";
|
||||||
ctx.fillText(percentage, barX + 5 * initZoom, barY + (CELL_WIDTH - 5) * initZoom);
|
ctx.fillText(percentage, barX + 5, barY + CELL_WIDTH - 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function paint(ctx)
|
function paint(ctx)
|
||||||
{
|
{
|
||||||
ctx.fillStyle = 'whitesmoke';
|
ctx.fillStyle = '#e2ebf3'; //'whitesmoke';
|
||||||
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
||||||
|
|
||||||
//Move grid to viewport as said with the offsets, below the stats
|
//Move grid to viewport as said with the offsets, below the stats
|
||||||
@@ -334,6 +345,7 @@ function paintDoubleBuff()
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
|
updateSize();
|
||||||
|
|
||||||
//Change grid offsets.
|
//Change grid offsets.
|
||||||
for (var i = 0; i <= 1; i++)
|
for (var i = 0; i <= 1; i++)
|
||||||
@@ -362,7 +374,7 @@ function update() {
|
|||||||
|
|
||||||
//Zoom goes from 1 to .5, decreasing as portion goes up. TODO: maybe can modify this?
|
//Zoom goes from 1 to .5, decreasing as portion goes up. TODO: maybe can modify this?
|
||||||
if (portionsRolling[user.num])
|
if (portionsRolling[user.num])
|
||||||
zoom = initZoom / (portionsRolling[user.num].lag + 1);
|
zoom = 1 / (portionsRolling[user.num].lag + 1);
|
||||||
|
|
||||||
var dead = [];
|
var dead = [];
|
||||||
core.updateFrame(grid, players, dead, function addKill(killer, other)
|
core.updateFrame(grid, players, dead, function addKill(killer, other)
|
||||||
@@ -386,8 +398,8 @@ function centerOnPlayer(player, pos)
|
|||||||
var xOff = Math.floor(player.posX - (gameWidth / zoom - CELL_WIDTH) / 2);
|
var xOff = Math.floor(player.posX - (gameWidth / zoom - CELL_WIDTH) / 2);
|
||||||
var yOff = Math.floor(player.posY - (gameHeight / zoom - CELL_WIDTH) / 2);
|
var yOff = Math.floor(player.posY - (gameHeight / zoom - CELL_WIDTH) / 2);
|
||||||
var gridWidth = grid.size * CELL_WIDTH + BORDER_WIDTH * 2;
|
var gridWidth = grid.size * CELL_WIDTH + BORDER_WIDTH * 2;
|
||||||
pos[0] = Math.max(Math.min(xOff, gridWidth + (BAR_WIDTH + 100) / zoom - gameWidth / zoom), 0);
|
pos[0] = xOff; //Math.max(Math.min(xOff, gridWidth + (BAR_WIDTH + 100) / zoom - gameWidth / zoom), 0);
|
||||||
pos[1] = Math.max(Math.min(yOff, gridWidth - gameHeight / zoom), 0);
|
pos[1] = yOff; //Math.max(Math.min(yOff, gridWidth - gameHeight / zoom), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBounceOffset(frame)
|
function getBounceOffset(frame)
|
||||||
|
@@ -23,8 +23,6 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/theKidOfArcrania/Blockly-IO#readme",
|
"homepage": "https://github.com/theKidOfArcrania/Blockly-IO#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"compression": "^1.6.2",
|
|
||||||
"express": "^4.15.0",
|
|
||||||
"finalhandler": "^1.0.0",
|
"finalhandler": "^1.0.0",
|
||||||
"serve-static": "^1.11.2",
|
"serve-static": "^1.11.2",
|
||||||
"socket.io": "^1.7.3",
|
"socket.io": "^1.7.3",
|
||||||
|
244
player-client.js
Normal file
244
player-client.js
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
var Player = require("./player.js");
|
||||||
|
var consts = require("./game-consts.js");
|
||||||
|
var core = require("./game-core.js");
|
||||||
|
var io = require('socket.io-client');
|
||||||
|
|
||||||
|
var GRID_SIZE = consts.GRID_SIZE;
|
||||||
|
var CELL_WIDTH = consts.CELL_WIDTH;
|
||||||
|
|
||||||
|
var running = false;
|
||||||
|
var user, socket, frame;
|
||||||
|
|
||||||
|
exports.connect = function(callback) {
|
||||||
|
if (running)
|
||||||
|
return; //Prevent multiple runs.
|
||||||
|
running = true;
|
||||||
|
|
||||||
|
user = null;
|
||||||
|
deadFrames = 0;
|
||||||
|
|
||||||
|
//Socket connection.
|
||||||
|
//, {transports: ['websocket'], upgrade: false}
|
||||||
|
connectServer();
|
||||||
|
socket.emit('hello', {
|
||||||
|
name: $("#name").val(),
|
||||||
|
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);
|
||||||
|
if (callback)
|
||||||
|
callback(success, msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.changeHeading = function(int newHeading)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var grid = renderer.grid;
|
||||||
|
var timeout = undefined;
|
||||||
|
var dirty = false;
|
||||||
|
var deadFrames = 0;
|
||||||
|
var requesting = -1; //frame that we are requesting at.
|
||||||
|
var frameCache = []; //Frames after our request.
|
||||||
|
|
||||||
|
function connectServer() {
|
||||||
|
io.j = [];
|
||||||
|
io.sockets = [];
|
||||||
|
socket = io('http://' + window.location.hostname + ':8081', {
|
||||||
|
'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;
|
||||||
|
renderer.reset();
|
||||||
|
|
||||||
|
//Load players.
|
||||||
|
data.players.forEach(function(p) {
|
||||||
|
var pl = new Player(grid, p);
|
||||||
|
renderer.addPlayer(pl);
|
||||||
|
});
|
||||||
|
user = renderer.getPlayerFromNum(data.num);
|
||||||
|
if (!user) throw new Error();
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.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;
|
||||||
|
|
||||||
|
//TODO: DISCONNECT event
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
renderer.addPlayer(pl);
|
||||||
|
core.initPlayer(grid, pl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var found = new Array(renderer.playerSize());
|
||||||
|
data.moves.forEach(function(val, i) {
|
||||||
|
var player = renderer.getPlayerFromNum(val.num);
|
||||||
|
if (!player) return;
|
||||||
|
if (val.left) player.die();
|
||||||
|
found[i] = true;
|
||||||
|
player.heading = val.heading;
|
||||||
|
});
|
||||||
|
for (var i = 0; i < renderer.playerSize(); i++)
|
||||||
|
{
|
||||||
|
//Implicitly leaving game.
|
||||||
|
if (!found[i])
|
||||||
|
{
|
||||||
|
var player = renderer.getPlayer();
|
||||||
|
player && player.die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.update();
|
||||||
|
|
||||||
|
var locs = {};
|
||||||
|
for (var i = 0; i < renderer.playerSize(); i++)
|
||||||
|
{
|
||||||
|
var p = renderer.getPlayer(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;
|
||||||
|
requestAnimationFrame(function() {
|
||||||
|
paintLoop();
|
||||||
|
});
|
||||||
|
timeout = setTimeout(function() {
|
||||||
|
console.warn("Server has timed-out. Disconnecting.");
|
||||||
|
socket.disconnect();
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function paintLoop()
|
||||||
|
{
|
||||||
|
if (!dirty)
|
||||||
|
return;
|
||||||
|
renderer.paint();
|
||||||
|
dirty = false;
|
||||||
|
|
||||||
|
if (user.dead)
|
||||||
|
{
|
||||||
|
if (timeout)
|
||||||
|
clearTimeout(timeout);
|
||||||
|
if (deadFrames === 60) //One second of frame
|
||||||
|
{
|
||||||
|
var before = renderer.allowAnimation;
|
||||||
|
renderer.allowAnimation = false;
|
||||||
|
renderer.update();
|
||||||
|
renderer.paint();
|
||||||
|
renderer.allowAnimation = before;
|
||||||
|
user = null;
|
||||||
|
deadFrames = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.disconnect();
|
||||||
|
deadFrames++;
|
||||||
|
dirty = true;
|
||||||
|
renderer.update();
|
||||||
|
requestAnimationFrame(paintLoop);
|
||||||
|
}
|
||||||
|
}
|
@@ -373,8 +373,9 @@ function Player(grid, sdata) {
|
|||||||
var hue = Math.random();
|
var hue = Math.random();
|
||||||
this.baseColor = base = new Color(hue, .8, .5);
|
this.baseColor = base = new Color(hue, .8, .5);
|
||||||
}
|
}
|
||||||
|
this.lightBaseColor = base.deriveLumination(.1);
|
||||||
this.shadowColor = base.deriveLumination(-.3);
|
this.shadowColor = base.deriveLumination(-.3);
|
||||||
this.tailColor = base.deriveLumination(.2).deriveAlpha(.5);
|
this.tailColor = base.deriveLumination(.3).deriveAlpha(.5);
|
||||||
|
|
||||||
//Tail requires special handling.
|
//Tail requires special handling.
|
||||||
this.grid = grid; //Temporary
|
this.grid = grid; //Temporary
|
||||||
|
6967
public/bundle.js
6967
public/bundle.js
File diff suppressed because it is too large
Load Diff
5
public/bundle.min.js
vendored
5
public/bundle.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,40 +1,25 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta name=viewport content="width=device-width, initial-scale=1">
|
|
||||||
<link href="changa.css" rel="stylesheet">
|
<link href="changa.css" rel="stylesheet">
|
||||||
<link href="styles.css" rel="stylesheet">
|
<link href="styles.css" rel="stylesheet">
|
||||||
<script src="jquery.min.js"></script>
|
<script src="jquery.min.js"></script>
|
||||||
<script src="bundle.min.js"></script>
|
<script src="bundle.js"></script>
|
||||||
<title>Blockly.IO</title>
|
<title>Blockly.IO</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="main-ui"></canvas>
|
<canvas id="main-ui"></canvas>
|
||||||
<div id="stats" style="opacity: 0" class="fullscreen hidden">
|
<div id="stats" style="opacity: 0" class="fullscreen hidden"></div>
|
||||||
<div style="padding-top: 100px"></div>
|
|
||||||
<div class="card">
|
|
||||||
<h1 id="score">Score: <span id="score-num">0</span></h1>
|
|
||||||
<h1 id="high-score">High Score: <span id="high-score-num">0</span></h1>
|
|
||||||
<h1 id="time">Time Alive: <span id="time-num">0</span></h1>
|
|
||||||
<h1 id="killed">Killed: <span id="killed-num">0</span></h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="begin" style="opacity: .99999" class="fullscreen">
|
<div id="begin" style="opacity: .99999" class="fullscreen">
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<h1>Blockly.IO!</h1>
|
<h1>Blockly.IO!</h1>
|
||||||
<small>Todo: replace ^^^ with a picture. Work in progress.</small><br>
|
<small>Todo: replace ^^^ with a picture. Work in progress.</small><br>
|
||||||
|
|
||||||
<h1>Enter your name</h1>
|
<h1>Enter your name</h1>
|
||||||
<div>
|
|
||||||
<input autocomplete="off" id="name" placeholder="An awesome name!">
|
<input autocomplete="off" id="name" placeholder="An awesome name!">
|
||||||
</div>
|
|
||||||
<div class="blockless">
|
|
||||||
<button type="submit">Play!</button>
|
<button type="submit">Play!</button>
|
||||||
</div>
|
<div>
|
||||||
<div class="blockless">
|
|
||||||
<small id="error">Your browser does not support JavaScript!</small>
|
<small id="error">Your browser does not support JavaScript!</small>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<small>Visit the open-source code on <a href="https://github.com/theKidOfArcrania/PaperIO-Web">GitHub</a>!</small>
|
||||||
<small>Visit the open-source code on <a href="https://github.com/theKidOfArcrania/PaperIO-Web">GitHub</a>!</small>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
@@ -28,9 +28,10 @@ canvas {
|
|||||||
.center {
|
.center {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 1rem;
|
position: fixed;
|
||||||
margin-top: 0rem;
|
top: 50%;
|
||||||
padding-top: 3rem;
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
@@ -39,7 +40,6 @@ input {
|
|||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
border: 4px solid lightgray;
|
border: 4px solid lightgray;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@@ -51,14 +51,6 @@ button {
|
|||||||
font-family: "Changa", "Sans-serif";
|
font-family: "Changa", "Sans-serif";
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
width: 100%;
|
|
||||||
margin-top: .5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 769px){
|
|
||||||
button, input {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button:active {
|
button:active {
|
||||||
|
29
server.js
29
server.js
@@ -2,17 +2,26 @@
|
|||||||
var hostname = process.argv[2] || "0.0.0.0";
|
var hostname = process.argv[2] || "0.0.0.0";
|
||||||
var port = parseInt(process.argv[3]) || 80;
|
var port = parseInt(process.argv[3]) || 80;
|
||||||
|
|
||||||
var express = require('express');
|
var finalhandler = require('finalhandler');
|
||||||
var compression = require('compression')
|
|
||||||
var app = express();
|
|
||||||
|
|
||||||
//Create static server
|
|
||||||
app.use(compression());
|
|
||||||
app.use(express.static('public'));
|
|
||||||
app.listen(port, hostname);
|
|
||||||
|
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
var server = http.createServer();
|
var serveStatic = require('serve-static');
|
||||||
|
|
||||||
|
// Serve up public/ftp folder
|
||||||
|
var serve = serveStatic('public/', {'setHeaders': setHeaders});
|
||||||
|
|
||||||
|
function setHeaders(res, path) {
|
||||||
|
res.setHeader('Cache-Control', 'public, max-age=0');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create server
|
||||||
|
var server = http.createServer(function onRequest (req, res) {
|
||||||
|
serve(req, res, finalhandler(req, res));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen
|
||||||
|
server.listen(port, hostname);
|
||||||
|
|
||||||
|
server = http.createServer();
|
||||||
var io = require('socket.io')(server);
|
var io = require('socket.io')(server);
|
||||||
io.set('transports', ['websocket']);
|
io.set('transports', ['websocket']);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user