Idk Linux now

This commit is contained in:
Alexander Bass 2022-06-19 16:21:33 -04:00
parent 165366c2b7
commit 80a21f626a
12 changed files with 1300 additions and 1071 deletions

2
.gitignore vendored
View file

@ -1 +1 @@
*node_modules/* *node_modules/*

84
TODO.md
View file

@ -1,42 +1,42 @@
# Project To Do list # Project To Do list
## Short Term ## Short Term
- [] Kill socket when browser closes/inactive. - [] Kill socket when browser closes/inactive.
- [] Make client get textures from single sprite sheet - [] Make client get textures from single sprite sheet
## Mid Term ## Mid Term
- [] Implement Rooms with different games on server - [] Implement Rooms with different games on server
- [] Add room selection menu on client - [] Add room selection menu on client
- [] Implement Players - [] Implement Players
- [] Player Names - [] Player Names
- [] Player Colors - [] Player Colors
- [] Prevent Duplicate player info - [] Prevent Duplicate player info
## Long Term ## Long Term
- [] Power and money system for players - [] Power and money system for players
- [] Add land ownership - [] Add land ownership
- [] Land Claiming - [] Land Claiming
- [] Difficulty to claim hills and seas - [] Difficulty to claim hills and seas
- [] Create bouy flag sprite - [] Create bouy flag sprite
- [] Make differentiation between land owned by different players - [] Make differentiation between land owned by different players
- [] System to have animated widgets overtop of the canvas. - [] System to have animated widgets overtop of the canvas.
- [] Explosion - [] Explosion
- [] Selection cursor - [] Selection cursor
- [] Color for different land status (claimed/open/unclaimable) - [] Color for different land status (claimed/open/unclaimable)
- [] Create spites for classes of buildings for economy. - [] Create spites for classes of buildings for economy.
- [x] Factory - [x] Factory
- [x] Farmland/town - [x] Farmland/town
- [] Fishing area - [] Fishing area
- [] Building selection menu - [] Building selection menu
## Longer Term ## Longer Term
- [] Add tests to ensure features act as they should - [] Add tests to ensure features act as they should
- [] Handle player death/leaving - [] Handle player death/leaving
- [] Dead player's resources go to killer with some tax. - [] Dead player's resources go to killer with some tax.
- [] Leaving player's resources go to player - [] Leaving player's resources go to player
## Finishing Touches ## Finishing Touches
- [] Sounds - [] Sounds
- [] Graphics Redo - [] Graphics Redo
- [] Fancy webpage decorations - [] Fancy webpage decorations
## Maybe ## Maybe
- [] Chat - [] Chat

287
index.js
View file

@ -1,121 +1,166 @@
const worldgen = require("./worldgen.js") const worldgen = require("./worldgen.js")
const util = require("./util.js") const util = require("./util.js")
const log = require("./log.js") const log = require("./log.js")
const gridSize = [18, 18]; const gridSize = [18, 18];
const perlinScale = 3; const perlinScale = 3;
var express = require('express');
var express = require('express'); log.setMode(0)
process.title = "Server"
process.title = "Server" setInterval(function(){ updateInfo()},5000)
setInterval(function(){ updateInfo()},5000)
function updateInfo() {
function updateInfo() { log.setInfo(server.games)
const players = game.players; }
log.setInfo(players) class Player {
} constructor(id, name, color) {
this.id = id;
class Player { this.name = name;
constructor(id, name, color) { this.color = color;
this.id = id; }
this.name = name; }
this.color = color;
} class Server {
} constructor(){
this.games = [];
class Game { }
constructor() { getGameByName(name, create) {
this.players = [{id: "adfhad", name: "bobbert"}]; const game = this.games.filter(obj => obj.name == name)[0]
this.world = worldgen.generateWorld(gridSize, perlinScale); if (game === undefined && create) {
} this.addGame(name);
// Oh no.... This cant be good code.
addPlayer(id, name) { return this.getGameByName(name);
if (this.getAllNames().includes(name)) return false }
var color = "blue" return game
const player = new Player(id, name, color); }
this.players.push(player);
return true addGame(name) {
} const game = new Game(name);
this.games.push(game);
removePlayer(id) { return game
this.players = this.players.filter(obj => obj.id != id); }
log.log("removed player - " + id) removeGame(name) {
} this.games = this.games.filter(obj => obj.name != name);
log.log("removed game - " + name)
getPlayerByID(id) { }
const player = this.players.filter(obj => obj.id == id)[0]
return player getAllIDs() {
} let ids = []
for (let i = 0; i < this.games.length; i++) {
getAllIDs() { for (let j = 0; j < this.games[i].players.length; j++) {
let ids = [] ids.push(this.games[i].players[j].id)
for (i = 0; i < this.players.length; i++) { }
ids.push(this.players[i].id) }
} return ids
return ids }
}
getAllNames() { joinClientToGame(room, nick, id, client) {
let names = [] const game = this.getGameByName(room, true);
for (i = 0; i < this.players.length; i++) { if (game.addPlayer(id, nick) == false) {
names.push(this.players[i].name) this.removeGame(game)
} return client.illegalAction(20)
return names }
} client.join(game.name)
} client.game = game;
var game = new Game(); return true
}
var app = express() //Static resources server
app.use(express.static(__dirname + '/www/'));var server = app.listen(8082, function () { }
var port = server.address().port;
log.log(`Server running at port ${port}`, "bright"); class Game {
}); constructor(name) {
this.name = name;
var io = require('socket.io')(server);/* Connection events */ this.players = [];
io.on('connection', function(client) { this.world = worldgen.generateWorld(gridSize, perlinScale);
}
client.illegalAction = function(action) {
client.emit('illegalAction', action) addPlayer(id, name) {
} if (this.getAllNames().includes(name)) return false
var color = "blue"
log.log('User connected', 'FgGreen'); const player = new Player(id, name, color);
this.players.push(player);
client.on('disconnect', function(){ return true
log.log(client.id + ' disconnected.', 'FgCyan') }
game.removePlayer(client.id)
client.broadcast.emit('playerList', game.players) removePlayer(id) {
}) this.players = this.players.filter(obj => obj.id != id);
log.log("removed player - " + id)
client.on('joinGame', function(data){ if (this.players.length < 1) {
if (game.addPlayer(client.id, data.name) == false) return client.illegalAction(20) server.removeGame(this.name);
sendMap(client) }
log.log(`${client.id} joined the game as ${data.name} requesting to join room: ${data.room}`, 'FgMagenta'); }
client.broadcast.emit('playerList', game.players)
client.emit('playerList', game.players) getPlayerByID(id) {
}) const player = this.players.filter(obj => obj.id == id)[0]
client.on('leaveGame', function(tank){ return player
log.log(client.id + ' disconnected.') }
game.removePlayer(client.id)
client.broadcast.emit('playerList', game.players) getAllIDs() {
}) let ids = []
for (i = 0; i < this.players.length; i++) {
ids.push(this.players[i].id)
client.on('clickCanvas', function(data){ }
if (!game.getAllIDs().includes(client.id)) return client.illegalAction(1) return ids
const xu = data.tilePosition[0] }
const yu = data.tilePosition[1] getAllNames() {
game.world[xu][yu].structure = data.structure let names = []
game.world[xu][yu].owner = game.getPlayerByID(client.id).color; for (i = 0; i < this.players.length; i++) {
// log.log(world[xu][yu].owner = game.getPlayerbyID(client.id)) names.push(this.players[i].name)
}
client.broadcast.emit('sync',{world: game.world}) return names
client.emit('sync',{world: game.world}) }
}) }
var server = new Server();
});
var app = express() //Static resources server
function sendMap(client) { app.use(express.static(__dirname + '/www/'));
client.broadcast.emit('sync',{world: game.world.map}) var webServer = app.listen(8082, function () {
client.emit('sync',{world: game.world.map}) var port = webServer.address().port;
} log.log(`Server running at port ${port}`, "bright");
});
var io = require('socket.io')(webServer);/* Connection events */
io.on('connection', function(client) {
client.illegalAction = function(action) {
client.emit('illegalAction', action)
}
log.log('User connected', 'FgGreen');
client.on('disconnect', function(){
if (!server.getAllIDs().includes(client.id)) return client.illegalAction(22)
log.log(client.id + ' disconnected.', 'FgCyan')
client.game.removePlayer(client.id)
})
client.on('joinGame', function(data){
if(!server.joinClientToGame(data.room, data.name, client.id, client)) return
io.to(client.game.name).emit('sync',{world: client.game.world})
log.log(`${client.id} joined the game as ${data.name} requesting to join room: ${data.room}`, 'FgMagenta');
client.emit('inGame', true)
})
client.on('leaveGame', function(tank){
log.log(celient.id + ' disconnected.')
client.game.removePlayer(client.id)
io.to(client.game.name).emit('playerList', client.game.players)
})
client.on('clickCanvas', function(data){
if (!server.getAllIDs().includes(client.id)) return client.illegalAction(1)
const room = client.game.name
const xu = util.clamp(data.tilePosition[0], 0, gridSize[0])
const yu = util.clamp(data.tilePosition[1], 0, gridSize[1])
if (!Number.isInteger(xu) || !Number.isInteger(yu)) return client.illegalAction(23)
client.game.world[xu][yu].structure = data.structure
client.game.world[xu][yu].owner = client.game.getPlayerByID(client.id).color;
io.to(client.game.name).emit('sync',{world: client.game.world})
// client.emit('sync',{world: client.game.world})
})
});

