From 80a21f626a983410eecd956217f73870d9b11b85 Mon Sep 17 00:00:00 2001 From: Alexander Bass Date: Sun, 19 Jun 2022 16:21:33 -0400 Subject: [PATCH] Idk Linux now --- .gitignore | 2 +- TODO.md | 84 +++---- index.js | 287 +++++++++++++---------- log.js | 224 ++++++++++-------- perlin.js | 622 ++++++++++++++++++++++++------------------------- tileinfo.js | 36 +-- tt.js | 20 +- util.js | 14 +- worldgen.js | 80 +++---- www/index.html | 81 ++++--- www/script.js | 508 ++++++++++++++++++++++------------------ www/style.css | 413 +++++++++++++++++++------------- 12 files changed, 1300 insertions(+), 1071 deletions(-) diff --git a/.gitignore b/.gitignore index 3b66d27..17935ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -*node_modules/* +*node_modules/* diff --git a/TODO.md b/TODO.md index f22a8c0..40a0640 100644 --- a/TODO.md +++ b/TODO.md @@ -1,42 +1,42 @@ -# Project To Do list - -## Short Term - - [] Kill socket when browser closes/inactive. - - [] Make client get textures from single sprite sheet - -## Mid Term - - [] Implement Rooms with different games on server - - [] Add room selection menu on client - - [] Implement Players - - [] Player Names - - [] Player Colors - - [] Prevent Duplicate player info -## Long Term - - [] Power and money system for players - - [] Add land ownership - - [] Land Claiming - - [] Difficulty to claim hills and seas - - [] Create bouy flag sprite - - [] Make differentiation between land owned by different players - - [] System to have animated widgets overtop of the canvas. - - [] Explosion - - [] Selection cursor - - [] Color for different land status (claimed/open/unclaimable) - - [] Create spites for classes of buildings for economy. - - [x] Factory - - [x] Farmland/town - - [] Fishing area - - [] Building selection menu -## Longer Term - - - [] Add tests to ensure features act as they should - - [] Handle player death/leaving - - [] Dead player's resources go to killer with some tax. - - [] Leaving player's resources go to player -## Finishing Touches - - [] Sounds - - [] Graphics Redo - - [] Fancy webpage decorations - -## Maybe - - [] Chat +# Project To Do list + +## Short Term + - [] Kill socket when browser closes/inactive. + - [] Make client get textures from single sprite sheet + +## Mid Term + - [] Implement Rooms with different games on server + - [] Add room selection menu on client + - [] Implement Players + - [] Player Names + - [] Player Colors + - [] Prevent Duplicate player info +## Long Term + - [] Power and money system for players + - [] Add land ownership + - [] Land Claiming + - [] Difficulty to claim hills and seas + - [] Create bouy flag sprite + - [] Make differentiation between land owned by different players + - [] System to have animated widgets overtop of the canvas. + - [] Explosion + - [] Selection cursor + - [] Color for different land status (claimed/open/unclaimable) + - [] Create spites for classes of buildings for economy. + - [x] Factory + - [x] Farmland/town + - [] Fishing area + - [] Building selection menu +## Longer Term + + - [] Add tests to ensure features act as they should + - [] Handle player death/leaving + - [] Dead player's resources go to killer with some tax. + - [] Leaving player's resources go to player +## Finishing Touches + - [] Sounds + - [] Graphics Redo + - [] Fancy webpage decorations + +## Maybe + - [] Chat diff --git a/index.js b/index.js index 7ce20ab..ab4e15e 100644 --- a/index.js +++ b/index.js @@ -1,121 +1,166 @@ -const worldgen = require("./worldgen.js") -const util = require("./util.js") -const log = require("./log.js") -const gridSize = [18, 18]; -const perlinScale = 3; - -var express = require('express'); - -process.title = "Server" -setInterval(function(){ updateInfo()},5000) - -function updateInfo() { - const players = game.players; - - log.setInfo(players) -} - -class Player { - constructor(id, name, color) { - this.id = id; - this.name = name; - this.color = color; - } -} - -class Game { - constructor() { - this.players = [{id: "adfhad", name: "bobbert"}]; - this.world = worldgen.generateWorld(gridSize, perlinScale); - } - - addPlayer(id, name) { - if (this.getAllNames().includes(name)) return false - var color = "blue" - const player = new Player(id, name, color); - this.players.push(player); - return true - } - - removePlayer(id) { - this.players = this.players.filter(obj => obj.id != id); - log.log("removed player - " + id) - } - - getPlayerByID(id) { - const player = this.players.filter(obj => obj.id == id)[0] - return player - } - - getAllIDs() { - let ids = [] - for (i = 0; i < this.players.length; i++) { - ids.push(this.players[i].id) - } - return ids - } - getAllNames() { - let names = [] - for (i = 0; i < this.players.length; i++) { - names.push(this.players[i].name) - } - return names - } -} -var game = new Game(); - - -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"); -}); - -var io = require('socket.io')(server);/* Connection events */ -io.on('connection', function(client) { - - client.illegalAction = function(action) { - client.emit('illegalAction', action) - } - - log.log('User connected', 'FgGreen'); - - client.on('disconnect', function(){ - log.log(client.id + ' disconnected.', 'FgCyan') - game.removePlayer(client.id) - client.broadcast.emit('playerList', game.players) - }) - - client.on('joinGame', function(data){ - if (game.addPlayer(client.id, data.name) == false) return client.illegalAction(20) - 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) - }) - client.on('leaveGame', function(tank){ - log.log(client.id + ' disconnected.') - game.removePlayer(client.id) - client.broadcast.emit('playerList', game.players) - }) - - - client.on('clickCanvas', function(data){ - if (!game.getAllIDs().includes(client.id)) return client.illegalAction(1) - const xu = data.tilePosition[0] - const yu = data.tilePosition[1] - game.world[xu][yu].structure = data.structure - game.world[xu][yu].owner = game.getPlayerByID(client.id).color; - // log.log(world[xu][yu].owner = game.getPlayerbyID(client.id)) - - client.broadcast.emit('sync',{world: game.world}) - client.emit('sync',{world: game.world}) - }) - - - }); - - function sendMap(client) { - client.broadcast.emit('sync',{world: game.world.map}) - client.emit('sync',{world: game.world.map}) - } +const worldgen = require("./worldgen.js") +const util = require("./util.js") +const log = require("./log.js") +const gridSize = [18, 18]; +const perlinScale = 3; +var express = require('express'); +log.setMode(0) +process.title = "Server" +setInterval(function(){ updateInfo()},5000) + +function updateInfo() { + log.setInfo(server.games) +} + +class Player { + constructor(id, name, color) { + this.id = id; + this.name = name; + this.color = color; + } +} + +class Server { + constructor(){ + this.games = []; + } + getGameByName(name, create) { + const game = this.games.filter(obj => obj.name == name)[0] + if (game === undefined && create) { + this.addGame(name); + // Oh no.... This cant be good code. + return this.getGameByName(name); + } + return game + } + + addGame(name) { + const game = new Game(name); + this.games.push(game); + return game + } + removeGame(name) { + this.games = this.games.filter(obj => obj.name != name); + log.log("removed game - " + name) + } + + getAllIDs() { + let ids = [] + for (let i = 0; i < this.games.length; i++) { + for (let j = 0; j < this.games[i].players.length; j++) { + ids.push(this.games[i].players[j].id) + } + } + return ids + } + + joinClientToGame(room, nick, id, client) { + const game = this.getGameByName(room, true); + if (game.addPlayer(id, nick) == false) { + this.removeGame(game) + return client.illegalAction(20) + } + client.join(game.name) + client.game = game; + return true + } + + +} + +class Game { + constructor(name) { + this.name = name; + this.players = []; + this.world = worldgen.generateWorld(gridSize, perlinScale); + } + + addPlayer(id, name) { + if (this.getAllNames().includes(name)) return false + var color = "blue" + const player = new Player(id, name, color); + this.players.push(player); + return true + } + + removePlayer(id) { + this.players = this.players.filter(obj => obj.id != id); + log.log("removed player - " + id) + if (this.players.length < 1) { + server.removeGame(this.name); + } + } + + getPlayerByID(id) { + const player = this.players.filter(obj => obj.id == id)[0] + return player + } + + getAllIDs() { + let ids = [] + for (i = 0; i < this.players.length; i++) { + ids.push(this.players[i].id) + } + return ids + } + getAllNames() { + let names = [] + for (i = 0; i < this.players.length; i++) { + names.push(this.players[i].name) + } + return names + } +} +var server = new Server(); + + +var app = express() //Static resources server +app.use(express.static(__dirname + '/www/')); +var webServer = app.listen(8082, function () { + 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}) + }) + + + }); diff --git a/log.js b/log.js index 5844f22..87c536b 100644 --- a/log.js +++ b/log.js @@ -1,101 +1,123 @@ -const os = require("os") - -var logs = [] -var info = [[],[]] - -function updateLog() { -console.clear() -const columns = process.stdout.columns; -const rows = process.stdout.rows; -const vertSplit = Math.round(rows/4) - -for (var i = 0; i < vertSplit; i++) { - process.stdout.cursorTo(Math.round(columns/2),i); - process.stdout.clearLine(); - process.stdout.write(`|`) -} -for (var i = 0; i < columns; i++) { - process.stdout.cursorTo(i, vertSplit) - process.stdout.write(`=`) -} - -process.stdout.cursorTo(0,0) -process.stdout.write("Players:") -const players = info[0] -for (var i = 0; i < players.length; i++) { -process.stdout.cursorTo(0,i+1) -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,vertSplit+1+i) - process.stdout.write(`${logs[i]}${os.EOL}` ) -} - -} -function log(string, color) { - if (string == undefined) return; - var prefix = ''; - switch (color) { - case "reset": - prefix = "\x1b[0m" - break; - case "bright": - prefix = "\x1b[1m" - break; - case "dim": - prefix = "\x1b[2m" - break; - case "underscore": - prefix = "\x1b[4m" - break; - case "reverse": - prefix = "\x1b[7m" - break; - case "FgBlack": - prefix = "\x1b[30m" - break; - case "FgRed": - prefix = "\x1b[31m" - break; - case "FgGreen": - prefix = "\x1b[32m" - break; - case "FgYellow": - prefix = "\x1b[33m" - break; - case "FgBlue": - prefix = "\x1b[34m" - break; - case "FgMagenta": - prefix = "\x1b[35m" - break; - case "FgCyan": - prefix = "\x1b[36m" - break; - case "FgWhite": - prefix = "\x1b[37m" - break; - } - - // BgBlack = "\x1b[40m" - // 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 (players != undefined) { - info[0] = players; - updateLog() -} - -} - -module.exports = {log, updateLog, setInfo} +const os = require("os") +var mode = 0 +var logs = [] +var info = [[],[]] + +function setMode(type) { + mode = type +} + +function updateLog() { +if (mode) return +let templogs = logs; + +console.clear() +const columns = process.stdout.columns; +const rows = process.stdout.rows; +const vertSplit = Math.round(rows/4) + +for (var i = 0; i < vertSplit; i++) { + process.stdout.cursorTo(Math.round(columns/2),i); + process.stdout.clearLine(); + process.stdout.write(`|`) +} +for (var i = 0; i < columns; i++) { + process.stdout.cursorTo(i, vertSplit) + process.stdout.write(`=`) +} + +process.stdout.cursorTo(0,0) +process.stdout.write("Players:") +const games = info[0] +var pointer = 0 +for (i = 0; i < games.length; i++) { + process.stdout.cursorTo(0,pointer+1) + + process.stdout.write(`\x1b[46mGameName: \x1b[1m${games[i].name}\x1b[0m`) + const players = games[i].players; + for (var j = 0; j < players.length; j++) { + process.stdout.cursorTo(0,pointer+2) + process.stdout.write(`--Name: \x1b[1m${players[j].name}\x1b[0m -\x1b[1m ID:${players[j].id}\x1b[0m`) + pointer++; + } + pointer++; +} +if (templogs.length > Math.round(3*rows/4)-3) { +templogs.splice(0, logs.length-Math.round(3*rows/4)+2); +} +for (var i = 0; i < templogs.length; i++ ) { + process.stdout.cursorTo(0,vertSplit+1+i) + process.stdout.write(`${templogs[i]}${os.EOL}` ) +} + +} +function log(string, color) { + if (mode) return console.log(string) + if (string == undefined) return; + var prefix = ''; + switch (color) { + case "reset": + prefix = "\x1b[0m" + break; + case "bright": + prefix = "\x1b[1m" + break; + case "dim": + prefix = "\x1b[2m" + break; + case "underscore": + prefix = "\x1b[4m" + break; + case "reverse": + prefix = "\x1b[7m" + break; + case "FgBlack": + prefix = "\x1b[30m" + break; + case "FgRed": + prefix = "\x1b[31m" + break; + case "FgGreen": + prefix = "\x1b[32m" + break; + case "FgYellow": + prefix = "\x1b[33m" + break; + case "FgBlue": + prefix = "\x1b[34m" + break; + case "FgMagenta": + prefix = "\x1b[35m" + break; + case "FgCyan": + prefix = "\x1b[36m" + break; + case "FgWhite": + prefix = "\x1b[37m" + break; + } + + // BgBlack = "\x1b[40m" + // 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} diff --git a/perlin.js b/perlin.js index 9c5f948..a3d5dd4 100644 --- a/perlin.js +++ b/perlin.js @@ -1,311 +1,311 @@ -/* - * A speed-improved perlin and simplex noise algorithms for 2D. - * - * Based on example code by Stefan Gustavson (stegu@itn.liu.se). - * Optimisations by Peter Eastman (peastman@drizzle.stanford.edu). - * Better rank ordering method by Stefan Gustavson in 2012. - * Converted to Javascript by Joseph Gentle. - * Converted to NPM Package by Jacob Schneider - * - * Version 2012-03-09 - * - * This code was placed in the public domain by its original author, - * Stefan Gustavson. You may use it as you see fit, but - * attribution is appreciated. - * - */ - -module.exports = (function(global){ - var functions = global.noise = {}; - - function Grad(x, y, z) { - this.x = x; this.y = y; this.z = z; - } - - Grad.prototype.dot2 = function(x, y) { - return this.x*x + this.y*y; - }; - - Grad.prototype.dot3 = function(x, y, 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), - 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)]; - - 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, - 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, - 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, - 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, - 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, - 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, - 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 - var perm = new Array(512); - var gradP = new Array(512); - - // 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. - functions.seed = function(seed) { - if(seed > 0 && seed < 1) { - // Scale the seed out - seed *= 65536; - } - - seed = Math.floor(seed); - if(seed < 256) { - seed |= seed << 8; - } - - for(var i = 0; i < 256; i++) { - var v; - if (i & 1) { - v = p[i] ^ (seed & 255); - } else { - v = p[i] ^ ((seed>>8) & 255); - } - - perm[i] = perm[i + 256] = v; - gradP[i] = gradP[i + 256] = grad3[v % 12]; - } - }; - - functions.seed(0); - - /* - for(var i=0; i<256; i++) { - perm[i] = perm[i + 256] = p[i]; - gradP[i] = gradP[i + 256] = grad3[perm[i] % 12]; - }*/ - - // Skewing and unskewing factors for 2, 3, and 4 dimensions - var F2 = 0.5*(Math.sqrt(3)-1); - var G2 = (3-Math.sqrt(3))/6; - - var F3 = 1/3; - var G3 = 1/6; - - // 2D simplex noise - functions.simplex2 = function(xin, yin) { - var n0, n1, n2; // Noise contributions from the three corners - // Skew the input space to determine which simplex cell we're in - var s = (xin+yin)*F2; // Hairy factor for 2D - var i = Math.floor(xin+s); - var j = Math.floor(yin+s); - var t = (i+j)*G2; - var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed. - var y0 = yin-j+t; - // For the 2D case, the simplex shape is an equilateral triangle. - // Determine which simplex we are in. - 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) - i1=1; j1=0; - } else { // upper triangle, YX order: (0,0)->(0,1)->(1,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 (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where - // c = (3-sqrt(3))/6 - var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords - var y1 = y0 - j1 + G2; - var x2 = x0 - 1 + 2 * G2; // Offsets for last corner in (x,y) unskewed coords - var y2 = y0 - 1 + 2 * G2; - // Work out the hashed gradient indices of the three simplex corners - i &= 255; - j &= 255; - var gi0 = gradP[i+perm[j]]; - var gi1 = gradP[i+i1+perm[j+j1]]; - var gi2 = gradP[i+1+perm[j+1]]; - // Calculate the contribution from the three corners - var t0 = 0.5 - x0*x0-y0*y0; - if(t0<0) { - n0 = 0; - } else { - t0 *= t0; - n0 = t0 * t0 * gi0.dot2(x0, y0); // (x,y) of grad3 used for 2D gradient - } - var t1 = 0.5 - x1*x1-y1*y1; - if(t1<0) { - n1 = 0; - } else { - t1 *= t1; - n1 = t1 * t1 * gi1.dot2(x1, y1); - } - var t2 = 0.5 - x2*x2-y2*y2; - if(t2<0) { - n2 = 0; - } else { - t2 *= t2; - n2 = t2 * t2 * gi2.dot2(x2, y2); - } - // Add contributions from each corner to get the final noise value. - // The result is scaled to return values in the interval [-1,1]. - return 70 * (n0 + n1 + n2); - }; - - // 3D simplex noise - functions.simplex3 = function(xin, yin, zin) { - var n0, n1, n2, n3; // Noise contributions from the four corners - - // Skew the input space to determine which simplex cell we're in - var s = (xin+yin+zin)*F3; // Hairy factor for 2D - var i = Math.floor(xin+s); - var j = Math.floor(yin+s); - var k = Math.floor(zin+s); - - var t = (i+j+k)*G3; - var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed. - var y0 = yin-j+t; - var z0 = zin-k+t; - - // For the 3D case, the simplex shape is a slightly irregular tetrahedron. - // Determine which simplex we are in. - 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 - if(x0 >= y0) { - 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 { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } - } else { - 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 { 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 (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 - // c = 1/6. - var x1 = x0 - i1 + G3; // Offsets for second corner - var y1 = y0 - j1 + G3; - var z1 = z0 - k1 + G3; - - var x2 = x0 - i2 + 2 * G3; // Offsets for third corner - var y2 = y0 - j2 + 2 * G3; - var z2 = z0 - k2 + 2 * G3; - - var x3 = x0 - 1 + 3 * G3; // Offsets for fourth corner - var y3 = y0 - 1 + 3 * G3; - var z3 = z0 - 1 + 3 * G3; - - // Work out the hashed gradient indices of the four simplex corners - i &= 255; - j &= 255; - k &= 255; - var gi0 = gradP[i+ perm[j+ perm[k ]]]; - var gi1 = gradP[i+i1+perm[j+j1+perm[k+k1]]]; - var gi2 = gradP[i+i2+perm[j+j2+perm[k+k2]]]; - var gi3 = gradP[i+ 1+perm[j+ 1+perm[k+ 1]]]; - - // Calculate the contribution from the four corners - var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0; - if(t0<0) { - n0 = 0; - } else { - t0 *= t0; - 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; - if(t1<0) { - n1 = 0; - } else { - t1 *= t1; - n1 = t1 * t1 * gi1.dot3(x1, y1, z1); - } - var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2; - if(t2<0) { - n2 = 0; - } else { - t2 *= t2; - n2 = t2 * t2 * gi2.dot3(x2, y2, z2); - } - var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3; - if(t3<0) { - n3 = 0; - } else { - t3 *= t3; - n3 = t3 * t3 * gi3.dot3(x3, y3, z3); - } - // Add contributions from each corner to get the final noise value. - // The result is scaled to return values in the interval [-1,1]. - return 32 * (n0 + n1 + n2 + n3); - - }; - - // ##### Perlin noise stuff - - function fade(t) { - return t*t*t*(t*(t*6-15)+10); - } - - function lerp(a, b, t) { - return (1-t)*a + t*b; - } - - // 2D Perlin Noise - functions.perlin2 = function(x, y) { - // Find unit grid cell containing point - var X = Math.floor(x), Y = Math.floor(y); - // Get relative xy coordinates of point within that cell - x = x - X; y = y - Y; - // Wrap the integer cells at 255 (smaller integer period can be introduced here) - X = X & 255; Y = Y & 255; - - // Calculate noise contributions from each of the four corners - var n00 = gradP[X+perm[Y]].dot2(x, y); - var n01 = gradP[X+perm[Y+1]].dot2(x, y-1); - var n10 = gradP[X+1+perm[Y]].dot2(x-1, y); - var n11 = gradP[X+1+perm[Y+1]].dot2(x-1, y-1); - - // Compute the fade curve value for x - var u = fade(x); - - // Interpolate the four results - return lerp( - lerp(n00, n10, u), - lerp(n01, n11, u), - fade(y)); - }; - - // 3D Perlin Noise - functions.perlin3 = function(x, y, z) { - // Find unit grid cell containing point - var X = Math.floor(x), Y = Math.floor(y), Z = Math.floor(z); - // Get relative xyz coordinates of point within that cell - x = x - X; y = y - Y; z = z - Z; - // Wrap the integer cells at 255 (smaller integer period can be introduced here) - X = X & 255; Y = Y & 255; Z = Z & 255; - - // Calculate noise contributions from each of the eight corners - 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 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 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 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); - - // Compute the fade curve value for x, y, z - var u = fade(x); - var v = fade(y); - var w = fade(z); - - // Interpolate - return lerp( - lerp( - lerp(n000, n100, u), - lerp(n001, n101, u), w), - lerp( - lerp(n010, n110, u), - lerp(n011, n111, u), w), - v); - }; - return functions; -})(this); +/* + * A speed-improved perlin and simplex noise algorithms for 2D. + * + * Based on example code by Stefan Gustavson (stegu@itn.liu.se). + * Optimisations by Peter Eastman (peastman@drizzle.stanford.edu). + * Better rank ordering method by Stefan Gustavson in 2012. + * Converted to Javascript by Joseph Gentle. + * Converted to NPM Package by Jacob Schneider + * + * Version 2012-03-09 + * + * This code was placed in the public domain by its original author, + * Stefan Gustavson. You may use it as you see fit, but + * attribution is appreciated. + * + */ + +module.exports = (function(global){ + var functions = global.noise = {}; + + function Grad(x, y, z) { + this.x = x; this.y = y; this.z = z; + } + + Grad.prototype.dot2 = function(x, y) { + return this.x*x + this.y*y; + }; + + Grad.prototype.dot3 = function(x, y, 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), + 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)]; + + 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, + 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, + 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, + 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, + 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, + 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, + 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 + var perm = new Array(512); + var gradP = new Array(512); + + // 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. + functions.seed = function(seed) { + if(seed > 0 && seed < 1) { + // Scale the seed out + seed *= 65536; + } + + seed = Math.floor(seed); + if(seed < 256) { + seed |= seed << 8; + } + + for(var i = 0; i < 256; i++) { + var v; + if (i & 1) { + v = p[i] ^ (seed & 255); + } else { + v = p[i] ^ ((seed>>8) & 255); + } + + perm[i] = perm[i + 256] = v; + gradP[i] = gradP[i + 256] = grad3[v % 12]; + } + }; + + functions.seed(0); + + /* + for(var i=0; i<256; i++) { + perm[i] = perm[i + 256] = p[i]; + gradP[i] = gradP[i + 256] = grad3[perm[i] % 12]; + }*/ + + // Skewing and unskewing factors for 2, 3, and 4 dimensions + var F2 = 0.5*(Math.sqrt(3)-1); + var G2 = (3-Math.sqrt(3))/6; + + var F3 = 1/3; + var G3 = 1/6; + + // 2D simplex noise + functions.simplex2 = function(xin, yin) { + var n0, n1, n2; // Noise contributions from the three corners + // Skew the input space to determine which simplex cell we're in + var s = (xin+yin)*F2; // Hairy factor for 2D + var i = Math.floor(xin+s); + var j = Math.floor(yin+s); + var t = (i+j)*G2; + var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed. + var y0 = yin-j+t; + // For the 2D case, the simplex shape is an equilateral triangle. + // Determine which simplex we are in. + 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) + i1=1; j1=0; + } else { // upper triangle, YX order: (0,0)->(0,1)->(1,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 (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where + // c = (3-sqrt(3))/6 + var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords + var y1 = y0 - j1 + G2; + var x2 = x0 - 1 + 2 * G2; // Offsets for last corner in (x,y) unskewed coords + var y2 = y0 - 1 + 2 * G2; + // Work out the hashed gradient indices of the three simplex corners + i &= 255; + j &= 255; + var gi0 = gradP[i+perm[j]]; + var gi1 = gradP[i+i1+perm[j+j1]]; + var gi2 = gradP[i+1+perm[j+1]]; + // Calculate the contribution from the three corners + var t0 = 0.5 - x0*x0-y0*y0; + if(t0<0) { + n0 = 0; + } else { + t0 *= t0; + n0 = t0 * t0 * gi0.dot2(x0, y0); // (x,y) of grad3 used for 2D gradient + } + var t1 = 0.5 - x1*x1-y1*y1; + if(t1<0) { + n1 = 0; + } else { + t1 *= t1; + n1 = t1 * t1 * gi1.dot2(x1, y1); + } + var t2 = 0.5 - x2*x2-y2*y2; + if(t2<0) { + n2 = 0; + } else { + t2 *= t2; + n2 = t2 * t2 * gi2.dot2(x2, y2); + } + // Add contributions from each corner to get the final noise value. + // The result is scaled to return values in the interval [-1,1]. + return 70 * (n0 + n1 + n2); + }; + + // 3D simplex noise + functions.simplex3 = function(xin, yin, zin) { + var n0, n1, n2, n3; // Noise contributions from the four corners + + // Skew the input space to determine which simplex cell we're in + var s = (xin+yin+zin)*F3; // Hairy factor for 2D + var i = Math.floor(xin+s); + var j = Math.floor(yin+s); + var k = Math.floor(zin+s); + + var t = (i+j+k)*G3; + var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed. + var y0 = yin-j+t; + var z0 = zin-k+t; + + // For the 3D case, the simplex shape is a slightly irregular tetrahedron. + // Determine which simplex we are in. + 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 + if(x0 >= y0) { + 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 { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } + } else { + 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 { 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 (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 + // c = 1/6. + var x1 = x0 - i1 + G3; // Offsets for second corner + var y1 = y0 - j1 + G3; + var z1 = z0 - k1 + G3; + + var x2 = x0 - i2 + 2 * G3; // Offsets for third corner + var y2 = y0 - j2 + 2 * G3; + var z2 = z0 - k2 + 2 * G3; + + var x3 = x0 - 1 + 3 * G3; // Offsets for fourth corner + var y3 = y0 - 1 + 3 * G3; + var z3 = z0 - 1 + 3 * G3; + + // Work out the hashed gradient indices of the four simplex corners + i &= 255; + j &= 255; + k &= 255; + var gi0 = gradP[i+ perm[j+ perm[k ]]]; + var gi1 = gradP[i+i1+perm[j+j1+perm[k+k1]]]; + var gi2 = gradP[i+i2+perm[j+j2+perm[k+k2]]]; + var gi3 = gradP[i+ 1+perm[j+ 1+perm[k+ 1]]]; + + // Calculate the contribution from the four corners + var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0; + if(t0<0) { + n0 = 0; + } else { + t0 *= t0; + 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; + if(t1<0) { + n1 = 0; + } else { + t1 *= t1; + n1 = t1 * t1 * gi1.dot3(x1, y1, z1); + } + var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2; + if(t2<0) { + n2 = 0; + } else { + t2 *= t2; + n2 = t2 * t2 * gi2.dot3(x2, y2, z2); + } + var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3; + if(t3<0) { + n3 = 0; + } else { + t3 *= t3; + n3 = t3 * t3 * gi3.dot3(x3, y3, z3); + } + // Add contributions from each corner to get the final noise value. + // The result is scaled to return values in the interval [-1,1]. + return 32 * (n0 + n1 + n2 + n3); + + }; + + // ##### Perlin noise stuff + + function fade(t) { + return t*t*t*(t*(t*6-15)+10); + } + + function lerp(a, b, t) { + return (1-t)*a + t*b; + } + + // 2D Perlin Noise + functions.perlin2 = function(x, y) { + // Find unit grid cell containing point + var X = Math.floor(x), Y = Math.floor(y); + // Get relative xy coordinates of point within that cell + x = x - X; y = y - Y; + // Wrap the integer cells at 255 (smaller integer period can be introduced here) + X = X & 255; Y = Y & 255; + + // Calculate noise contributions from each of the four corners + var n00 = gradP[X+perm[Y]].dot2(x, y); + var n01 = gradP[X+perm[Y+1]].dot2(x, y-1); + var n10 = gradP[X+1+perm[Y]].dot2(x-1, y); + var n11 = gradP[X+1+perm[Y+1]].dot2(x-1, y-1); + + // Compute the fade curve value for x + var u = fade(x); + + // Interpolate the four results + return lerp( + lerp(n00, n10, u), + lerp(n01, n11, u), + fade(y)); + }; + + // 3D Perlin Noise + functions.perlin3 = function(x, y, z) { + // Find unit grid cell containing point + var X = Math.floor(x), Y = Math.floor(y), Z = Math.floor(z); + // Get relative xyz coordinates of point within that cell + x = x - X; y = y - Y; z = z - Z; + // Wrap the integer cells at 255 (smaller integer period can be introduced here) + X = X & 255; Y = Y & 255; Z = Z & 255; + + // Calculate noise contributions from each of the eight corners + 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 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 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 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); + + // Compute the fade curve value for x, y, z + var u = fade(x); + var v = fade(y); + var w = fade(z); + + // Interpolate + return lerp( + lerp( + lerp(n000, n100, u), + lerp(n001, n101, u), w), + lerp( + lerp(n010, n110, u), + lerp(n011, n111, u), w), + v); + }; + return functions; +})(this); diff --git a/tileinfo.js b/tileinfo.js index d59a2fd..31367c8 100644 --- a/tileinfo.js +++ b/tileinfo.js @@ -1,18 +1,18 @@ -const tileTypes = -[ -{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: "Sea", textureID: 2, buildPrice: 20, capturePrice:10, capturePower: 10, captureTime: 2, sellPrice:5, recapturePrice: 15, recapturePower: 100, recaptureTime: 10} -]; - -const structureTypes = -[ -{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: "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: "Capitol", textureID:34, claimable: false, buildable: true, destroyable: false, maxQuantity:1, buildPrice: 30, sellPrice: 20, buildableOn: [0,2]}, -] - - -module.exports = {tileTypes, structureTypes} +const tileTypes = +[ +{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: "Sea", textureID: 2, buildPrice: 20, capturePrice:10, capturePower: 10, captureTime: 2, sellPrice:5, recapturePrice: 15, recapturePower: 100, recaptureTime: 10} +]; + +const structureTypes = +[ +{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: "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: "Capitol", textureID:34, claimable: false, buildable: true, destroyable: false, maxQuantity:1, buildPrice: 30, sellPrice: 20, buildableOn: [0,2]}, +] + + +module.exports = {tileTypes, structureTypes} diff --git a/tt.js b/tt.js index c23ce9a..b318a2a 100644 --- a/tt.js +++ b/tt.js @@ -1,10 +1,10 @@ - -let os = require('os'); -var i = 0; -var j = 0; -var jh = 0 - - -process.stdout.write('Hello World' + os.EOL); -console.log(Boolean(process.stdout.isTTY)) -process.title = "Server" + +let os = require('os'); +var i = 0; +var j = 0; +var jh = 0 + + +process.stdout.write('Hello World' + os.EOL); +console.log(Boolean(process.stdout.isTTY)) +process.title = "Server" diff --git a/util.js b/util.js index 102b476..284a94f 100644 --- a/util.js +++ b/util.js @@ -1,7 +1,7 @@ -function randomNumber(min, max) { - return Math.floor(Math.random() * (max - min) + min); -} -function clamp(number, min, max) { - return Math.max(min, Math.min(number, max)); -} -module.exports = {randomNumber, clamp} +function randomNumber(min, max) { + return Math.floor(Math.random() * (max - min) + min); +} +function clamp(number, min, max) { + return Math.max(min, Math.min(number, max)); +} +module.exports = {randomNumber, clamp} diff --git a/worldgen.js b/worldgen.js index 039e4c1..0a07073 100644 --- a/worldgen.js +++ b/worldgen.js @@ -1,40 +1,40 @@ -var noise = require('./perlin.js'); -const util = require("./util.js") - -function generateWorld(gridSize, perlinScale){ - let x, y = 0 - - let tempWorld = Array.from(Array(gridSize[0]), () => new Array(gridSize[1])); - for (x = 0; x < gridSize[0]; x++){ - for (y = 0; y < gridSize[1]; y++){ - tempWorld[x][y] = {type: 0, structure: 0, color: null, owner: null} - } - } - - noise.seed(Math.random()) - for(x = 0; x < gridSize[0]; x++){ - for(y = 0; y < gridSize[1]; y++){ - - var value = (noise.perlin2(x/perlinScale, y/perlinScale))*10; - if (value >= -3) { - tempWorld[x][y].type = 0 - } else if (value < -3) { - tempWorld[x][y].type = 1 - } - if (value > 1.4) { - tempWorld[x][y].type = 2 - } - - } - } - for (i = 0; i < gridSize[0]*gridSize[1]/15; i){ - x = util.randomNumber(0,gridSize[0]); - y = util.randomNumber(0,gridSize[1]); - if (tempWorld[x][y].type != 1) { - i++; - tempWorld[x][y].structure = util.randomNumber(1,4) - } -} - return tempWorld; -} -module.exports = { generateWorld }; +var noise = require('./perlin.js'); +const util = require("./util.js") + +function generateWorld(gridSize, perlinScale){ + let x, y = 0 + + let tempWorld = Array.from(Array(gridSize[0]), () => new Array(gridSize[1])); + for (x = 0; x < gridSize[0]; x++){ + for (y = 0; y < gridSize[1]; y++){ + tempWorld[x][y] = {type: 0, structure: 0, color: null, owner: null} + } + } + + noise.seed(Math.random()) + for(x = 0; x < gridSize[0]; x++){ + for(y = 0; y < gridSize[1]; y++){ + + var value = (noise.perlin2(x/perlinScale, y/perlinScale))*10; + if (value >= -3) { + tempWorld[x][y].type = 0 + } else if (value < -3) { + tempWorld[x][y].type = 1 + } + if (value > 1.4) { + tempWorld[x][y].type = 2 + } + + } + } + for (i = 0; i < gridSize[0]*gridSize[1]/15; i){ + x = util.randomNumber(0,gridSize[0]); + y = util.randomNumber(0,gridSize[1]); + if (tempWorld[x][y].type != 1) { + i++; + tempWorld[x][y].structure = util.randomNumber(1,4) + } +} + return tempWorld; +} +module.exports = { generateWorld }; diff --git a/www/index.html b/www/index.html index c14ce19..6c34303 100644 --- a/www/index.html +++ b/www/index.html @@ -1,35 +1,46 @@ - - - - - - - - - - - - - - -
-
Connection Status
-
- - - + + + + + + + + + + + + + + + + + diff --git a/www/script.js b/www/script.js index 4da30fc..98630ee 100644 --- a/www/script.js +++ b/www/script.js @@ -1,224 +1,284 @@ -// const perlinScale = 3; -const IP_ADDRESS = 'http://127.0.0.1:8082/' - - -var SERVER_CONNECTION = "disconnected" - -const tileSize = 24; -const gridSize = [18, 18]; -var cash = 99; -var world -var tiles = [] - -var canvas = document.getElementById('canvas'); -var hud = document.getElementById('hud'); -var ctx = canvas.getContext('2d'); -var hctx = hud.getContext('2d'); -var socket = io.connect(IP_ADDRESS); -function joinGame(socket, data){ - socket.emit('joinGame', data); -} -function leaveGame(socket){ - socket.emit('leaveGame', {}); -} - -socket.on('connect', function(data){ - SERVER_CONNECTION = "connected" - updateConnectionStatus(); -}) -socket.on('disconnect', function(data){ - SERVER_CONNECTION = "disconnected" - updateConnectionStatus(); -}) - -socket.on('illegalAction', function(data){ - let action - switch (data) { - case 1: - action = "You must be in game to do this." - break; - case 20: - action = "That name is already taken." - break; - default: - action = "Unknown action." - - } -console.log(`Illegal Action. ${action}`) -alert(`Illegal Action, ${action}`) -}) - -function updateConnectionStatus() { - document.getElementById("status").textContent = `Server Connection: ${SERVER_CONNECTION}` -} - -class Cursor { - constructor(){ - this.x = 0 - this.y = 0 - this.xold = 0 - this.yold = 0 - } - -} -var cursor = new Cursor(); - -window.onbeforeunload = function(){ - socket.disconnect(); - world = [] -} - -socket.on('playerList', function(data){ - console.log(data) -}); - -socket.on('sync', function (sync){ - world = sync.world; - render() -}) - -function loadSprites(){ - var spriteJank = document.getElementById('spriteJank'); - var ctxj = spriteJank.getContext('2d'); - var spriteSheet = new Image(); - - spriteSheet.src = '/sheet.png' - spriteSheet.onload = function() { - - - for (y = 0; y < 16; y++) { - for (x = 0; x < 16; x++) { - ctxj.drawImage(spriteSheet, -x*24,-y*24) - var tmp = new Image(); - tmp.src = spriteJank.toDataURL(); - ctxj.clearRect(0, 0, 24, 24); - tiles.push(tmp) - } - } - } - spriteJank.remove(); -} - -function submit(event) { - - document.getElementById('menu').style = "display: none;" - document.getElementById('container').style = "" - const room = document.getElementById("room").value - const name = document.getElementById("name").value - if (room == '' || name == '' || SERVER_CONNECTION == 'disconnected') return - - joinGame(socket, {room: room, name: name}) - event.preventDefault(); -} - - - -window.onload = function () { - // Register Events - const form = document.getElementById('form'); - form.addEventListener('submit', submit); - - hud.addEventListener('mousemove', e => { - mouseMoved(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 - hud.height = canvas.height - - //Load all sprites into memory - loadSprites() -} - -function randomNumber(min, max) { - return Math.floor(Math.random() * (max - min) + min); -} - -function render() { // DRAW THE IMAGE TO THE CANVAS. - let x, y = 0 - for(x = 0; x < gridSize[0]; x++){ - for(y = 0; y < gridSize[1]; y++){ - const xu = x*tileSize; - const yu = y*tileSize; - - // Draw buildings - switch (world[x][y].type) { - case (0): - ctx.drawImage(tiles[0], xu,yu) - break; - case (1): - ctx.drawImage(tiles[2], xu,yu) - break; - case (2): - ctx.drawImage(tiles[1], xu,yu) - break; - } - - // 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: 2}); - -} -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 -} -} +// const perlinScale = 3; +const IP_ADDRESS = 'http://127.0.0.1:8082/' +var SERVER_CONNECTION = "disconnected" +var IN_GAME = false + +const tileSize = 24; +const gridSize = [18, 18]; +var world +var tiles = [] +var button + +var canvas = document.getElementById('canvas'); +var hud = document.getElementById('hud'); +var ctx = canvas.getContext('2d'); +var hctx = hud.getContext('2d'); +var socket = io.connect(IP_ADDRESS); +function joinGame(socket, data){ + socket.emit('joinGame', data); +} +function leaveGame(socket){ + socket.emit('leaveGame', {}); +} + +socket.on('connect', function(data){ + SERVER_CONNECTION = "connected" + updateConnectionStatus(); +}) +socket.on('disconnect', function(data){ + + SERVER_CONNECTION = "disconnected" + updateConnectionStatus(); +}) + +socket.on('illegalAction', function(data){ + let action + switch (data) { + case 1: + action = "You must be in game to do this." + break; + case 20: + action = "That name is already taken." + break; + case 23: + action = "Invalid Placement location." + break; + default: + action = "Unknown action." + + } +console.log(`Illegal Action. ${action}`) +alert(`Illegal Action, ${action}`) +}) + +function updateConnectionStatus() { + let obj = document.getElementById("status") + obj.textContent = `Server Connection: ${SERVER_CONNECTION}` + switch (SERVER_CONNECTION) { + case "connected": + obj.style.color = "green"; + break; + case "disconnected": + obj.style.color = "red"; + break; + + } +} + +class Cursor { + constructor(){ + this.x = 0 + this.y = 0 + this.xold = 0 + this.yold = 0 + } + +} +var cursor = new Cursor(); + +window.onbeforeunload = function(){ + socket.disconnect(); + world = [] +} + +socket.on('playerList', function(data){ + console.log(data) +}); + +socket.on('inGame', function(data){ + if (!IN_GAME) {changeScene()} + IN_GAME = true; +}) + +socket.on('sync', function (sync){ + world = sync.world; + render() +}) +function changeScene() { + document.getElementById('menu').style = "display: none;" + document.getElementById('container').style = "" + for(i=0;i < 5;i++) { + let span = document.createElement('span') + span.className = "button" + let n; + switch (i) { + case (1): + n = 4 + break; + case (2): + n = 32 + break; + case (3): + n = 33 + break; + case (4): + n = 34 + break; + default: + n = 5 + } + span.appendChild(tiles[n]); + document.getElementById("buttonBar").appendChild(span); + span.no = i; + span.addEventListener('click', e => { + clickSelector(e) + }) +} +} + + + + + +function loadSprites() { + var spriteJank = document.getElementById('spriteJank'); + var ctxj = spriteJank.getContext('2d'); + var spriteSheet = new Image(); + + spriteSheet.src = '/sheet.png' + spriteSheet.onload = function() { + + + for (y = 0; y < 16; y++) { + for (x = 0; x < 16; x++) { + ctxj.drawImage(spriteSheet, -x*24,-y*24) + var tmp = new Image(); + tmp.src = spriteJank.toDataURL(); + ctxj.clearRect(0, 0, 24, 24); + tiles.push(tmp) + } + } +} + spriteJank.remove(); +} + +function submit(event) { + const room = document.getElementById("room").value + const name = document.getElementById("name").value + if (room == '' || name == '' || SERVER_CONNECTION == 'disconnected') return + joinGame(socket, {room: room, name: name}) + event.preventDefault(); +} + +function clickSelector(e) { + document.querySelectorAll('.button').forEach(item => { + item.style =""; + }) + event.target.style = "background: lightslategray;" + button = event.target.no + + + +} + + +window.onload = function () { + +document.getElementById("submit").addEventListener("click", e => { + submit(e) +}); + + hud.addEventListener('mousemove', e => { + mouseMoved(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 + hud.height = canvas.height + + //Load all sprites into memory + loadSprites() +} + +function randomNumber(min, max) { + return Math.floor(Math.random() * (max - min) + min); +} + +function render() { // DRAW THE IMAGE TO THE CANVAS. + let x, y = 0 + for(x = 0; x < gridSize[0]; x++){ + for(y = 0; y < gridSize[1]; y++){ + const xu = x*tileSize; + const yu = y*tileSize; + + // Draw buildings + switch (world[x][y].type) { + case (0): + ctx.drawImage(tiles[0], xu,yu) + break; + case (1): + ctx.drawImage(tiles[2], xu,yu) + break; + case (2): + ctx.drawImage(tiles[1], xu,yu) + break; + } + + // 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 +} +} diff --git a/www/style.css b/www/style.css index 25dba44..6b58476 100644 --- a/www/style.css +++ b/www/style.css @@ -1,161 +1,252 @@ -canvas { - -webkit-user-select: none; /* Chrome all / Safari all */ - -moz-user-select: none; /* Firefox all */ - -ms-user-select: none; /* IE 10+ */ - -o-user-select: none; - user-select: none; - image-rendering: -moz-crisp-edges; - image-rendering: -webkit-crisp-edges; - image-rendering: pixelated; - image-rendering: crisp-edges; - border: solid white; - border-radius: 6px; - /* display: inline-block; */ - /* margin: auto; */ -} - -.status{ - color: green; -} - -.hidden { - display: none; -} - -.canvas1{ - z-index: 0; - position: fixed; - left: 50%; - transform: translate(-50%, 0); -} - -.canvas2 { - z-index: 1; - position: fixed; - left: 50%; - transform: translate(-50%, 0); -} - -.canvasStack { - position: fixed; - top: 150px; - -} - -body { -text-align: center; -background-color: #2c2f33; -color: white; -font-variant: normal; -font-family: verdana; -} - -/* .wrapper { - position: fixed; - left: 50%; - transform: translate(-50%, 0); - background-color: #ff00ff; -} */ -.container{ - margin: 0px; -} -h1 { - font-size: 25pt; - -} -h2 { - 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; - - -} +canvas { + -webkit-user-select: none; /* Chrome all / Safari all */ + -moz-user-select: none; /* Firefox all */ + -ms-user-select: none; /* IE 10+ */ + -o-user-select: none; + user-select: none; + image-rendering: -moz-crisp-edges; + image-rendering: -webkit-crisp-edges; + image-rendering: pixelated; + image-rendering: crisp-edges; + border: solid white; + border-radius: 6px; + border-width: 3px; +} + +.left{ + display: block; + transform: translate(0, 50px); + float:left; + width: 100px; + height: 437px; + background: darkolivegreen; +} + +.right{ + display: block; + transform: translate(0, 50px); + float:right; + width: 100px; + height: 437px; + background: darkolivegreen; +} + +.top { +position: absolute; +background: salmon; +width: 632px; +height: 50px; +} + +.bottom{ + position: absolute; + background: coral; + width:632px; + height:100px; + transform: translate(0, 486px); +} + + +#mydiv { + position: absolute; + cursor: move; + z-index: 10; + background: coral; + width: 30px; + height: 30px; + border: 1px solid #d3d3d3; +} + + + +span.button > img { + pointer-events: none; + image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */ + image-rendering: -moz-crisp-edges; /* Firefox */ + image-rendering: -o-crisp-edges; /* Opera */ + image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */ + image-rendering: pixelated; /* Chrome */ + -ms-interpolation-mode: nearest-neighbor; /* IE8+*/ + width: 70px; + height: 70px; + transform: translate(0, 8px); + border: 2px solid darkgray; + border-radius: 4px; + background: lightgray; +} + +span.button { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + display: inline-block; + background: tan; + width:90px; + height:90px; + margin: 5px 5px 5px 5px; + vertical-align: middle; + border-radius: 3px; + white-space: normal; + align-items: center; + cursor: pointer; + +} + +span.button:hover { + background: gray; +} + +.canvas1{ + z-index: 0; + position: absolute; + transform: translate(-50%, 0); +} + +.canvas2 { + z-index: 1; + position: absolute; + transform: translate(-50%, 0); + + +} + +.canvasStack { + position: absolute; + top: 50px; + background: darkslategray; + /* display: block; */ + /* position: relative; */ + /* top: 150px; */ +} + +.wrapper { + left: 50%; + transform: translate(-50%, 0); + position: absolute; + background: khaki; + width: 632px; + height: 586px; +} + +.hidden { + display: none; +} + +body { +text-align: center; +background-color: #2c2f33; +color: white; +font-variant: normal; +font-family: verdana; +} + +/* .wrapper { + position: fixed; + left: 50%; + transform: translate(-50%, 0); + background-color: #ff00ff; +} */ +.container{ + margin: 0px; +} +h1 { + font-size: 25pt; + +} +h2 { + 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; + + +}