This commit is contained in:
Johnathon Slightham
2021-09-07 12:53:34 -04:00
parent 57b9827e64
commit 71017cc5b6
34 changed files with 27214 additions and 2626 deletions

7
API/games/circle.js Normal file
View File

@@ -0,0 +1,7 @@
exports.newCircle = function(center, radius, velocity) {
return {
center: center,
radius: radius,
velocity: velocity
}
}

32
API/games/vector.js Normal file
View File

@@ -0,0 +1,32 @@
exports.createVector = function(x, y) {
return {x: x, y: y};
}
exports.mag = function(v){
return Math.sqrt(exports.dot(v, v));
}
exports.add = function(v1, v2){
return {x:v1.x + v2.x, y:v1.y + v2.y};
}
exports.sub = function(v1, v2){
return {x: v1.x - v2.x, y:v1.y - v2.y};
}
exports.dot = function(v1, v2){
return v1.x*v2.x + v1.y*v2.y;
}
exports.mult = function(v1, k){
return {x: v1.x*k, y:v1.y*k};
}
exports.reflect = function(v1, n){
return exports.sub(exports.mult(exports.project(v1, n), 2), v1);
}
exports.project = function(v1, v2){
return exports.mult(v2, (1/Math.pow(exports.mag(v2), 2)) * exports.dot(v1, v2));
}

195
API/games/volleyball.js Normal file
View File

@@ -0,0 +1,195 @@
//import * as posenet from "@tensorflow-models/posenet";
let posenet = require("@tensorflow-models/posenet");
//var circle = require("./circle")
let vec = require("./vector");
var collide = require('line-circle-collision');
let prevTime = 0;
exports.process = function(game, players) {
if (Object.keys(game.data).length == 0) {
initialize(game);
}
let timeElapsed = Date.now() - prevTime;
prevTime = Date.now();
collideAll(game.data.objects, players);
moveItems(game.data.objects, timeElapsed);
}
function initialize(game){
prevTime = Date.now();
game.data = {
objects: []
}
for (let i = 0; i < 50; i++){
game.data.objects.push({
name: "circle",
position: vec.createVector(20*i, -100),
radius: 20,
velocity: vec.createVector(0, 0)
})
}
}
function moveItems(objects, timeElapsed) {
let acceleration = vec.createVector(0, 0.0002);
for (let i = 0; i < objects.length; i++){
objects[i].velocity = vec.add(objects[i].velocity, vec.mult(acceleration, timeElapsed))
objects[i].position = vec.add(objects[i].position, vec.mult(objects[i].velocity, timeElapsed))
if (objects[i].position.y > 500 && objects[i].velocity.y > 0) {
objects[i].velocity.y *= -1;
}
// if (objects[i].position.x < 0 && objects[i].velocity.x < 0) {
// objects[i].velocity.x *= -1;
// }
// if (objects[i].position.x > 1000 && objects[i].velocity.x > 0) {
// objects[i].velocity.x *= -1;
// }
}
}
function collideWithJoint(object, [start, end]){
let diff = vec.sub(end, start);
object.velocity = vec.mult(vec.reflect(object.velocity, {x:-diff.y, y:diff.x}), -1);
object.position = vec.add(object.position, vec.mult(object.velocity, 3));
}
/*
function pointInCircle(x1, y1, cx, cy, cr){
let distance = (x1-cx)*(x1-cx)+(y1-cy)*(y1-cy);
distance = Math.sqrt(distance);
return distance <= cr;
}
*/
function pointOnLine(point, start, end){
if (point.x < start.x && point.x > end.x || point.x > start.x && point.x < end.x){
if (point.y > start.y && point.y < end.y || point.y > end.y && point.y < start.y){
return true;
}
}
// if (vec.mag(vec.sub(point, start)) > vec.mag(vec.sub(end, start))) {
// return false;
// }
// if (vec.mag(vec.sub(point, end)) > vec.mag(vec.sub(start, end))) {
// return false;
// }
return false;
}
// is either end INSIDE the circle?
// if so, return true immediately
function overlappingWithJoint(object, start, end){
// let cx = object.position.x;
// let cy = object.position.y;
// let r = object.radius;
// let x1 = start.x;
// let y1 = start.y;
// let x2 = end.x;
// let y2 = end.y;
// let inside1 = pointCircle(x1,y1, cx,cy,r);
// let inside2 = pointCircle(x2,y2, cx,cy,r);
// if (inside1 || inside2) return true;
// // get length of the line
// let distX = x1 - x2;
// let distY = y1 - y2;
// let len = Math.sqrt( (distX*distX) + (distY*distY) );
// // get dot product of the line and circle
// let dot = ( ((cx-x1)*(x2-x1)) + ((cy-y1)*(y2-y1)) ) / Math.pow(len,2);
// // find the closest point on the line
// let closestX = x1 + (dot * (x2-x1));
// let closestY = y1 + (dot * (y2-y1));
// // is this point actually on the line segment?
// // if so keep going, but if not, return false
// let onSegment = linePoint(x1,y1,x2,y2, closestX,closestY);
// if (!onSegment) return false;
// // optionally, draw a circle at the closest
// // point on the line
// // fill(255,0,0);
// // noStroke();
// // ellipse(closestX, closestY, 20, 20);
// // get distance to closest point
// distX = closestX - cx;
// distY = closestY - cy;
// let distance = Math.sqrt( (distX*distX) + (distY*distY) );
// if (distance <= r) {
// return true;
// }
// return false;
// let pos = object.position;
// // if (pointInCircle(end.x, end.y, pos.x, pos.y, object.radius)){
// // return true;
// // }
// // if (pointInCircle(start.x, start.y, pos.x, pos.y, object.radius)){
// // return true;
// // }
// let diff = vec.sub(end, start);
// let len = vec.mag(diff);
// let proj = vec.project(vec.sub(end, pos), diff);
// let point = vec.sub(end, proj);
// console.log("diff: ")
// console.log(diff)
// console.log("proj")
// console.log(proj)
// console.log("new")
// //console.log(point);
// if (!pointOnLine(point, start, end)){
// return false;
// }
// //let dist = Math.sqrt(Math.pow(vec.mag(vec.sub(end, pos))) - Math.pow(vec.mag(proj)))
// let dist = vec.mag(vec.sub(point, pos));
// return dist <= object.radius;
// //console.log("overlapping detected");
// // let diff = vec.sub(end, start);
// // let pos = object.position;
// // let diff2 = vec.sub(end, pos);
// // let r = vec.project(diff2, diff);
// // let dist = Math.sqrt(vec.dot(pos, pos) + vec.dot(r, r));
// // let midPoint = vec.mult(vec.add(start, end), 0.5);
// // return Math.abs(dist) <= object.radius;
return collide([start.x, start.y], [end.x, end.y], [object.position.x, object.position.y], object.radius);
}
function collideAll(objects, players){
let minConfidence = 0.5;
if (playes){
players.forEach(player => {
if (player.universePairs){
console.log("sdfsdfg");
player.universePairs.forEach(pair => {
let start = vec.createVector(pair.x1, pair.y1);
let end = vec.createVector(pair.x2, pair.y2);
for (let i = 0; i < objects.length; i++){
let object = objects[i];
if (overlappingWithJoint(object, start, end)){
collideWithJoint(object, [start, end]);
}
}
})
}
})
}
}