224
log.js
View file

@ -1,101 +1,123 @@
const os = require("os") const os = require("os")
var mode = 0
var logs = [] var logs = []
var info = [[],[]] var info = [[],[]]
function updateLog() { function setMode(type) {
console.clear() mode = type
const columns = process.stdout.columns; }
const rows = process.stdout.rows;
const vertSplit = Math.round(rows/4) function updateLog() {
if (mode) return
for (var i = 0; i < vertSplit; i++) { let templogs = logs;
process.stdout.cursorTo(Math.round(columns/2),i);
process.stdout.clearLine(); console.clear()
process.stdout.write(`|`) const columns = process.stdout.columns;
} const rows = process.stdout.rows;
for (var i = 0; i < columns; i++) { const vertSplit = Math.round(rows/4)
process.stdout.cursorTo(i, vertSplit)
process.stdout.write(`=`) for (var i = 0; i < vertSplit; i++) {
} process.stdout.cursorTo(Math.round(columns/2),i);
process.stdout.clearLine();
process.stdout.cursorTo(0,0) process.stdout.write(`|`)
process.stdout.write("Players:") }
const players = info[0] for (var i = 0; i < columns; i++) {
for (var i = 0; i < players.length; i++) { process.stdout.cursorTo(i, vertSplit)
process.stdout.cursorTo(0,i+1) process.stdout.write(`=`)
process.stdout.write(`Name: \x1b[1m${players[i].name}\x1b[0m -\x1b[1m ID:${players[i].id}\x1b[0m`) }
}
for (var i = 0; i < logs.length; i++ ) { process.stdout.cursorTo(0,0)
process.stdout.cursorTo(0,vertSplit+1+i) process.stdout.write("Players:")
process.stdout.write(`${logs[i]}${os.EOL}` ) const games = info[0]
} var pointer = 0
for (i = 0; i < games.length; i++) {
} process.stdout.cursorTo(0,pointer+1)
function log(string, color) {
if (string == undefined) return; process.stdout.write(`\x1b[46mGameName: \x1b[1m${games[i].name}\x1b[0m`)
var prefix = ''; const players = games[i].players;
switch (color) { for (var j = 0; j < players.length; j++) {
case "reset": process.stdout.cursorTo(0,pointer+2)
prefix = "\x1b[0m" process.stdout.write(`--Name: \x1b[1m${players[j].name}\x1b[0m -\x1b[1m ID:${players[j].id}\x1b[0m`)
break; pointer++;
case "bright": }
prefix = "\x1b[1m" pointer++;
break; }
case "dim": if (templogs.length > Math.round(3*rows/4)-3) {
prefix = "\x1b[2m" templogs.splice(0, logs.length-Math.round(3*rows/4)+2);
break; }
case "underscore": for (var i = 0; i < templogs.length; i++ ) {
prefix = "\x1b[4m" process.stdout.cursorTo(0,vertSplit+1+i)
break; process.stdout.write(`${templogs[i]}${os.EOL}` )
case "reverse": }
prefix = "\x1b[7m"
break; }
case "FgBlack": function log(string, color) {
prefix = "\x1b[30m" if (mode) return console.log(string)
break; if (string == undefined) return;
case "FgRed": var prefix = '';
prefix = "\x1b[31m" switch (color) {
break; case "reset":
case "FgGreen": prefix = "\x1b[0m"
prefix = "\x1b[32m" break;
break; case "bright":
case "FgYellow": prefix = "\x1b[1m"
prefix = "\x1b[33m" break;
break; case "dim":
case "FgBlue": prefix = "\x1b[2m"
prefix = "\x1b[34m" break;
break; case "underscore":
case "FgMagenta": prefix = "\x1b[4m"
prefix = "\x1b[35m" break;
break; case "reverse":
case "FgCyan": prefix = "\x1b[7m"
prefix = "\x1b[36m" break;
break; case "FgBlack":
case "FgWhite": prefix = "\x1b[30m"
prefix = "\x1b[37m" break;
break; case "FgRed":
} prefix = "\x1b[31m"
break;
// BgBlack = "\x1b[40m" case "FgGreen":
// BgRed = "\x1b[41m" prefix = "\x1b[32m"
// BgGreen = "\x1b[42m" break;
// BgYellow = "\x1b[43m" case "FgYellow":
// BgBlue = "\x1b[44m" prefix = "\x1b[33m"
// BgMagenta = "\x1b[45m" break;
// BgCyan = "\x1b[46m" case "FgBlue":
// BgWhite = "\x1b[47m" prefix = "\x1b[34m"
const newString = prefix + string + "\x1b[0m" break;
logs.push(newString) case "FgMagenta":
updateLog(); prefix = "\x1b[35m"
} break;
case "FgCyan":
function setInfo (players){ prefix = "\x1b[36m"
if (players != undefined) { break;
info[0] = players; case "FgWhite":
updateLog() prefix = "\x1b[37m"
} break;
}
}
// BgBlack = "\x1b[40m"
module.exports = {log, updateLog, setInfo} // BgRed = "\x1b[41m"
// BgGreen = "\x1b[42m"
// BgYellow = "\x1b[43m"
// BgBlue = "\x1b[44m"
// BgMagenta = "\x1b[45m"
// BgCyan = "\x1b[46m"
// BgWhite = "\x1b[47m"
const newString = prefix + string + "\x1b[0m"
logs.push(newString)
updateLog();
}
function setInfo (players){
if (mode) return false
if (players != undefined) {
info[0] = players;
updateLog()
}
}
module.exports = {log, updateLog, setInfo, setMode}

622
perlin.js
View file

