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
## 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

287
index.js
View file

@ -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})
})
});

224
log.js
View file

@ -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}

622
perlin.js
View file

@ -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);

View file

@ -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}

20
tt.js
View file

@ -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"

14
util.js
View file

@ -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}

View file

@ -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 };

View file

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

View file

@ -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;
}