View File

@@ -2,41 +2,114 @@ const express = require('express');
const app = express();
const webSockets = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
var fs = require('fs');
var http = require('http');
var https = require('https');
const WebSocket = require('ws');
const mongoose = require('mongoose');
const socket = require('socket.io');
const config = require('./DB.js');
const roomRoute = require('./room.route');
var expressWs = require('express-ws')(app);
// DB credentials
const config = require('./DB.js');
// Routes
const roomRoute = require('./room.route');
// All active rooms, store in map since faster than DB
var rooms = new Map();
// For SSL Connection
var privateKey = fs.readFileSync('/etc/letsencrypt/live/dance.cubehostingmc.com/privkey.pem', 'utf8');
var certificate = fs.readFileSync('/etc/letsencrypt/live/dance.cubehostingmc.com/fullchain.pem', 'utf8');
var credentials = {key: privateKey, cert: certificate};
// DB connection
mongoose.Promise = global.Promise;
mongoose.connect(config.DB, { useNewUrlParser: true }).then(
() => { console.log('Database is connected') },
err => { console.log('Can not connect to the database' + err) }
);
// Express config
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/rooms', roomRoute);
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
app.listen(PORT, function () {
console.log('Express server running on port:', PORT);
})
//games
//import * as volleyball from 'games/volleyball.mjs';
app.ws('/:id', function (ws, req) {
var volleyball = require('./games/volleyball');
ws.on('message', function (msg) {
msgJ = JSON.parse(msg);
console.log(req.params.id);
console.log(msgJ.playerId);
ws.send(msg);
// Websocket config
const wss = new WebSocket.Server({ server: httpsServer }); // Use SSL Server
// On WebSocket Connection
wss.on('connection', function connection(ws) {
// On Message Recieve
ws.on('message', function incoming(message) {
let msgJson = JSON.parse(message); // Convert text to JSON
// Process Player Positions
if (rooms.has(msgJson.roomId)) { // Check if the room already exists in the map
// Process Game Data
//TODO: implement a generic way to have the gameData sent to the right file
if (msgJson.game.name == "0"){
//console.log(msgJson.playerArr);
volleyball.process(rooms.get(msgJson.roomId).game, msgJson.playerArr);
}
let changed = false; // To see if the player already exists in the arena
for (let i = 0; i < rooms.get(msgJson.roomId).playerArr.length; i++) {
// Update existing player positions
if (rooms.get(msgJson.roomId).playerArr[i].playerId == msgJson.playerArr[0].playerId) {
//console.log(msgJson.name);
let newRoom = rooms.get(msgJson.roomId);
newRoom.playerArr[i] = msgJson.playerArr[0];
newRoom.playerArr[i].colour = msgJson.colour;
newRoom.playerArr[i].name = msgJson.name;
rooms.set(msgJson.roomId, newRoom);
changed = true;
}
}
// Create new player positions
if(!changed) {
let newRoom = rooms.get(msgJson.roomId);
newRoom.playerArr.push(msgJson.playerArr[0]);
newRoom.playerArr[newRoom.playerArr.length-1].session = ws.sessionIdContext; // Required for handling socket closing
newRoom.playerArr[newRoom.playerArr.length-1].colour = msgJson.colour;
newRoom.playerArr[newRoom.playerArr.length-1].name = msgJson.name;
rooms.set(msgJson.roomId, newRoom);
}
} else {
msgJson.game.data = {};
rooms.set(msgJson.roomId, msgJson); // Create the room
}
ws.send(JSON.stringify(rooms.get(msgJson.roomId))); // Send the updated room data
});
// On websocket close
ws.onclose = function (event) {
console.log("Client disconnected from: " + req.params.id);
console.log("Client disconnected");
// Go through each existing room entry to find the websocket with the session that was closed with
for (const [key, value] of rooms.entries()) {
for (let i = 0; i < value.playerArr.length; i++){
if (value.playerArr[i].session == ws.sessionIdContext) {
newRoom = value;
newRoom.playerArr.splice(i); // Remove player with index i
rooms.set(key, newRoom);
}
// TODO: Add code to remove the room from both DB and Map if
}
}
};
console.log("Client connected to: " + req.params.id);
});
});
// Host both an http and https server
httpServer.listen(4001);
httpsServer.listen(4000);

6295
API/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,10 @@
"cors": "^2.8.5",
"express": "^4.17.1",
"express-ws": "^4.0.0",
"line-circle-collision": "^1.1.3",
"mongoose": "^5.11.17",
"node-p5": "^1.0.3",
"p5": "^1.2.0",
"socket.io": "^3.1.1"
},
"devDependencies": {

View File

@@ -5,6 +5,15 @@ const Schema = mongoose.Schema;
let Player = new Schema({
name: {
type: String
},
session: {
type: String
},
colour: {
type: Number
},
score: {
type: Number
}
}, {
collection: 'players'

View File

@@ -8,6 +8,9 @@ let Room = new Schema({
},
members: {
type: Array
},
game: {
type: String
}
}, {
collection: 'rooms'

View File

@@ -8,12 +8,15 @@ let Player = require('./player.model');
postRoutes.route('/add').get(function (req, res) {
let r = new Room();
let p = new Player();
p.colour = Math.trunc(Math.random()*8);
p.score = 0;
r.members.push(p);
r.save()
.then(() => {
let ret = {};
ret._id = r._id;
ret.playerId = p._id;
ret.colour = p.colour;
res.send(ret);
console.log("Created Room");
})
@@ -31,39 +34,26 @@ postRoutes.route('/join').post(function (req, res) {
res.json(err);
console.log("Error Joining Room");
} else {
let p = new Player();
r.members.push(p);
r.save().then(() => {
res.send(p);
console.log("Joined Room");
console.log(r.members);
}).catch(() => {
console.log("Unable to save to db");
res.status(400).send("Unable to save to the database")
})
if (r) {
let p = new Player();
p.colour = Math.trunc(Math.random()*8);
p.score = 0;
r.members.push(p);
r.save().then(() => {
res.send(p);
console.log(p);
console.log("Joined Room");
console.log(r.members);
}).catch(() => {
console.log("Unable to save to db");
res.status(400).send("Unable to save to the database")
})
} else {
res.send(null);
}
}
})
});
// Defined get data(index or listing) route
postRoutes.route('/').get(function (req, res) {
Post.find(function (err, posts) {
if (err) {
res.json(err);
}
else {
res.json(posts);
}
});
});
// Defined delete | remove | destroy route
postRoutes.route('/delete/:id').delete(function (req, res) {
Post.findByIdAndRemove({ _id: req.params.id }, function (err) {
if (err) res.json(err);
else res.json('Successfully removed');
});
});
module.exports = postRoutes;