@ -1,311 +1,311 @@
/* /*
* A speed-improved perlin and simplex noise algorithms for 2D. * A speed-improved perlin and simplex noise algorithms for 2D.
* *
* Based on example code by Stefan Gustavson (stegu@itn.liu.se). * Based on example code by Stefan Gustavson (stegu@itn.liu.se).
* Optimisations by Peter Eastman (peastman@drizzle.stanford.edu). * Optimisations by Peter Eastman (peastman@drizzle.stanford.edu).
* Better rank ordering method by Stefan Gustavson in 2012. * Better rank ordering method by Stefan Gustavson in 2012.
* Converted to Javascript by Joseph Gentle. * Converted to Javascript by Joseph Gentle.
* Converted to NPM Package by Jacob Schneider * Converted to NPM Package by Jacob Schneider
* *
* Version 2012-03-09 * Version 2012-03-09
* *
* This code was placed in the public domain by its original author, * This code was placed in the public domain by its original author,
* Stefan Gustavson. You may use it as you see fit, but * Stefan Gustavson. You may use it as you see fit, but
* attribution is appreciated. * attribution is appreciated.
* *
*/ */
module.exports = (function(global){ module.exports = (function(global){
var functions = global.noise = {}; var functions = global.noise = {};
function Grad(x, y, z) { function Grad(x, y, z) {
this.x = x; this.y = y; this.z = z; this.x = x; this.y = y; this.z = z;
} }
Grad.prototype.dot2 = function(x, y) { Grad.prototype.dot2 = function(x, y) {
return this.x*x + this.y*y; return this.x*x + this.y*y;
}; };
Grad.prototype.dot3 = function(x, y, z) { Grad.prototype.dot3 = function(x, y, z) {
return this.x*x + this.y*y + this.z*z; return this.x*x + this.y*y + this.z*z;
}; };
var grad3 = [new Grad(1,1,0),new Grad(-1,1,0),new Grad(1,-1,0),new Grad(-1,-1,0), var grad3 = [new Grad(1,1,0),new Grad(-1,1,0),new Grad(1,-1,0),new Grad(-1,-1,0),
new Grad(1,0,1),new Grad(-1,0,1),new Grad(1,0,-1),new Grad(-1,0,-1), new Grad(1,0,1),new Grad(-1,0,1),new Grad(1,0,-1),new Grad(-1,0,-1),
new Grad(0,1,1),new Grad(0,-1,1),new Grad(0,1,-1),new Grad(0,-1,-1)]; new Grad(0,1,1),new Grad(0,-1,1),new Grad(0,1,-1),new Grad(0,-1,-1)];
var p = [151,160,137,91,90,15, var p = [151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]; 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180];
// To remove the need for index wrapping, double the permutation table length // To remove the need for index wrapping, double the permutation table length
var perm = new Array(512); var perm = new Array(512);
var gradP = new Array(512); var gradP = new Array(512);
// This isn't a very good seeding function, but it works ok. It supports 2^16 // This isn't a very good seeding function, but it works ok. It supports 2^16
// different seed values. Write something better if you need more seeds. // different seed values. Write something better if you need more seeds.
functions.seed = function(seed) { functions.seed = function(seed) {
if(seed > 0 && seed < 1) { if(seed > 0 && seed < 1) {
// Scale the seed out // Scale the seed out
seed *= 65536; seed *= 65536;
} }
seed = Math.floor(seed); seed = Math.floor(seed);
if(seed < 256) { if(seed < 256) {
seed |= seed << 8; seed |= seed << 8;
} }
for(var i = 0; i < 256; i++) { for(var i = 0; i < 256; i++) {
var v; var v;
if (i & 1) { if (i & 1) {
v = p[i] ^ (seed & 255); v = p[i] ^ (seed & 255);
} else { } else {
v = p[i] ^ ((seed>>8) & 255); v = p[i] ^ ((seed>>8) & 255);
} }
perm[i] = perm[i + 256] = v; perm[i] = perm[i + 256] = v;
gradP[i] = gradP[i + 256] = grad3[v % 12]; gradP[i] = gradP[i + 256] = grad3[v % 12];
} }
}; };
functions.seed(0); functions.seed(0);
/* /*
for(var i=0; i<256; i++) { for(var i=0; i<256; i++) {
perm[i] = perm[i + 256] = p[i]; perm[i] = perm[i + 256] = p[i];
gradP[i] = gradP[i + 256] = grad3[perm[i] % 12]; gradP[i] = gradP[i + 256] = grad3[perm[i] % 12];
}*/ }*/
// Skewing and unskewing factors for 2, 3, and 4 dimensions // Skewing and unskewing factors for 2, 3, and 4 dimensions
var F2 = 0.5*(Math.sqrt(3)-1); var F2 = 0.5*(Math.sqrt(3)-1);
var G2 = (3-Math.sqrt(3))/6; var G2 = (3-Math.sqrt(3))/6;
var F3 = 1/3; var F3 = 1/3;
var G3 = 1/6; var G3 = 1/6;
// 2D simplex noise // 2D simplex noise
functions.simplex2 = function(xin, yin) { functions.simplex2 = function(xin, yin) {
var n0, n1, n2; // Noise contributions from the three corners var n0, n1, n2; // Noise contributions from the three corners
// Skew the input space to determine which simplex cell we're in // Skew the input space to determine which simplex cell we're in
var s = (xin+yin)*F2; // Hairy factor for 2D var s = (xin+yin)*F2; // Hairy factor for 2D
var i = Math.floor(xin+s); var i = Math.floor(xin+s);
var j = Math.floor(yin+s); var j = Math.floor(yin+s);
var t = (i+j)*G2; var t = (i+j)*G2;
var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed. var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed.
var y0 = yin-j+t; var y0 = yin-j+t;
// For the 2D case, the simplex shape is an equilateral triangle. // For the 2D case, the simplex shape is an equilateral triangle.
// Determine which simplex we are in. // Determine which simplex we are in.
var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
if(x0>y0) { // lower triangle, XY order: (0,0)->(1,0)->(1,1) if(x0>y0) { // lower triangle, XY order: (0,0)->(1,0)->(1,1)
i1=1; j1=0; i1=1; j1=0;
} else { // upper triangle, YX order: (0,0)->(0,1)->(1,1) } else { // upper triangle, YX order: (0,0)->(0,1)->(1,1)
i1=0; j1=1; i1=0; j1=1;
} }
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
// c = (3-sqrt(3))/6 // c = (3-sqrt(3))/6
var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
var y1 = y0 - j1 + G2; var y1 = y0 - j1 + G2;
var x2 = x0 - 1 + 2 * G2; // Offsets for last corner in (x,y) unskewed coords var x2 = x0 - 1 + 2 * G2; // Offsets for last corner in (x,y) unskewed coords
var y2 = y0 - 1 + 2 * G2; var y2 = y0 - 1 + 2 * G2;
// Work out the hashed gradient indices of the three simplex corners // Work out the hashed gradient indices of the three simplex corners
i &= 255; i &= 255;
j &= 255; j &= 255;
var gi0 = gradP[i+perm[j]]; var gi0 = gradP[i+perm[j]];
var gi1 = gradP[i+i1+perm[j+j1]]; var gi1 = gradP[i+i1+perm[j+j1]];
var gi2 = gradP[i+1+perm[j+1]]; var gi2 = gradP[i+1+perm[j+1]];
// Calculate the contribution from the three corners // Calculate the contribution from the three corners
var t0 = 0.5 - x0*x0-y0*y0; var t0 = 0.5 - x0*x0-y0*y0;
if(t0<0) { if(t0<0) {
n0 = 0; n0 = 0;
} else { } else {
t0 *= t0; t0 *= t0;
n0 = t0 * t0 * gi0.dot2(x0, y0); // (x,y) of grad3 used for 2D gradient n0 = t0 * t0 * gi0.dot2(x0, y0); // (x,y) of grad3 used for 2D gradient
} }
var t1 = 0.5 - x1*x1-y1*y1; var t1 = 0.5 - x1*x1-y1*y1;
if(t1<0) { if(t1<0) {
n1 = 0; n1 = 0;
} else { } else {
t1 *= t1; t1 *= t1;
n1 = t1 * t1 * gi1.dot2(x1, y1); n1 = t1 * t1 * gi1.dot2(x1, y1);
} }
var t2 = 0.5 - x2*x2-y2*y2; var t2 = 0.5 - x2*x2-y2*y2;
if(t2<0) { if(t2<0) {
n2 = 0; n2 = 0;
} else { } else {
t2 *= t2; t2 *= t2;
n2 = t2 * t2 * gi2.dot2(x2, y2); n2 = t2 * t2 * gi2.dot2(x2, y2);
} }
// Add contributions from each corner to get the final noise value. // Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1]. // The result is scaled to return values in the interval [-1,1].
return 70 * (n0 + n1 + n2); return 70 * (n0 + n1 + n2);
}; };
// 3D simplex noise // 3D simplex noise
functions.simplex3 = function(xin, yin, zin) { functions.simplex3 = function(xin, yin, zin) {
var n0, n1, n2, n3; // Noise contributions from the four corners var n0, n1, n2, n3; // Noise contributions from the four corners
// Skew the input space to determine which simplex cell we're in // Skew the input space to determine which simplex cell we're in
var s = (xin+yin+zin)*F3; // Hairy factor for 2D var s = (xin+yin+zin)*F3; // Hairy factor for 2D
var i = Math.floor(xin+s); var i = Math.floor(xin+s);
var j = Math.floor(yin+s); var j = Math.floor(yin+s);
var k = Math.floor(zin+s); var k = Math.floor(zin+s);
var t = (i+j+k)*G3; var t = (i+j+k)*G3;
var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed. var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed.
var y0 = yin-j+t; var y0 = yin-j+t;
var z0 = zin-k+t; var z0 = zin-k+t;
// For the 3D case, the simplex shape is a slightly irregular tetrahedron. // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
// Determine which simplex we are in. // Determine which simplex we are in.
var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
if(x0 >= y0) { if(x0 >= y0) {
if(y0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } if(y0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; }
else if(x0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } else if(x0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; }
else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; }
} else { } else {
if(y0 < z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } if(y0 < z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; }
else if(x0 < z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } else if(x0 < z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; }
else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; }
} }
// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z), // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
// c = 1/6. // c = 1/6.
var x1 = x0 - i1 + G3; // Offsets for second corner var x1 = x0 - i1 + G3; // Offsets for second corner
var y1 = y0 - j1 + G3; var y1 = y0 - j1 + G3;
var z1 = z0 - k1 + G3; var z1 = z0 - k1 + G3;
var x2 = x0 - i2 + 2 * G3; // Offsets for third corner var x2 = x0 - i2 + 2 * G3; // Offsets for third corner
var y2 = y0 - j2 + 2 * G3; var y2 = y0 - j2 + 2 * G3;
var z2 = z0 - k2 + 2 * G3; var z2 = z0 - k2 + 2 * G3;
var x3 = x0 - 1 + 3 * G3; // Offsets for fourth corner var x3 = x0 - 1 + 3 * G3; // Offsets for fourth corner
var y3 = y0 - 1 + 3 * G3; var y3 = y0 - 1 + 3 * G3;
var z3 = z0 - 1 + 3 * G3; var z3 = z0 - 1 + 3 * G3;
// Work out the hashed gradient indices of the four simplex corners // Work out the hashed gradient indices of the four simplex corners
i &= 255; i &= 255;
j &= 255; j &= 255;
k &= 255; k &= 255;
var gi0 = gradP[i+ perm[j+ perm[k ]]]; var gi0 = gradP[i+ perm[j+ perm[k ]]];
var gi1 = gradP[i+i1+perm[j+j1+perm[k+k1]]]; var gi1 = gradP[i+i1+perm[j+j1+perm[k+k1]]];
var gi2 = gradP[i+i2+perm[j+j2+perm[k+k2]]]; var gi2 = gradP[i+i2+perm[j+j2+perm[k+k2]]];
var gi3 = gradP[i+ 1+perm[j+ 1+perm[k+ 1]]]; var gi3 = gradP[i+ 1+perm[j+ 1+perm[k+ 1]]];
// Calculate the contribution from the four corners // Calculate the contribution from the four corners
var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0; var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
if(t0<0) { if(t0<0) {
n0 = 0; n0 = 0;
} else { } else {
t0 *= t0; t0 *= t0;
n0 = t0 * t0 * gi0.dot3(x0, y0, z0); // (x,y) of grad3 used for 2D gradient n0 = t0 * t0 * gi0.dot3(x0, y0, z0); // (x,y) of grad3 used for 2D gradient
} }
var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1; var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
if(t1<0) { if(t1<0) {
n1 = 0; n1 = 0;
} else { } else {
t1 *= t1; t1 *= t1;
n1 = t1 * t1 * gi1.dot3(x1, y1, z1); n1 = t1 * t1 * gi1.dot3(x1, y1, z1);
} }
var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2; var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
if(t2<0) { if(t2<0) {
n2 = 0; n2 = 0;
} else { } else {
t2 *= t2; t2 *= t2;
n2 = t2 * t2 * gi2.dot3(x2, y2, z2); n2 = t2 * t2 * gi2.dot3(x2, y2, z2);
} }
var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3; var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
if(t3<0) { if(t3<0) {
n3 = 0; n3 = 0;
} else { } else {
t3 *= t3; t3 *= t3;
n3 = t3 * t3 * gi3.dot3(x3, y3, z3); n3 = t3 * t3 * gi3.dot3(x3, y3, z3);
} }
// Add contributions from each corner to get the final noise value. // Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1]. // The result is scaled to return values in the interval [-1,1].
return 32 * (n0 + n1 + n2 + n3); return 32 * (n0 + n1 + n2 + n3);
}; };
// ##### Perlin noise stuff // ##### Perlin noise stuff
function fade(t) { function fade(t) {
return t*t*t*(t*(t*6-15)+10); return t*t*t*(t*(t*6-15)+10);
} }
function lerp(a, b, t) { function lerp(a, b, t) {
return (1-t)*a + t*b; return (1-t)*a + t*b;
} }
// 2D Perlin Noise // 2D Perlin Noise
functions.perlin2 = function(x, y) { functions.perlin2 = function(x, y) {
// Find unit grid cell containing point // Find unit grid cell containing point
var X = Math.floor(x), Y = Math.floor(y); var X = Math.floor(x), Y = Math.floor(y);
// Get relative xy coordinates of point within that cell // Get relative xy coordinates of point within that cell
x = x - X; y = y - Y; x = x - X; y = y - Y;
// Wrap the integer cells at 255 (smaller integer period can be introduced here) // Wrap the integer cells at 255 (smaller integer period can be introduced here)
X = X & 255; Y = Y & 255; X = X & 255; Y = Y & 255;
// Calculate noise contributions from each of the four corners // Calculate noise contributions from each of the four corners
var n00 = gradP[X+perm[Y]].dot2(x, y); var n00 = gradP[X+perm[Y]].dot2(x, y);
var n01 = gradP[X+perm[Y+1]].dot2(x, y-1); var n01 = gradP[X+perm[Y+1]].dot2(x, y-1);
var n10 = gradP[X+1+perm[Y]].dot2(x-1, y); var n10 = gradP[X+1+perm[Y]].dot2(x-1, y);
var n11 = gradP[X+1+perm[Y+1]].dot2(x-1, y-1); var n11 = gradP[X+1+perm[Y+1]].dot2(x-1, y-1);
// Compute the fade curve value for x // Compute the fade curve value for x
var u = fade(x); var u = fade(x);
// Interpolate the four results // Interpolate the four results
return lerp( return lerp(
lerp(n00, n10, u), lerp(n00, n10, u),
lerp(n01, n11, u), lerp(n01, n11, u),
fade(y)); fade(y));
}; };
// 3D Perlin Noise // 3D Perlin Noise
functions.perlin3 = function(x, y, z) { functions.perlin3 = function(x, y, z) {
// Find unit grid cell containing point // Find unit grid cell containing point
var X = Math.floor(x), Y = Math.floor(y), Z = Math.floor(z); var X = Math.floor(x), Y = Math.floor(y), Z = Math.floor(z);
// Get relative xyz coordinates of point within that cell // Get relative xyz coordinates of point within that cell
x = x - X; y = y - Y; z = z - Z; x = x - X; y = y - Y; z = z - Z;
// Wrap the integer cells at 255 (smaller integer period can be introduced here) // Wrap the integer cells at 255 (smaller integer period can be introduced here)
X = X & 255; Y = Y & 255; Z = Z & 255; X = X & 255; Y = Y & 255; Z = Z & 255;
// Calculate noise contributions from each of the eight corners // Calculate noise contributions from each of the eight corners
var n000 = gradP[X+ perm[Y+ perm[Z ]]].dot3(x, y, z); var n000 = gradP[X+ perm[Y+ perm[Z ]]].dot3(x, y, z);
var n001 = gradP[X+ perm[Y+ perm[Z+1]]].dot3(x, y, z-1); var n001 = gradP[X+ perm[Y+ perm[Z+1]]].dot3(x, y, z-1);
var n010 = gradP[X+ perm[Y+1+perm[Z ]]].dot3(x, y-1, z); var n010 = gradP[X+ perm[Y+1+perm[Z ]]].dot3(x, y-1, z);
var n011 = gradP[X+ perm[Y+1+perm[Z+1]]].dot3(x, y-1, z-1); var n011 = gradP[X+ perm[Y+1+perm[Z+1]]].dot3(x, y-1, z-1);
var n100 = gradP[X+1+perm[Y+ perm[Z ]]].dot3(x-1, y, z); var n100 = gradP[X+1+perm[Y+ perm[Z ]]].dot3(x-1, y, z);
var n101 = gradP[X+1+perm[Y+ perm[Z+1]]].dot3(x-1, y, z-1); var n101 = gradP[X+1+perm[Y+ perm[Z+1]]].dot3(x-1, y, z-1);
var n110 = gradP[X+1+perm[Y+1+perm[Z ]]].dot3(x-1, y-1, z); var n110 = gradP[X+1+perm[Y+1+perm[Z ]]].dot3(x-1, y-1, z);
var n111 = gradP[X+1+perm[Y+1+perm[Z+1]]].dot3(x-1, y-1, z-1); var n111 = gradP[X+1+perm[Y+1+perm[Z+1]]].dot3(x-1, y-1, z-1);
// Compute the fade curve value for x, y, z // Compute the fade curve value for x, y, z
var u = fade(x); var u = fade(x);
var v = fade(y); var v = fade(y);
var w = fade(z); var w = fade(z);
// Interpolate // Interpolate
return lerp( return lerp(
lerp( lerp(
lerp(n000, n100, u), lerp(n000, n100, u),
lerp(n001, n101, u), w), lerp(n001, n101, u), w),
lerp( lerp(
lerp(n010, n110, u), lerp(n010, n110, u),
lerp(n011, n111, u), w), lerp(n011, n111, u), w),
v); v);
}; };
return functions; return functions;
})(this); })(this);

