initial commit
This commit is contained in:
commit
7fb6a7cd73
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
server/node_modules/*
|
9
client/index.html
Normal file
9
client/index.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body onload="loaded = true">
|
||||||
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
|
<script src="js/client.js"></script>
|
||||||
|
<script src="js/canvas.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
216
client/js/canvas.js
Normal file
216
client/js/canvas.js
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
var canv = document.createElement("canvas");
|
||||||
|
const ww = window.innerWidth;
|
||||||
|
const wh = window.innerHeight;
|
||||||
|
const rc = ww > wh;
|
||||||
|
const cw = (rc) ? ww : wh;
|
||||||
|
const ch = (rc) ? wh : ww;
|
||||||
|
canv.width = ww;
|
||||||
|
canv.height = wh;
|
||||||
|
canv.style.position = "absolute";
|
||||||
|
canv.style.top = "0px";
|
||||||
|
canv.style.left = "0px";
|
||||||
|
var ctx = canv.getContext("2d");
|
||||||
|
document.body.appendChild(canv);
|
||||||
|
var mouse = {x: 0, y: 0};
|
||||||
|
document.addEventListener("mousemove", evt => {
|
||||||
|
var rect = canv.getBoundingClientRect();
|
||||||
|
mouse = {
|
||||||
|
x: evt.clientX - rect.left,
|
||||||
|
y: evt.clientY - rect.top
|
||||||
|
};
|
||||||
|
});
|
||||||
|
document.addEventListener("mousedown", () => {
|
||||||
|
const mx = (rc) ? mouse.x : mouse.y;
|
||||||
|
const my = (rc) ? mouse.y : mouse.x;
|
||||||
|
const LEFT = mx < cw * (1/3);
|
||||||
|
const RIGHT = mx > cw * (2/3);
|
||||||
|
const BOTTOM = my > ch * (2/3);
|
||||||
|
const TOP = my < ch * (1/3);
|
||||||
|
const copy = self.b;
|
||||||
|
if (LEFT && !BOTTOM && !TOP) {
|
||||||
|
//Left
|
||||||
|
addKeyCode(37);
|
||||||
|
} else if (RIGHT && !BOTTOM && !TOP) {
|
||||||
|
//Right
|
||||||
|
addKeyCode(39);
|
||||||
|
} else if (BOTTOM && !RIGHT && !LEFT) {
|
||||||
|
//Down
|
||||||
|
addKeyCode(38);
|
||||||
|
} else if (TOP && !RIGHT && !LEFT) {
|
||||||
|
//Up
|
||||||
|
addKeyCode(40);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.addEventListener("keydown",evt => {
|
||||||
|
addKeyCode(evt.keyCode);
|
||||||
|
});
|
||||||
|
function addKeyCode(kC) {
|
||||||
|
let isInB = false, isOpposite = false;
|
||||||
|
for (let i = 0; i < self.b.length; i++) {
|
||||||
|
const e = self.b[i];
|
||||||
|
if (e == kC) {
|
||||||
|
isInB = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Didn't get this to work, lol.
|
||||||
|
Instead just checked for opposite on line 54, 60, 66, 72.
|
||||||
|
|
||||||
|
if (e == kC-2 || e == kC+2) {
|
||||||
|
isOpposite = true;
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
if (!isOpposite && !isInB) {
|
||||||
|
self.b.push(kC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Snake {
|
||||||
|
constructor(px, py) {
|
||||||
|
this.x = px;
|
||||||
|
this.y = py;
|
||||||
|
this.h = {x: 0, y: 0};
|
||||||
|
this.l = 5;
|
||||||
|
this.t = Array();
|
||||||
|
this.b = [Math.floor(Math.random()*4+37)];
|
||||||
|
this.p = {x: 0, y: 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't want each socket.emit() to also sent update and show as method from Snake, so seperate functions it is.
|
||||||
|
}
|
||||||
|
|
||||||
|
const cells = 40, cwidth = ch/cells, fCL = 6;
|
||||||
|
let self = new Snake(Math.floor(cells/2), Math.floor(cells/2)), fC = 0;
|
||||||
|
for (let i = 0; i < self.l; i++) {
|
||||||
|
update(self, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(snake, ignore = false) {
|
||||||
|
if (fC%fCL == 0) {
|
||||||
|
const e = snake.b.splice(0,1)[0];
|
||||||
|
switch (e) {
|
||||||
|
case 37:
|
||||||
|
if (snake.h.x != 1) {
|
||||||
|
snake.h.x = -1;
|
||||||
|
snake.h.y = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
if (snake.h.y != 1) {
|
||||||
|
snake.h.x = 0;
|
||||||
|
snake.h.y = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
if (snake.h.x != -1) {
|
||||||
|
snake.h.x = 1;
|
||||||
|
snake.h.y = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
if (snake.h.y != -1) {
|
||||||
|
snake.h.x = 0;
|
||||||
|
snake.h.y = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
snake.t.push({x: snake.x, y: snake.y});
|
||||||
|
while (snake.t.length > snake.l) {
|
||||||
|
snake.p = snake.t.splice(0,1);
|
||||||
|
//snake.t.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
snake.x = (snake.x + snake.h.x + cells) % cells;
|
||||||
|
snake.y = (snake.y + snake.h.y + cells) % cells;
|
||||||
|
|
||||||
|
if (snake.x == food.x && snake.y == food.y) {
|
||||||
|
snake.l++;
|
||||||
|
socket.emit('snakeFoodUpdate');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < snake.t.length; i++) {
|
||||||
|
if (snake.t[i].x == snake.x && snake.t[i].y == snake.y) {
|
||||||
|
snake.l = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < players.length; i++) {
|
||||||
|
if (players[i].x == snake.x && players[i].y == snake.y) {
|
||||||
|
snake.l = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let broke = false;
|
||||||
|
for (let j = 0; j < players[i].t.length; j++) {
|
||||||
|
if (players[i].t[j].x == snake.x && players[i].t[j].y == snake.y) {
|
||||||
|
snake.l = 5;
|
||||||
|
broke = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (broke) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ignore) {
|
||||||
|
socket.emit('snakePlayerUpdate', {ownID: selfID, data: snake});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(snake) {
|
||||||
|
if (snake == self) {
|
||||||
|
ctx.fillStyle = "green";
|
||||||
|
ctx.strokeStyle = "green";
|
||||||
|
} else {
|
||||||
|
ctx.fillStyle = "blue";
|
||||||
|
ctx.strokeStyle = "blue";
|
||||||
|
}
|
||||||
|
const sx = (rc) ? snake.x : snake.y;
|
||||||
|
const sy = (rc) ? snake.y : snake.x;
|
||||||
|
ctx.fillRect(sx*cwidth+1, sy*cwidth+1, cwidth-2, cwidth-2);
|
||||||
|
|
||||||
|
if (snake == self) {
|
||||||
|
ctx.fillStyle = "lime";
|
||||||
|
ctx.strokeStyle = "lime";
|
||||||
|
} else {
|
||||||
|
ctx.fillStyle = "cyan";
|
||||||
|
ctx.strokeStyle = "cyan";
|
||||||
|
}
|
||||||
|
snake.t.forEach(e => {
|
||||||
|
const ex = (rc) ? e.x : e.y;
|
||||||
|
const ey = (rc) ? e.y : e.x;
|
||||||
|
ctx.fillRect(ex*cwidth+1, ey*cwidth+1, cwidth-2, cwidth-2);
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx.fillStyle = "red";
|
||||||
|
ctx.strokeStyle = "red";
|
||||||
|
const fx = (rc) ? food.x : food.y;
|
||||||
|
const fy = (rc) ? food.y : food.x;
|
||||||
|
ctx.fillRect(fx*cwidth+1, fy*cwidth+1, cwidth-2, cwidth-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var frames = 60, interv = setInterval(() => {
|
||||||
|
ctx.fillStyle = "grey";
|
||||||
|
ctx.fillRect(0,0,canv.width,canv.height);
|
||||||
|
if (selfID != -1 && loaded) {
|
||||||
|
var t = ctx.getTransform();
|
||||||
|
const nwidth = cw/2-ch/2;
|
||||||
|
if (rc) {
|
||||||
|
ctx.translate(nwidth, 0);
|
||||||
|
} else {
|
||||||
|
ctx.translate(0, nwidth);
|
||||||
|
}
|
||||||
|
ctx.fillStyle = "black";
|
||||||
|
ctx.fillRect(0, 0, ch, ch);
|
||||||
|
|
||||||
|
update(self);
|
||||||
|
show(self);
|
||||||
|
players.forEach(show);
|
||||||
|
|
||||||
|
ctx.setTransform(t);
|
||||||
|
fC = (fC+1001)%1000;
|
||||||
|
}
|
||||||
|
}, 1000/frames);
|
18
client/js/client.js
Normal file
18
client/js/client.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
const socket = io();
|
||||||
|
let selfID = -1, players = Array(), loaded = false, food = {x: -1, y: -1};
|
||||||
|
|
||||||
|
socket.on('connected', d => {
|
||||||
|
//console.log("Connected!");
|
||||||
|
players = d.pdata;
|
||||||
|
selfID = d.ownID;
|
||||||
|
food = d.food;
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('snakeUpdatePlayers', p => {
|
||||||
|
//console.log("Recieved "+ p.pdata.length +" players.");
|
||||||
|
players = Array();
|
||||||
|
p.pdata.forEach(e => {
|
||||||
|
players.push(e);
|
||||||
|
});
|
||||||
|
food = p.food;
|
||||||
|
});
|
4019
server/package-lock.json
generated
Normal file
4019
server/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
server/package.json
Normal file
22
server/package.json
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nodemon server.js",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.24.0",
|
||||||
|
"cheerio": "^1.0.0-rc.10",
|
||||||
|
"express": "^4.17.3",
|
||||||
|
"global-agent": "^3.0.0",
|
||||||
|
"nodemon": "^2.0.15",
|
||||||
|
"reddit-image-fetcher": "^2.0.10",
|
||||||
|
"reddit.images": "^1.0.7",
|
||||||
|
"socket.io": "^4.4.1"
|
||||||
|
}
|
||||||
|
}
|
86
server/server.js
Normal file
86
server/server.js
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
const port = 3000;
|
||||||
|
|
||||||
|
const http = require('http');
|
||||||
|
const express = require('express');
|
||||||
|
const socketio = require('socket.io');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const clientPath = __dirname+'/../client';
|
||||||
|
console.log('Serving static from ' + clientPath);
|
||||||
|
app.use(express.static(clientPath));
|
||||||
|
|
||||||
|
const server = http.createServer(app);
|
||||||
|
const io = socketio(server);
|
||||||
|
|
||||||
|
server.on('error', err => {
|
||||||
|
console.error('Server error:', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(port, () => {
|
||||||
|
console.log('Server Started on Port '+port);
|
||||||
|
});
|
||||||
|
|
||||||
|
const cells = 40;
|
||||||
|
let snakePlayers = Array(), snakeFood = {x: Math.floor(Math.random()*cells), y: Math.floor(Math.random()*cells)};
|
||||||
|
|
||||||
|
io.on('connection', socket => {
|
||||||
|
let id = -1;
|
||||||
|
|
||||||
|
console.log("New Player has connected.");
|
||||||
|
while (true) {
|
||||||
|
let current = Math.floor(Math.random()*89+10);
|
||||||
|
let isUsed = false;
|
||||||
|
for (let i = 0; i < snakePlayers.length; i++) {
|
||||||
|
if (snakePlayers[i].uid == current) {
|
||||||
|
isUsed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isUsed) {
|
||||||
|
id = current;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id != -1) {
|
||||||
|
console.log('Handing ID', id);
|
||||||
|
let temp = Array();
|
||||||
|
snakePlayers.forEach(p => {
|
||||||
|
if (p.data != null) {
|
||||||
|
temp.push(p.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.emit('connected', {pdata: temp, ownID: id, food: snakeFood});
|
||||||
|
snakePlayers.push({socket, ownID: id, data: null});
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
for (let i = 0; i < snakePlayers.length; i++) {
|
||||||
|
if (snakePlayers[i].socket == socket) {
|
||||||
|
console.log("Disconnecting SNAKEGAME User. ID", snakePlayers[i].ownID);
|
||||||
|
snakePlayers.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('snakeFoodUpdate', () => {
|
||||||
|
snakeFood = {x: Math.floor(Math.random()*cells), y: Math.floor(Math.random()*cells)};
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('snakePlayerUpdate', p => {
|
||||||
|
for (let i = 0; i < snakePlayers.length; i++) {
|
||||||
|
if (p.ownID == snakePlayers[i].ownID) {
|
||||||
|
snakePlayers[i].data = p.data;
|
||||||
|
let temp = Array();
|
||||||
|
snakePlayers.forEach(d => {
|
||||||
|
if (d.ownID != p.ownID && d.data != null) {
|
||||||
|
temp.push(d.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
snakePlayers[i].socket.emit('snakeUpdatePlayers', {pdata: temp, food: snakeFood});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user