Game rooms with page hash
This commit is contained in:
+28
-11
@@ -4,7 +4,7 @@ const ctx = canvas.getContext('2d');
|
|||||||
let hsize = 300;
|
let hsize = 300;
|
||||||
let current;
|
let current;
|
||||||
let players;
|
let players;
|
||||||
|
let room;
|
||||||
let history = {};
|
let history = {};
|
||||||
|
|
||||||
function ellipse(cx, cy, rx, ry) {
|
function ellipse(cx, cy, rx, ry) {
|
||||||
@@ -70,13 +70,23 @@ function drawGame() {
|
|||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
const ratio = canvas.height / window.innerHeight;
|
const ratio = canvas.height / window.innerHeight;
|
||||||
|
|
||||||
ctx.font = `bold ${ratio * 120}px Roboto`;
|
const writeTitleText = function (txt, x, y) {
|
||||||
ctx.textAlign = 'center';
|
ctx.font = `bold 120px Roboto`;
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
|
||||||
ctx.fillStyle = '#4b4b4b';
|
const lines = txt.split('\n');
|
||||||
ctx.fillText('snex.io', canvas.width / 2 - ratio * 3, canvas.height / 2 + ratio * 37);
|
|
||||||
ctx.fillStyle = '#545454';
|
lines.forEach(function (line, i) {
|
||||||
ctx.fillText('snex.io', canvas.width / 2, canvas.height / 2 + ratio * 40);
|
ctx.fillStyle = '#4b4b4b';
|
||||||
|
ctx.fillText(line, x - 3, y + 37 - (120 * lines.length) / 2 + 120 * i);
|
||||||
|
ctx.fillStyle = '#545454';
|
||||||
|
ctx.fillText(line, x, y + 40 - (120 * lines.length) / 2 + 120 * i);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
writeTitleText(`snex.io\n#${room}`, canvas.width / 2, canvas.height / 2);
|
||||||
|
|
||||||
ctx.lineCap = 'round';
|
ctx.lineCap = 'round';
|
||||||
ctx.lineJoin = 'round';
|
ctx.lineJoin = 'round';
|
||||||
@@ -101,9 +111,11 @@ const socket = io({
|
|||||||
});
|
});
|
||||||
socket.on('connect', function () {
|
socket.on('connect', function () {
|
||||||
console.log('connected');
|
console.log('connected');
|
||||||
$(window).focus(function () {
|
if (window.location.hash) {
|
||||||
socket.emit('history', current);
|
socket.emit('room', window.location.hash.slice(1));
|
||||||
});
|
} else {
|
||||||
|
socket.emit('room', undefined);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
socket.on('disconnect', function () {
|
socket.on('disconnect', function () {
|
||||||
console.log('disconnected');
|
console.log('disconnected');
|
||||||
@@ -114,7 +126,12 @@ socket.on('info', function (res) {
|
|||||||
history = res.history;
|
history = res.history;
|
||||||
hsize = res.hsize;
|
hsize = res.hsize;
|
||||||
players = res.players;
|
players = res.players;
|
||||||
drawGame()
|
room = res.room;
|
||||||
|
window.location.hash = '#' + room;
|
||||||
|
drawGame();
|
||||||
|
$(window).focus(function () {
|
||||||
|
socket.emit('history', current);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('history', function (h) {
|
socket.on('history', function (h) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const convert = require('color-convert');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
app.get('*', function (req, res) {
|
app.get('*', function (req, res) {
|
||||||
if(req.originalUrl === '/')
|
if (req.originalUrl === '/')
|
||||||
res.sendFile(`${__dirname}/client/index.html`);
|
res.sendFile(`${__dirname}/client/index.html`);
|
||||||
else if (fs.existsSync(`${__dirname}/client${req.originalUrl}`))
|
else if (fs.existsSync(`${__dirname}/client${req.originalUrl}`))
|
||||||
res.sendFile(`${__dirname}/client${req.originalUrl}`);
|
res.sendFile(`${__dirname}/client${req.originalUrl}`);
|
||||||
@@ -33,12 +33,12 @@ function intersects(a1, a2, b1, b2) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dist(a1,a2){
|
function dist(a1, a2) {
|
||||||
return Math.sqrt(Math.pow(a1.x-a2.x,2)+Math.pow(a1.y-a2.y,2));
|
return Math.sqrt(Math.pow(a1.x - a2.x, 2) + Math.pow(a1.y - a2.y, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
function clone(a){
|
function clone(a) {
|
||||||
return {x:parseFloat(a.x),y:parseFloat(a.y)};
|
return {x: parseFloat(a.x), y: parseFloat(a.y)};
|
||||||
}
|
}
|
||||||
|
|
||||||
const HSIZE = 300;
|
const HSIZE = 300;
|
||||||
@@ -47,131 +47,168 @@ const MAXY = 900;
|
|||||||
const SPD = 5;
|
const SPD = 5;
|
||||||
const MAX_ANGLE_SPEED = Math.PI / 32;
|
const MAX_ANGLE_SPEED = Math.PI / 32;
|
||||||
|
|
||||||
const players = {};
|
const rooms = {};
|
||||||
const history = {};
|
|
||||||
|
|
||||||
let upc = 0;
|
let updateCount = 0;
|
||||||
let ic = 0;
|
let intersectCount = 0;
|
||||||
|
let playerCount = 0;
|
||||||
|
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
//main loop
|
//main loop
|
||||||
Object.keys(players).forEach(function (name) {
|
Object.keys(rooms).forEach(function (room) {
|
||||||
const p = players[name];
|
Object.keys(rooms[room].players).forEach(function (name) {
|
||||||
if (p.alive) {
|
const p = rooms[room].players[name];
|
||||||
const lastpos = clone(p.pos);
|
if (p.alive) {
|
||||||
p.pos.x += SPD * Math.cos(p.angle);
|
const lastpos = clone(p.pos);
|
||||||
p.pos.y += SPD * Math.sin(p.angle);
|
p.pos.x += SPD * Math.cos(p.angle);
|
||||||
p.angle += p.angleSpd;
|
p.pos.y += SPD * Math.sin(p.angle);
|
||||||
let exempt = false;
|
p.angle += p.angleSpd;
|
||||||
if (p.pos.x > MAXX){
|
let exempt = false;
|
||||||
p.pos.x = 0;
|
if (p.pos.x > MAXX) {
|
||||||
exempt = true;
|
p.pos.x = 0;
|
||||||
}
|
exempt = true;
|
||||||
if (p.pos.x < 0){
|
}
|
||||||
p.pos.x = MAXX;
|
if (p.pos.x < 0) {
|
||||||
exempt = true;
|
p.pos.x = MAXX;
|
||||||
}
|
exempt = true;
|
||||||
if (p.pos.y > MAXY){
|
}
|
||||||
p.pos.y = 0;
|
if (p.pos.y > MAXY) {
|
||||||
exempt = true;
|
p.pos.y = 0;
|
||||||
}
|
exempt = true;
|
||||||
if (p.pos.y < 0){
|
}
|
||||||
p.pos.y = MAXY;
|
if (p.pos.y < 0) {
|
||||||
exempt = true;
|
p.pos.y = MAXY;
|
||||||
}
|
exempt = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(p.starting <= 0){
|
if (p.starting <= 0) {
|
||||||
const h = history[name];
|
const h = rooms[room].history[name];
|
||||||
h.i0 = (h.i0 + 1) % HSIZE;
|
h.i0 = (h.i0 + 1) % HSIZE;
|
||||||
h.list[h.i0] = clone(p.pos);
|
h.list[h.i0] = clone(p.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!exempt && p.starting <= 0){
|
if (!exempt && p.starting <= 0) {
|
||||||
const ds = dist(lastpos,p.pos);
|
const ds = dist(lastpos, p.pos);
|
||||||
if(ds <= SPD*0.9)
|
if (ds <= SPD * 0.9)
|
||||||
process.stdout.write(`\r${name} moved too slowly : ${ds} [${lastpos.x},${lastpos.y}]->[${p.pos.x},${p.pos.y}]\n`);
|
process.stdout.write(`\r${name} moved too slowly : ${ds} [${lastpos.x},${lastpos.y}]->[${p.pos.x},${p.pos.y}]\n`);
|
||||||
if(ds >= SPD*1.1)
|
if (ds >= SPD * 1.1)
|
||||||
process.stdout.write(`\r${name} moved too quickly : ${ds} [${lastpos.x},${lastpos.y}]->[${p.pos.x},${p.pos.y}]\n`);
|
process.stdout.write(`\r${name} moved too quickly : ${ds} [${lastpos.x},${lastpos.y}]->[${p.pos.x},${p.pos.y}]\n`);
|
||||||
|
|
||||||
Object.keys(history).forEach(function (name2) {
|
Object.keys(rooms[room].history).forEach(function (name2) {
|
||||||
if (p.alive && name !== name2) {
|
if (p.alive && name !== name2) {
|
||||||
const h2 = history[name2];
|
const h2 = rooms[room].history[name2];
|
||||||
let lastpoint = h2.list[h2.i0];
|
let lastpoint = h2.list[h2.i0];
|
||||||
if(!lastpoint)
|
if (!lastpoint)
|
||||||
return;
|
return;
|
||||||
for (let di = 1; di < HSIZE; di++) {
|
for (let di = 1; di < HSIZE; di++) {
|
||||||
const point = h2.list[(h2.i0 - di + HSIZE) % HSIZE];
|
const point = h2.list[(h2.i0 - di + HSIZE) % HSIZE];
|
||||||
if (point !== undefined) {
|
if (point !== undefined) {
|
||||||
if(Math.abs(lastpoint.x - point.x) < 1600 * .9 && Math.abs(lastpoint.y - point.y) < 900 * .9){
|
if (Math.abs(lastpoint.x - point.x) < 1600 * .9 && Math.abs(lastpoint.y - point.y) < 900 * .9) {
|
||||||
ic++;
|
intersectCount++;
|
||||||
if (intersects(lastpos, p.pos, lastpoint, point)) {
|
if (intersects(lastpos, p.pos, lastpoint, point)) {
|
||||||
process.stdout.write(`\r${name} collided with ${name2} \n`);
|
process.stdout.write(`\r${name} collided with ${name2} \n`);
|
||||||
p.alive = false;
|
p.alive = false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
lastpoint = point;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
lastpoint = point;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if (p.starting > 0)
|
||||||
|
p.starting -= 20;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
if(p.starting > 0)
|
io.to(room).emit('players', rooms[room].players);
|
||||||
p.starting -= 20;
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
io.emit('players', players);
|
updateCount++;
|
||||||
upc++;
|
|
||||||
}, 20);
|
}, 20);
|
||||||
|
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
process.stdout.write(`\rtick ${20 * upc * 20 / 1000}/20 ms (${Object.keys(players).length} connected) (${ic} intersect/s) `);
|
process.stdout.write(`\rtick ${20 * updateCount * 20 / 1000}/20 ms (${Object.keys(rooms).length} rooms) (${playerCount} players) (${intersectCount} intersect/s) `);
|
||||||
upc = 0;
|
updateCount = 0;
|
||||||
ic = 0;
|
intersectCount = 0;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
io.on('connection', function (socket) {
|
io.on('connection', function (socket) {
|
||||||
socket.name = '#' + ('0000' + randInt(0, 10000)).slice(-4);
|
socket.name = '#' + ('0000' + randInt(0, 10000)).slice(-4);
|
||||||
process.stdout.write(`\r${socket.name} connected \n`);
|
process.stdout.write(`\r${socket.name} connected \n`);
|
||||||
players[socket.name] = {
|
playerCount++;
|
||||||
pos: {
|
|
||||||
x: randInt(100, MAXX - 100),
|
socket.on('room', function (name) {
|
||||||
y: randInt(100, MAXY - 100)
|
if (socket.room)
|
||||||
},
|
return;
|
||||||
angle: Math.random() * Math.PI,
|
if (name) {
|
||||||
angleSpd: 0,
|
socket.room = name;
|
||||||
color: randomColor(),
|
} else {
|
||||||
name: socket.name,
|
socket.room = ('000000' + randInt(0, 1000000)).slice(-4);
|
||||||
alive: true,
|
}
|
||||||
starting: 2000
|
|
||||||
};
|
socket.join(socket.room);
|
||||||
history[socket.name] = {
|
|
||||||
i0: -1,
|
if (!rooms[socket.room]) {
|
||||||
list: new Array(HSIZE)
|
rooms[socket.room] = {
|
||||||
};
|
players: {},
|
||||||
socket.emit('info', {
|
history: {}
|
||||||
self:players[socket.name],
|
}
|
||||||
players:players,
|
}
|
||||||
history:history,
|
|
||||||
hsize:HSIZE
|
rooms[socket.room].players[socket.name] = {
|
||||||
|
pos: {
|
||||||
|
x: randInt(100, MAXX - 100),
|
||||||
|
y: randInt(100, MAXY - 100)
|
||||||
|
},
|
||||||
|
angle: Math.random() * Math.PI,
|
||||||
|
angleSpd: 0,
|
||||||
|
color: randomColor(),
|
||||||
|
name: socket.name,
|
||||||
|
alive: true,
|
||||||
|
starting: 2000
|
||||||
|
};
|
||||||
|
rooms[socket.room].history[socket.name] = {
|
||||||
|
i0: -1,
|
||||||
|
list: new Array(HSIZE)
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.emit('info', {
|
||||||
|
room: socket.room,
|
||||||
|
self: rooms[socket.room].players[socket.name],
|
||||||
|
players: rooms[socket.room].players,
|
||||||
|
history: rooms[socket.room].history,
|
||||||
|
hsize: HSIZE
|
||||||
|
});
|
||||||
|
|
||||||
|
process.stdout.write(`\rroom #${socket.room} > ${socket.name} connected \n`);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('history', function () {
|
socket.on('history', function () {
|
||||||
socket.emit('history', history);
|
if (socket.room)
|
||||||
|
socket.emit('history', rooms[socket.room].history);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('disconnect', function () {
|
socket.on('disconnect', function () {
|
||||||
delete players[socket.name];
|
playerCount--;
|
||||||
delete history[socket.name];
|
if (!socket.room)
|
||||||
process.stdout.write(`\r${socket.name} disconnected \n`);
|
return;
|
||||||
io.emit('players', players);
|
delete rooms[socket.room].players[socket.name];
|
||||||
|
delete rooms[socket.room].history[socket.name];
|
||||||
|
process.stdout.write(`\rroom #${socket.room} > ${socket.name} disconnected \n`);
|
||||||
|
if (Object.keys(rooms[socket.room].players).length === 0) {
|
||||||
|
delete rooms[socket.room];
|
||||||
|
process.stdout.write(`\rroom #${socket.room} deleted \n`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('update', function (newp) {
|
socket.on('update', function (newp) {
|
||||||
const p = players[newp.name];
|
if (!socket.room)
|
||||||
|
return;
|
||||||
|
const p = rooms[socket.room].players[newp.name];
|
||||||
if (!p) {
|
if (!p) {
|
||||||
socket.disconnect();
|
socket.disconnect();
|
||||||
return;
|
return;
|
||||||
@@ -179,11 +216,11 @@ io.on('connection', function (socket) {
|
|||||||
if (!p.alive)
|
if (!p.alive)
|
||||||
return;
|
return;
|
||||||
if (newp.angleSpd > 0)
|
if (newp.angleSpd > 0)
|
||||||
players[newp.name].angleSpd = MAX_ANGLE_SPEED;
|
rooms[socket.room].players[newp.name].angleSpd = MAX_ANGLE_SPEED;
|
||||||
else if (newp.angleSpd < 0)
|
else if (newp.angleSpd < 0)
|
||||||
players[newp.name].angleSpd = -MAX_ANGLE_SPEED;
|
rooms[socket.room].players[newp.name].angleSpd = -MAX_ANGLE_SPEED;
|
||||||
else
|
else
|
||||||
players[newp.name].angleSpd = 0;
|
rooms[socket.room].players[newp.name].angleSpd = 0;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user