View file

@ -1,18 +1,18 @@
const tileTypes = const tileTypes =
[ [
{name: "Grass", textureID: 0, buildPrice: 20, capturePrice:10, capturePower: 10, captureTime: 2, sellPrice:5, recapturePrice: 15, recapturePower: 100, recaptureTime: 10}, {name: "Grass", textureID: 0, buildPrice: 20, capturePrice:10, capturePower: 10, captureTime: 2, sellPrice:5, recapturePrice: 15, recapturePower: 100, recaptureTime: 10},
{name: "Hills", textureID: 1, buildPrice: 20, capturePrice:10, capturePower: 10, captureTime: 2, sellPrice:5, recapturePrice: 15, recapturePower: 100, recaptureTime: 10}, {name: "Hills", textureID: 1, buildPrice: 20, capturePrice:10, capturePower: 10, captureTime: 2, sellPrice:5, recapturePrice: 15, recapturePower: 100, recaptureTime: 10},
{name: "Sea", textureID: 2, buildPrice: 20, capturePrice:10, capturePower: 10, captureTime: 2, sellPrice:5, recapturePrice: 15, recapturePower: 100, recaptureTime: 10} {name: "Sea", textureID: 2, buildPrice: 20, capturePrice:10, capturePower: 10, captureTime: 2, sellPrice:5, recapturePrice: 15, recapturePower: 100, recaptureTime: 10}
]; ];
const structureTypes = const structureTypes =
[ [
{name: "Air", textureID:null, claimable: true, buildable: false, destroyable: false, maxQuantity:null, buildPrice: null, sellPrice: null, buildableOn: null}, {name: "Air", textureID:null, claimable: true, buildable: false, destroyable: false, maxQuantity:null, buildPrice: null, sellPrice: null, buildableOn: null},
{name: "Rock", textureID:4, claimable: false, buildable: false, destroyable: false, maxQuantity:null, buildPrice: null, sellPrice: null, buildableOn: [0,1]}, {name: "Rock", textureID:4, claimable: false, buildable: false, destroyable: false, maxQuantity:null, buildPrice: null, sellPrice: null, buildableOn: [0,1]},
{name: "Town", textureID:32, claimable: false, buildable: true, destroyable: true, maxQuantity:10, buildPrice: 10, sellPrice: 5, buildableOn: [0,2]}, {name: "Town", textureID:32, claimable: false, buildable: true, destroyable: true, maxQuantity:10, buildPrice: 10, sellPrice: 5, buildableOn: [0,2]},
{name: "City", textureID:33, claimable: false, buildable: true, destroyable: true, maxQuantity:10, buildPrice: 20, sellPrice: 10, buildableOn: [0,2]}, {name: "City", textureID:33, claimable: false, buildable: true, destroyable: true, maxQuantity:10, buildPrice: 20, sellPrice: 10, buildableOn: [0,2]},
{name: "Capitol", textureID:34, claimable: false, buildable: true, destroyable: false, maxQuantity:1, buildPrice: 30, sellPrice: 20, buildableOn: [0,2]}, {name: "Capitol", textureID:34, claimable: false, buildable: true, destroyable: false, maxQuantity:1, buildPrice: 30, sellPrice: 20, buildableOn: [0,2]},
] ]
module.exports = {tileTypes, structureTypes} module.exports = {tileTypes, structureTypes}

