updated
This commit is contained in:
7
API/games/circle.js
Normal file
7
API/games/circle.js
Normal 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
32
API/games/vector.js
Normal 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
195
API/games/volleyball.js
Normal 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]);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
109
API/index.js
109
API/index.js
@@ -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
6295
API/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -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": {
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -8,6 +8,9 @@ let Room = new Schema({
|
||||
},
|
||||
members: {
|
||||
type: Array
|
||||
},
|
||||
game: {
|
||||
type: String
|
||||
}
|
||||
}, {
|
||||
collection: 'rooms'
|
||||
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user