optimize canvas style

This commit is contained in:
StevenJoeZhang 2019-02-22 15:10:20 +08:00
parent afa909f9e2
commit 33f6dbd00e
7 changed files with 65 additions and 111 deletions

4
bot.js
View File

@ -97,8 +97,8 @@ function foundProto(func) {
function connect() {
var prefixes = consts.PREFIXES.split(" ");
var names = consts.NAMES.split(" ");
var name = process.argv[3] || ["[BOT]", prefixes[Math.floor(Math.random() * prefixes.length)], names[Math.floor(Math.random() * names.length)]].join(" ");
client.connectGame(process.argv[2], name, function(success, msg) {
var name = process.argv[3] || [prefixes[Math.floor(Math.random() * prefixes.length)], names[Math.floor(Math.random() * names.length)]].join(" ");
client.connectGame(process.argv[2], "[BOT] " + name, function(success, msg) {
if (!success) {
console.error(msg);
setTimeout(connect, 1000);

View File

@ -22,8 +22,8 @@ function mod(x) {
function connect() {
var prefixes = consts.PREFIXES.split(" ");
var names = consts.NAMES.split(" ");
var name = process.argv[3] || ["[BOT]", prefixes[Math.floor(Math.random() * prefixes.length)], names[Math.floor(Math.random() * names.length)]].join(" ");
client.connectGame(process.argv[2], name, function(success, msg) {
var name = process.argv[3] || [prefixes[Math.floor(Math.random() * prefixes.length)], names[Math.floor(Math.random() * names.length)]].join(" ");
client.connectGame(process.argv[2], "[BOT] " + name, function(success, msg) {
if (!success) {
console.error(msg);
setTimeout(connect, 1000);

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,27 @@ function verifyRange() {
if (arguments[i] < 0 || arguments[i] > 1) throw new RangeError("H, S, L, and A parameters must be between the range [0, 1]");
}
}
//https://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 Color(h, s, l, a) {
verifyRange(h, s, l);
if (a === undefined) a = 1;
@ -65,25 +86,29 @@ Color.prototype.rgbString = function() {
rgb[3] = this.a;
return `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${this.alpha})`;
};
//https://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);
Color.possColors = function() {
var SATS = [192, 150, 100].map(function(val) {
return val / 240;
});
var HUES = [0, 10, 20, 25, 30, 35, 40, 45, 50, 60, 70, 100, 110, 120, 125, 130, 135, 140, 145, 150, 160, 170, 180, 190, 200, 210, 220].map(function(val) {
return val / 240;
});
var possColors = new Array(SATS.length * HUES.length);
i = 0;
for (var s = 0; s < SATS.length; s++) {
for (var h = 0; h < HUES.length; h++) {
possColors[i++] = new Color(HUES[h], SATS[s], .5, 1);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
//Shuffle the colors
for (var i = 0; i < possColors.length * 50; i++) {
var a = Math.floor(Math.random() * possColors.length);
var b = Math.floor(Math.random() * possColors.length);
var tmp = possColors[a];
possColors[a] = possColors[b];
possColors[b] = tmp;
}
return possColors;
}
module.exports = Color;

View File

@ -1,32 +1,8 @@
var core = require("./core");
var consts = require("../config.json").consts;
var SATS = [192, 150, 100].map(function(val) {
return val / 240;
});
var HUES = [0, 10, 20, 25, 30, 35, 40, 45, 50, 60, 70, 100, 110, 120, 125, 130, 135, 140, 145, 150, 160, 170, 180, 190, 200, 210, 220].map(function(val) {
return val / 240;
});
function log(msg) {
console.log(`[${new Date()}] ${msg}`);
}
function Game(id) {
var possColors = new Array(SATS.length * HUES.length);
i = 0;
for (var s = 0; s < SATS.length; s++) {
for (var h = 0; h < HUES.length; h++) {
possColors[i++] = new core.Color(HUES[h], SATS[s], .5, 1);
}
}
//Shuffle the colors
for (var i = 0; i < possColors.length * 50; i++) {
var a = Math.floor(Math.random() * possColors.length);
var b = Math.floor(Math.random() * possColors.length);
var tmp = possColors[a];
possColors[a] = possColors[b];
possColors[b] = tmp;
}
var possColors = core.Color.possColors();
var nextInd = 0;
var players = [];
var gods = [];
@ -38,7 +14,7 @@ function Game(id) {
if (!!after ^ !!before) {
if (after) filled++;
else filled--;
if (filled === consts.GRID_COUNT * consts.GRID_COUNT) log("FULL GAME");
if (filled === consts.GRID_COUNT * consts.GRID_COUNT) console.log(`[${new Date()}] FULL GAME`);
}
});
this.id = id;
@ -61,7 +37,7 @@ function Game(id) {
newPlayers.push(p);
nextInd++;
core.initPlayer(grid, p);
if (p.name.indexOf("BOT") == -1) log((p.name || "Unnamed") + " (" + p.num + ") joined.");
if (p.name.indexOf("[BOT]") == -1) console.log(`[${new Date()}] ${p.name || "Unnamed"} (${p.num}) joined.`);
client.on("requestFrame", function() {
if (p.frame === frame) return;
p.frame = frame; //Limit number of requests per frame (One per frame)
@ -107,7 +83,7 @@ function Game(id) {
client.on("disconnect", function() {
p.die(); //Die immediately if not already
p.disconnected = true;
if (p.name.indexOf("BOT") == -1) log((p.name || "Unnamed") + " (" + p.num + ") left.");
if (p.name.indexOf("[BOT]") == -1) console.log(`[${new Date()}] ${p.name || "Unnamed"} (${p.num}) left.`);
});
return true;
};
@ -230,7 +206,7 @@ function Game(id) {
possColors.push(p.baseColor);
p.handledDead = true;
}
if (p.name.indexOf("BOT") == -1) log((p.name || "Unnamed") + " (" + p.num + ") died.");
if (p.name.indexOf("[BOT]") == -1) console.log(`${p.name || "Unnamed"} (${p.num}) died.`);
p.client.emit("dead");
p.client.disconnect(true);
}

View File

@ -21,7 +21,6 @@ $(function() {
ctx = canvas.getContext("2d");
offscreenCanvas = document.createElement("canvas");
offctx = offscreenCanvas.getContext("2d");
canvas.style.marginTop = 10;
updateSize();
});
@ -34,9 +33,8 @@ function updateSize() {
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;
if (canvasHeight != window.innerHeight) {
gameHeight = canvasHeight = offscreenCanvas.height = canvas.height = window.innerHeight;
changed = true;
}
if (changed && user) centerOnPlayer(user, offset);
@ -50,7 +48,7 @@ function reset() {
animateTo = [0, 0];
offset = [0, 0];
user = null;
zoom = 0.2;
zoom = (Math.min(canvasWidth, canvasHeight) - consts.BORDER_WIDTH) / (consts.CELL_WIDTH * consts.GRID_COUNT);
showedDead = false;
}
@ -73,7 +71,6 @@ function paintGrid(ctx) {
ctx.fillRect(0, 0, consts.CELL_WIDTH * consts.GRID_COUNT, consts.CELL_WIDTH * consts.GRID_COUNT);
paintGridBorder(ctx);
//paintGridLines(ctx);
//Get viewing limits
var offsetX = (offset[0] - consts.BORDER_WIDTH);
var offsetY = (offset[1] - consts.BORDER_WIDTH);
@ -82,7 +79,7 @@ function paintGrid(ctx) {
var maxRow = Math.min(Math.ceil((offsetY + gameHeight / zoom) / consts.CELL_WIDTH), grid.size);
var maxCol = Math.min(Math.ceil((offsetX + gameWidth / zoom) / consts.CELL_WIDTH), grid.size);
//Paint occupied areas. (and fading ones)
//Paint occupied areas (and fading ones)
for (var r = minRow; r < maxRow; r++) {
for (var c = minCol; c < maxCol; c++) {
var p = grid.get(r, c);
@ -142,37 +139,8 @@ function paintGrid(ctx) {
}
function paintUIBar(ctx) {
//UI Bar background
ctx.fillStyle = "#24422c";
ctx.fillRect(0, 0, canvasWidth, BAR_HEIGHT);
var barOffset;
ctx.fillStyle = "white";
ctx.font = "24px Changa";
barOffset = (user && user.name) ? (ctx.measureText(user.name).width + 20) : 0;
ctx.fillText(user ? user.name : "", 5, consts.CELL_WIDTH - 5);
//Draw filled bar
ctx.fillStyle = "rgba(180, 180, 180, .3)";
ctx.fillRect(barOffset, 0, BAR_WIDTH, BAR_HEIGHT);
var userPortions = 0;
var barSize = Math.ceil((BAR_WIDTH - MIN_BAR_WIDTH) * userPortions + MIN_BAR_WIDTH);
ctx.fillStyle = user ? user.baseColor.rgbString() : "";
ctx.fillRect(barOffset, 0, barSize, consts.CELL_WIDTH);
ctx.fillStyle = user ? user.shadowColor.rgbString() : "";
ctx.fillRect(barOffset, consts.CELL_WIDTH, barSize, SHADOW_OFFSET);
//TODO: dont reset kill count and zoom when we request frames.
//Percentage
ctx.fillStyle = "white";
ctx.font = "18px Changa";
ctx.fillText((userPortions * 100).toFixed(3) + "%", 5 + barOffset, consts.CELL_WIDTH - 5);
//Number of kills
var killsText = "Kills: " + client.kills;
var killsOffset = 20 + BAR_WIDTH + barOffset;
ctx.fillText(killsText, killsOffset, consts.CELL_WIDTH - 5);
//Calcuate rank
var sorted = [];
@ -183,12 +151,6 @@ function paintUIBar(ctx) {
return (a.portion === b.portion) ? a.player.num - b.player.num : b.portion - a.portion;
});
var rank = sorted.findIndex(function(val) {
return val.player === user
});
ctx.fillText("Rank: " + (rank === -1 ? "--" : rank + 1) + " of " + sorted.length,
ctx.measureText(killsText).width + killsOffset + 20, consts.CELL_WIDTH - 5);
//Rolling the leaderboard bars
if (sorted.length > 0) {
var maxPortion = sorted[0].portion;
@ -208,7 +170,7 @@ function paintUIBar(ctx) {
var nameWidth = ctx.measureText(name).width;
barSize = Math.ceil((BAR_WIDTH - MIN_BAR_WIDTH) * portion + MIN_BAR_WIDTH);
var barX = canvasWidth - barSize;
var barY = BAR_HEIGHT * (i + 1);
var barY = BAR_HEIGHT * i;
var offset = i == 0 ? 10 : 0;
ctx.fillStyle = "rgba(10, 10, 10, .3)";
ctx.fillRect(barX - 10, barY + 10 - offset, barSize + 10, BAR_HEIGHT + offset);
@ -230,14 +192,14 @@ function paint(ctx) {
//Move grid to viewport as said with the offsets, below the stats
ctx.save();
ctx.translate(0, BAR_HEIGHT);
//ctx.translate(0, BAR_HEIGHT);
ctx.beginPath();
ctx.rect(0, 0, gameWidth, gameHeight);
ctx.clip();
//Zoom in/out based on player stats
ctx.scale(zoom, zoom);
ctx.translate(-offset[0] + consts.BORDER_WIDTH, -offset[1] + consts.BORDER_WIDTH);
ctx.translate(consts.BORDER_WIDTH, consts.BORDER_WIDTH);
paintGrid(ctx);
client.getPlayers().forEach(function (p) {
@ -253,7 +215,6 @@ function paint(ctx) {
if ((!user || user.dead) && !showedDead) {
showedDead = true;
console.log("You died!");
//return;
}
}
@ -284,11 +245,6 @@ function update() {
roll.value = playerPortion[player.num] / consts.GRID_COUNT / consts.GRID_COUNT;
roll.update();
});
//Zoom goes from 1 to .5, decreasing as portion goes up. TODO: maybe can modify this?
//if (portionsRolling[user.num]) zoom = 0.2 / (portionsRolling[user.num].lag + 1);
//TODO: animate player is dead. (maybe explosion?), and tail rewinds itself.
if (user) centerOnPlayer(user, animateTo);
}
//Helper methods

View File

@ -21,7 +21,6 @@ $(function() {
ctx = canvas.getContext("2d");
offscreenCanvas = document.createElement("canvas");
offctx = offscreenCanvas.getContext("2d");
canvas.style.marginTop = 10;
updateSize();
});
@ -34,8 +33,8 @@ function updateSize() {
gameWidth = canvasWidth = offscreenCanvas.width = canvas.width = window.innerWidth;
changed = true;
}
if (canvasHeight != window.innerHeight - 20) {
canvasHeight = offscreenCanvas.height = canvas.height = window.innerHeight - 20;
if (canvasHeight != window.innerHeight) {
canvasHeight = offscreenCanvas.height = canvas.height = window.innerHeight;
gameHeight = canvasHeight - BAR_HEIGHT;
changed = true;
}
@ -73,7 +72,6 @@ function paintGrid(ctx) {
ctx.fillRect(0, 0, consts.CELL_WIDTH * consts.GRID_COUNT, consts.CELL_WIDTH * consts.GRID_COUNT);
paintGridBorder(ctx);
//paintGridLines(ctx);
//Get viewing limits
var offsetX = (offset[0] - consts.BORDER_WIDTH);
var offsetY = (offset[1] - consts.BORDER_WIDTH);
@ -82,7 +80,7 @@ function paintGrid(ctx) {
var maxRow = Math.min(Math.ceil((offsetY + gameHeight / zoom) / consts.CELL_WIDTH), grid.size);
var maxCol = Math.min(Math.ceil((offsetX + gameWidth / zoom) / consts.CELL_WIDTH), grid.size);
//Paint occupied areas. (and fading ones)
//Paint occupied areas (and fading ones)
for (var r = minRow; r < maxRow; r++) {
for (var c = minCol; c < maxCol; c++) {
var p = grid.get(r, c);
@ -184,7 +182,7 @@ function paintUIBar(ctx) {
});
var rank = sorted.findIndex(function(val) {
return val.player === user
return val.player === user;
});
ctx.fillText("Rank: " + (rank === -1 ? "--" : rank + 1) + " of " + sorted.length,
ctx.measureText(killsText).width + killsOffset + 20, consts.CELL_WIDTH - 5);
@ -253,7 +251,6 @@ function paint(ctx) {
if ((!user || user.dead) && !showedDead) {
showedDead = true;
console.log("You died!");
//return;
}
}