20
tt.js
View file

@ -1,10 +1,10 @@
let os = require('os'); let os = require('os');
var i = 0; var i = 0;
var j = 0; var j = 0;
var jh = 0 var jh = 0
process.stdout.write('Hello World' + os.EOL); process.stdout.write('Hello World' + os.EOL);
console.log(Boolean(process.stdout.isTTY)) console.log(Boolean(process.stdout.isTTY))
process.title = "Server" process.title = "Server"

14
util.js
View file

@ -1,7 +1,7 @@
function randomNumber(min, max) { function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min); return Math.floor(Math.random() * (max - min) + min);
} }
function clamp(number, min, max) { function clamp(number, min, max) {
return Math.max(min, Math.min(number, max)); return Math.max(min, Math.min(number, max));
} }
module.exports = {randomNumber, clamp} module.exports = {randomNumber, clamp}

View file

@ -1,40 +1,40 @@
var noise = require('./perlin.js'); var noise = require('./perlin.js');
const util = require("./util.js") const util = require("./util.js")
function generateWorld(gridSize, perlinScale){ function generateWorld(gridSize, perlinScale){
let x, y = 0 let x, y = 0
let tempWorld = Array.from(Array(gridSize[0]), () => new Array(gridSize[1])); let tempWorld = Array.from(Array(gridSize[0]), () => new Array(gridSize[1]));
for (x = 0; x < gridSize[0]; x++){ for (x = 0; x < gridSize[0]; x++){
for (y = 0; y < gridSize[1]; y++){ for (y = 0; y < gridSize[1]; y++){
tempWorld[x][y] = {type: 0, structure: 0, color: null, owner: null} tempWorld[x][y] = {type: 0, structure: 0, color: null, owner: null}
} }
} }
noise.seed(Math.random()) noise.seed(Math.random())
for(x = 0; x < gridSize[0]; x++){ for(x = 0; x < gridSize[0]; x++){
for(y = 0; y < gridSize[1]; y++){ for(y = 0; y < gridSize[1]; y++){
var value = (noise.perlin2(x/perlinScale, y/perlinScale))*10; var value = (noise.perlin2(x/perlinScale, y/perlinScale))*10;
if (value >= -3) { if (value >= -3) {
tempWorld[x][y].type = 0 tempWorld[x][y].type = 0
} else if (value < -3) { } else if (value < -3) {
tempWorld[x][y].type = 1 tempWorld[x][y].type = 1
} }
if (value > 1.4) { if (value > 1.4) {
tempWorld[x][y].type = 2 tempWorld[x][y].type = 2
} }
} }
} }
for (i = 0; i < gridSize[0]*gridSize[1]/15; i){ for (i = 0; i < gridSize[0]*gridSize[1]/15; i){
x = util.randomNumber(0,gridSize[0]); x = util.randomNumber(0,gridSize[0]);
y = util.randomNumber(0,gridSize[1]); y = util.randomNumber(0,gridSize[1]);
if (tempWorld[x][y].type != 1) { if (tempWorld[x][y].type != 1) {
i++; i++;
tempWorld[x][y].structure = util.randomNumber(1,4) tempWorld[x][y].structure = util.randomNumber(1,4)
} }
} }
return tempWorld; return tempWorld;
} }
module.exports = { generateWorld }; module.exports = { generateWorld };

