Initial commit
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
const app = require('express')();
|
||||
const http = require('http').Server(app);
|
||||
const io = require('socket.io')(http);
|
||||
const convert = require('color-convert');
|
||||
|
||||
app.get('/', function (req, res) {
|
||||
res.sendFile(__dirname + '/client.html');
|
||||
});
|
||||
|
||||
function randomColor() {
|
||||
return '#' + convert.hsl.hex([randInt(0, 256), randInt(50, 200), 256]);
|
||||
}
|
||||
|
||||
function randInt(min, max) {
|
||||
return Math.floor(min + Math.random() * (max - min));
|
||||
}
|
||||
|
||||
function intersects(a1, a2, b1, b2) {
|
||||
let det, gamma, lambda;
|
||||
det = (a2.x - a1.x) * (b2.y - b1.y) - (b2.x - b1.x) * (a2.y - a1.y);
|
||||
if (det === 0) {
|
||||
return false;
|
||||
} else {
|
||||
lambda = ((b2.y - b1.y) * (b2.x - a1.x) + (b1.x - b2.x) * (b2.y - a1.y)) / det;
|
||||
gamma = ((a1.y - a2.y) * (b2.x - a1.x) + (a2.x - a1.x) * (b2.y - a1.y)) / det;
|
||||
return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1);
|
||||
}
|
||||
}
|
||||
|
||||
function dist(a1,a2){
|
||||
return Math.sqrt(Math.pow(a1.x-a2.x,2)+Math.pow(a1.y-a2.y,2));
|
||||
}
|
||||
|
||||
function clone(a){
|
||||
return {x:parseFloat(a.x),y:parseFloat(a.y)};
|
||||
}
|
||||
|
||||
const HSIZE = 300;
|
||||
const MAXX = 1600;
|
||||
const MAXY = 900;
|
||||
const SPD = 5;
|
||||
const MAX_ANGLE_SPEED = Math.PI / 32;
|
||||
|
||||
const players = {};
|
||||
const history = {};
|
||||
|
||||
let upc = 0;
|
||||
let ic = 0;
|
||||
|
||||
setInterval(function () {
|
||||
//main loop
|
||||
Object.keys(players).forEach(function (name) {
|
||||
const p = players[name];
|
||||
if (p.alive) {
|
||||
const lastpos = clone(p.pos);
|
||||
p.pos.x += SPD * Math.cos(p.angle);
|
||||
p.pos.y += SPD * Math.sin(p.angle);
|
||||
p.angle += p.angleSpd;
|
||||
let exempt = false;
|
||||
if (p.pos.x > MAXX){
|
||||
p.pos.x = 0;
|
||||
exempt = true;
|
||||
}
|
||||
if (p.pos.x < 0){
|
||||
p.pos.x = MAXX;
|
||||
exempt = true;
|
||||
}
|
||||
if (p.pos.y > MAXY){
|
||||
p.pos.y = 0;
|
||||
exempt = true;
|
||||
}
|
||||
if (p.pos.y < 0){
|
||||
p.pos.y = MAXY;
|
||||
exempt = true;
|
||||
}
|
||||
|
||||
if(p.starting <= 0){
|
||||
const h = history[name];
|
||||
h.i0 = (h.i0 + 1) % HSIZE;
|
||||
h.list[h.i0] = clone(p.pos);
|
||||
}
|
||||
|
||||
if(!exempt && p.starting <= 0){
|
||||
const ds = dist(lastpos,p.pos);
|
||||
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`);
|
||||
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`);
|
||||
|
||||
Object.keys(history).forEach(function (name2) {
|
||||
if (p.alive && name !== name2) {
|
||||
const h2 = history[name2];
|
||||
let lastpoint = h2.list[h2.i0];
|
||||
if(!lastpoint)
|
||||
return;
|
||||
for (let di = 1; di < HSIZE; di++) {
|
||||
const point = h2.list[(h2.i0 - di + HSIZE) % HSIZE];
|
||||
if (point !== undefined) {
|
||||
if(Math.abs(lastpoint.x - point.x) < 1600 * .9 && Math.abs(lastpoint.y - point.y) < 900 * .9){
|
||||
ic++;
|
||||
if (intersects(lastpos, p.pos, lastpoint, point)) {
|
||||
process.stdout.write(`\r${name} collided with ${name2}\n`);
|
||||
p.alive = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastpoint = point;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(p.starting > 0)
|
||||
p.starting -= 20;
|
||||
|
||||
}
|
||||
});
|
||||
io.emit('players', players);
|
||||
upc++;
|
||||
}, 20);
|
||||
|
||||
setInterval(function () {
|
||||
process.stdout.write(`\rtick ${20 * upc * 20 / 1000}/20 ms (${ic} intersect/s)`);
|
||||
upc = 0;
|
||||
ic = 0;
|
||||
}, 1000);
|
||||
|
||||
io.on('connection', function (socket) {
|
||||
socket.name = '#' + ('0000' + randInt(0, 10000)).slice(-4);
|
||||
process.stdout.write(`\r${socket.name} connected\n`);
|
||||
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
|
||||
};
|
||||
history[socket.name] = {
|
||||
i0: -1,
|
||||
list: new Array(HSIZE)
|
||||
};
|
||||
socket.emit('info', {
|
||||
self:players[socket.name],
|
||||
players:players,
|
||||
history:history,
|
||||
hsize:HSIZE
|
||||
});
|
||||
|
||||
socket.on('disconnect', function () {
|
||||
delete players[socket.name];
|
||||
delete history[socket.name];
|
||||
process.stdout.write(`\r${socket.name} disconnected\n`);
|
||||
io.emit('players', players);
|
||||
});
|
||||
socket.on('update', function (newp) {
|
||||
const p = players[newp.name];
|
||||
if (!p) {
|
||||
socket.disconnect();
|
||||
return;
|
||||
}
|
||||
if (!p.alive)
|
||||
return;
|
||||
if (newp.color === 'new')
|
||||
players[newp.name].color = randomColor();
|
||||
if (newp.angleSpd > 0)
|
||||
players[newp.name].angleSpd = MAX_ANGLE_SPEED;
|
||||
else if (newp.angleSpd < 0)
|
||||
players[newp.name].angleSpd = -MAX_ANGLE_SPEED;
|
||||
else
|
||||
players[newp.name].angleSpd = 0;
|
||||
});
|
||||
});
|
||||
|
||||
http.listen(3001, function () {
|
||||
console.log('listening on *:3001\n');
|
||||
});
|
||||
Reference in New Issue
Block a user