View file

@ -1,35 +1,46 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title></title> <title></title>
<script type="text/javascript" src="socket.io.js"></script> <script type="text/javascript" src="socket.io.js"></script>
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
</head> </head>
<body> <body>
<!-- Canvas used to generate individual sprites off one sprite atlas --> <!-- Canvas used to generate individual sprites off one sprite atlas -->
<canvas class="hidden" id="spriteJank" width=24 height=24></canvas> <canvas class="hidden" id="spriteJank" width=24 height=24></canvas>
<div class="container" id="container" style="display: none;"> <div class="container" id="container" style="display: none;">
<h1>No Longer Secret Project</h1> <h1>Project</h1>
<div class="wrapper">
<div class="canvasStack"> <div class="wrapper" id="wrapper">
<canvas oncontextmenu="return false;" class="canvas1" id="canvas" width=0 height=0></canvas> <div class="top">
<canvas oncontextmenu="return false;" class="canvas2" id="hud" width="0" height="0"></canvas> <h4 id="status">Connection Status</h4>
</div> </div>
<span class ="left"><p>left</p></span>
</div> <span class="canvasStack">
</div> <canvas oncontextmenu="return false;" class="canvas1" id="canvas" width=0 height=0></canvas>
<canvas oncontextmenu="return false;" class="canvas2" id="hud" width="0" height="0"></canvas>
<div class="menu" id="menu"> </span>
<form id="form"> <span class ="right"><p>right</p></span>
<input type="text" id="room" value="room">
<input type="text" id="name" value="bob"> <div class="bottom">
<input type="submit" id="join" value="join"> <div class="buttonBar" id="buttonBar">
</form> <!-- <span class="button" no="1"></span>
</div> <span class="button" no="2"></span>
<div class="status"> <span class="button" no="3"></span>
<footer id="status">Connection Status</footer> <span class="button" no="4"></span>
</div> <span class="button" no="null"></span> -->
</body> </div>
<script src='script.js'></script> </div>
</html>
</div>
</div>
<div class="menu" id="menu">
<input type="text" id="room" value="room">
<input type="text" id="name" value="bob">
<input type="submit" id="submit" value="join">
</div>
</body>
<script src='script.js'></script>
</html>

View file

@ -1,224 +1,284 @@
// const perlinScale = 3; // const perlinScale = 3;
const IP_ADDRESS = 'http://127.0.0.1:8082/' const IP_ADDRESS = 'http://127.0.0.1:8082/'
var SERVER_CONNECTION = "disconnected"
var IN_GAME = false
var SERVER_CONNECTION = "disconnected"
const tileSize = 24;
const tileSize = 24; const gridSize = [18, 18];
const gridSize = [18, 18]; var world
var cash = 99; var tiles = []
var world var button
var tiles = []
var canvas = document.getElementById('canvas');
var canvas = document.getElementById('canvas'); var hud = document.getElementById('hud');
var hud = document.getElementById('hud'); var ctx = canvas.getContext('2d');
var ctx = canvas.getContext('2d'); var hctx = hud.getContext('2d');
var hctx = hud.getContext('2d'); var socket = io.connect(IP_ADDRESS);
var socket = io.connect(IP_ADDRESS); function joinGame(socket, data){
function joinGame(socket, data){ socket.emit('joinGame', data);
socket.emit('joinGame', data); }
} function leaveGame(socket){
function leaveGame(socket){ socket.emit('leaveGame', {});
socket.emit('leaveGame', {}); }
}
socket.on('connect', function(data){
socket.on('connect', function(data){ SERVER_CONNECTION = "connected"
SERVER_CONNECTION = "connected" updateConnectionStatus();
updateConnectionStatus(); })
}) socket.on('disconnect', function(data){
socket.on('disconnect', function(data){
SERVER_CONNECTION = "disconnected" SERVER_CONNECTION = "disconnected"
updateConnectionStatus(); updateConnectionStatus();
}) })
socket.on('illegalAction', function(data){ socket.on('illegalAction', function(data){
let action let action
switch (data) { switch (data) {
case 1: case 1:
action = "You must be in game to do this." action = "You must be in game to do this."
break; break;
case 20: case 20:
action = "That name is already taken." action = "That name is already taken."
break; break;
default: case 23:
action = "Unknown action." action = "Invalid Placement location."
break;
} default:
console.log(`Illegal Action. ${action}`) action = "Unknown action."
alert(`Illegal Action, ${action}`)
}) }
console.log(`Illegal Action. ${action}`)
function updateConnectionStatus() { alert(`Illegal Action, ${action}`)
document.getElementById("status").textContent = `Server Connection: ${SERVER_CONNECTION}` })
}
function updateConnectionStatus() {
class Cursor { let obj = document.getElementById("status")
constructor(){ obj.textContent = `Server Connection: ${SERVER_CONNECTION}`
this.x = 0 switch (SERVER_CONNECTION) {
this.y = 0 case "connected":
this.xold = 0 obj.style.color = "green";
this.yold = 0 break;
} case "disconnected":
obj.style.color = "red";
} break;
var cursor = new Cursor();
}
window.onbeforeunload = function(){ }
socket.disconnect();
world = [] class Cursor {
} constructor(){
this.x = 0
socket.on('playerList', function(data){ this.y = 0
console.log(data) this.xold = 0
}); this.yold = 0
}
socket.on('sync', function (sync){
world = sync.world; }
render() var cursor = new Cursor();
})
window.onbeforeunload = function(){
function loadSprites(){ socket.disconnect();
var spriteJank = document.getElementById('spriteJank'); world = []
var ctxj = spriteJank.getContext('2d'); }
var spriteSheet = new Image();
socket.on('playerList', function(data){
spriteSheet.src = '/sheet.png' console.log(data)
spriteSheet.onload = function() { });
socket.on('inGame', function(data){
for (y = 0; y < 16; y++) { if (!IN_GAME) {changeScene()}
for (x = 0; x < 16; x++) { IN_GAME = true;
ctxj.drawImage(spriteSheet, -x*24,-y*24) })
var tmp = new Image();
tmp.src = spriteJank.toDataURL(); socket.on('sync', function (sync){
ctxj.clearRect(0, 0, 24, 24); world = sync.world;
tiles.push(tmp) render()
} })
} function changeScene() {
} document.getElementById('menu').style = "display: none;"
spriteJank.remove(); document.getElementById('container').style = ""
} for(i=0;i < 5;i++) {
let span = document.createElement('span')
function submit(event) { span.className = "button"
let n;
document.getElementById('menu').style = "display: none;" switch (i) {
document.getElementById('container').style = "" case (1):
const room = document.getElementById("room").value n = 4
const name = document.getElementById("name").value break;
if (room == '' || name == '' || SERVER_CONNECTION == 'disconnected') return case (2):
n = 32
joinGame(socket, {room: room, name: name}) break;
event.preventDefault(); case (3):
} n = 33
break;
case (4):
n = 34
window.onload = function () { break;
// Register Events default:
const form = document.getElementById('form'); n = 5
form.addEventListener('submit', submit); }
span.appendChild(tiles[n]);
hud.addEventListener('mousemove', e => { document.getElementById("buttonBar").appendChild(span);
mouseMoved(e) span.no = i;
}); span.addEventListener('click', e => {
clickSelector(e)
hud.addEventListener("mousedown", function(e) })
{ }
getMousePosition(canvas, e); }
});
//Set canvases to be ready
canvas.width = tileSize*gridSize[0];
canvas.height = tileSize*gridSize[1];
hud.width = canvas.width function loadSprites() {
hud.height = canvas.height var spriteJank = document.getElementById('spriteJank');
var ctxj = spriteJank.getContext('2d');
//Load all sprites into memory var spriteSheet = new Image();
loadSprites()
} spriteSheet.src = '/sheet.png'
spriteSheet.onload = function() {
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
} for (y = 0; y < 16; y++) {
for (x = 0; x < 16; x++) {
function render() { // DRAW THE IMAGE TO THE CANVAS. ctxj.drawImage(spriteSheet, -x*24,-y*24)
let x, y = 0 var tmp = new Image();
for(x = 0; x < gridSize[0]; x++){ tmp.src = spriteJank.toDataURL();
for(y = 0; y < gridSize[1]; y++){ ctxj.clearRect(0, 0, 24, 24);
const xu = x*tileSize; tiles.push(tmp)
const yu = y*tileSize; }
}
// Draw buildings }
switch (world[x][y].type) { spriteJank.remove();
case (0): }
ctx.drawImage(tiles[0], xu,yu)
break; function submit(event) {
case (1): const room = document.getElementById("room").value
ctx.drawImage(tiles[2], xu,yu) const name = document.getElementById("name").value
break; if (room == '' || name == '' || SERVER_CONNECTION == 'disconnected') return
case (2): joinGame(socket, {room: room, name: name})
ctx.drawImage(tiles[1], xu,yu) event.preventDefault();
break; }
}
function clickSelector(e) {
// Draw Structures document.querySelectorAll('.button').forEach(item => {
switch (world[x][y].structure) { item.style ="";
case (1): })
ctx.drawImage(tiles[4], xu,yu) event.target.style = "background: lightslategray;"
break; button = event.target.no
case (2):
ctx.drawImage(tiles[32], xu,yu)
break;
case (3): }
ctx.drawImage(tiles[33], xu,yu)
break;
case (4): window.onload = function () {
ctx.drawImage(tiles[34], xu,yu)
break; document.getElementById("submit").addEventListener("click", e => {
} submit(e)
});
// Draw Property overlays
if (world[x][y].color != null){ hud.addEventListener('mousemove', e => {
ctx.beginPath(); mouseMoved(e)
ctx.fillStyle = world[x][y].color; });
ctx.rect(xu, yu, tileSize, tileSize) hud.addEventListener("mousedown", function(e)
ctx.globalAlpha = 0.6; {
ctx.fill() getMousePosition(canvas, e);
ctx.globalAlpha = 1; });
}
//Set canvases to be ready
} canvas.width = tileSize*gridSize[0];
} canvas.height = tileSize*gridSize[1];
console.log("image Rendered") hud.width = canvas.width
} hud.height = canvas.height
function getMousePosition(canvas, event) { //Load all sprites into memory
// Get mouse position on canvas loadSprites()
const rect = canvas.getBoundingClientRect(); }
const x = event.clientX - rect.left;
const y = event.clientY - rect.top; function randomNumber(min, max) {
// const xu = Math.floor(x/tileSize) return Math.floor(Math.random() * (max - min) + min);
// const yu = Math.floor(y/tileSize) }
const xu = cursor.x
const yu = cursor.y function render() { // DRAW THE IMAGE TO THE CANVAS.
// Convert canvas coordinates to usable coordinates within the coordinate system let x, y = 0
for(x = 0; x < gridSize[0]; x++){
for(y = 0; y < gridSize[1]; y++){
console.log("Click!") const xu = x*tileSize;
console.log(xu,yu) const yu = y*tileSize;
socket.emit('clickCanvas', {tilePosition: [xu,yu], structure: 2});
// Draw buildings
} switch (world[x][y].type) {
function mouseMoved(event) { case (0):
const x = Math.floor(event.offsetX/tileSize) ctx.drawImage(tiles[0], xu,yu)
const y = Math.floor(event.offsetY/tileSize) break;
if (cursor.xold != x || cursor.yold != y) { case (1):
cursor.x = x ctx.drawImage(tiles[2], xu,yu)
cursor.y = y break;
hctx.clearRect(cursor.xold*tileSize, cursor.yold*tileSize, tileSize, tileSize) case (2):
hctx.drawImage(tiles[80], x*tileSize,y*tileSize) ctx.drawImage(tiles[1], xu,yu)
cursor.xold = x break;
cursor.yold = y }
}
} // Draw Structures
switch (world[x][y].structure) {
case (1):
ctx.drawImage(tiles[4], xu,yu)
break;
case (2):
ctx.drawImage(tiles[32], xu,yu)
break;
case (3):
ctx.drawImage(tiles[33], xu,yu)
break;
case (4):
ctx.drawImage(tiles[34], xu,yu)
break;
}
// Draw Property overlays
if (world[x][y].color != null){
ctx.beginPath();
ctx.fillStyle = world[x][y].color;
ctx.rect(xu, yu, tileSize, tileSize)
ctx.globalAlpha = 0.6;
ctx.fill()
ctx.globalAlpha = 1;
}
}
}
console.log("image Rendered")
}
function getMousePosition(canvas, event) {
// Get mouse position on canvas
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
// const xu = Math.floor(x/tileSize)
// const yu = Math.floor(y/tileSize)
const xu = cursor.x
const yu = cursor.y
// Convert canvas coordinates to usable coordinates within the coordinate system
console.log("Click!")
console.log(xu,yu)
socket.emit('clickCanvas', {tilePosition: [xu,yu], structure: button*1});
}
function mouseMoved(event) {
const x = Math.floor(event.offsetX/tileSize)
const y = Math.floor(event.offsetY/tileSize)
if (cursor.xold != x || cursor.yold != y) {
cursor.x = x
cursor.y = y
hctx.clearRect(cursor.xold*tileSize, cursor.yold*tileSize, tileSize, tileSize)
hctx.drawImage(tiles[80], x*tileSize,y*tileSize)
cursor.xold = x
cursor.yold = y
}
}

View file

@ -1,161 +1,252 @@
canvas { canvas {
-webkit-user-select: none; /* Chrome all / Safari all */ -webkit-user-select: none; /* Chrome all / Safari all */
-moz-user-select: none; /* Firefox all */ -moz-user-select: none; /* Firefox all */
-ms-user-select: none; /* IE 10+ */ -ms-user-select: none; /* IE 10+ */
-o-user-select: none; -o-user-select: none;
user-select: none; user-select: none;
image-rendering: -moz-crisp-edges; image-rendering: -moz-crisp-edges;
image-rendering: -webkit-crisp-edges; image-rendering: -webkit-crisp-edges;
image-rendering: pixelated; image-rendering: pixelated;
image-rendering: crisp-edges; image-rendering: crisp-edges;
border: solid white; border: solid white;
border-radius: 6px; border-radius: 6px;
/* display: inline-block; */ border-width: 3px;
/* margin: auto; */ }
}
.left{
.status{ display: block;
color: green; transform: translate(0, 50px);
} float:left;
width: 100px;
.hidden { height: 437px;
display: none; background: darkolivegreen;
} }
.canvas1{ .right{
z-index: 0; display: block;
position: fixed; transform: translate(0, 50px);
left: 50%; float:right;
transform: translate(-50%, 0); width: 100px;
} height: 437px;
background: darkolivegreen;
.canvas2 { }
z-index: 1;
position: fixed; .top {
left: 50%; position: absolute;
transform: translate(-50%, 0); background: salmon;
} width: 632px;
height: 50px;
.canvasStack { }
position: fixed;
top: 150px; .bottom{
position: absolute;
} background: coral;
width:632px;
body { height:100px;
text-align: center; transform: translate(0, 486px);
background-color: #2c2f33; }
color: white;
font-variant: normal;
font-family: verdana; #mydiv {
} position: absolute;
cursor: move;
/* .wrapper { z-index: 10;
position: fixed; background: coral;
left: 50%; width: 30px;
transform: translate(-50%, 0); height: 30px;
background-color: #ff00ff; border: 1px solid #d3d3d3;
} */ }
.container{
margin: 0px;
}
h1 { span.button > img {
font-size: 25pt; pointer-events: none;
image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
} image-rendering: -moz-crisp-edges; /* Firefox */
h2 { image-rendering: -o-crisp-edges; /* Opera */
font-size: 20pt; image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
} image-rendering: pixelated; /* Chrome */
p{ -ms-interpolation-mode: nearest-neighbor; /* IE8+*/
/* font-size: 12pt; */ width: 70px;
/* text-align: left; */ height: 70px;
margin: 0; transform: translate(0, 8px);
} border: 2px solid darkgray;
border-radius: 4px;
h4 { background: lightgray;
font-size: 12pt; }
padding: 0;
margin: 0; span.button {
} -webkit-user-select: none;
-moz-user-select: none;
.startButton { -ms-user-select: none;
width: 100.5%; user-select: none;
background-color: #4CAF50; display: inline-block;
color: white; background: tan;
padding-top: 14px; width:90px;
padding-bottom: 14px; height:90px;
margin-top: 4px; margin: 5px 5px 5px 5px;
margin-bottom: 4px; vertical-align: middle;
border: none; border-radius: 3px;
border-radius: 4px; white-space: normal;
cursor: pointer; align-items: center;
} cursor: pointer;
.subSection { }
width: 100%;
text-align: center; span.button:hover {
font-size: 12pt; background: gray;
color: white; }
padding: 0;
background-color: #4d5259; .canvas1{
border-style: solid; z-index: 0;
border: solid white; position: absolute;
border-radius: 6px; transform: translate(-50%, 0);
padding-bottom: 2px; }
padding-top: 2px;
margin-top: 3px; .canvas2 {
margin-bottom: 3px; z-index: 1;
} position: absolute;
transform: translate(-50%, 0);
.slider {
-webkit-appearance: none;
width: 98%; }
background: none;
outline: none; .canvasStack {
margin-top: 10px; position: absolute;
margin-bottom: 10px; top: 50px;
height: 1px; background: darkslategray;
border: 2px solid #white; /* display: block; */
background-color: #fff; /* position: relative; */
} /* top: 150px; */
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none; .wrapper {
border: 1px solid #bdc3c7; left: 50%;
width: 20px; transform: translate(-50%, 0);
height: 20px; position: absolute;
background: #4CAF50; background: khaki;
border-radius: 3px; width: 632px;
cursor: pointer; height: 586px;
} }
.slider::-moz-range-thumb { .hidden {
border: 1px solid #bdc3c7; display: none;
width: 20px; }
height: 20px;
background: #4CAF50; body {
border-radius: 3px; text-align: center;
cursor: pointer; background-color: #2c2f33;
} color: white;
font-variant: normal;
.slider::-moz-range-track { font-family: verdana;
width: 100%; }
height: 5px;
background-color: #fff; /* .wrapper {
} position: fixed;
left: 50%;
.inline{ transform: translate(-50%, 0);
display:inline-block; background-color: #ff00ff;
margin: auto; } */
} .container{
span.spacer{ margin: 0px;
display:inline-block; }
width: 1px; h1 {
height: 25px; font-size: 25pt;
color: #fff;
background-color: #fff; }
border: 1px solid #fff; h2 {
border-radius: 6px; font-size: 20pt;
}
p{
} /* font-size: 12pt; */
/* text-align: left; */
margin: 0;
}
h4 {
font-size: 12pt;
padding: 0;
margin: 0;
}
.startButton {
width: 100.5%;
background-color: #4CAF50;
color: white;
padding-top: 14px;
padding-bottom: 14px;
margin-top: 4px;
margin-bottom: 4px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.subSection {
width: 100%;
text-align: center;
font-size: 12pt;
color: white;
padding: 0;
background-color: #4d5259;
border-style: solid;
border: solid white;
border-radius: 6px;
padding-bottom: 2px;
padding-top: 2px;
margin-top: 3px;
margin-bottom: 3px;
}
.slider {
-webkit-appearance: none;
width: 98%;
background: none;
outline: none;
margin-top: 10px;
margin-bottom: 10px;
height: 1px;
border: 2px solid #white;
background-color: #fff;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
border: 1px solid #bdc3c7;
width: 20px;
height: 20px;
background: #4CAF50;
border-radius: 3px;
cursor: pointer;
}
.slider::-moz-range-thumb {
border: 1px solid #bdc3c7;
width: 20px;
height: 20px;
background: #4CAF50;
border-radius: 3px;
cursor: pointer;
}
.slider::-moz-range-track {
width: 100%;
height: 5px;
background-color: #fff;
}
.inline{
display:inline-block;
margin: auto;
}
span.spacer{
display:inline-block;
width: 1px;
height: 25px;
color: #fff;
background-color: #fff;
border: 1px solid #fff;
border-radius: 6px;
}