mirror of
https://git.rezel.net/LudoTech/traque.git
synced 2026-02-09 10:20:16 +01:00
Merge branch 'main' of github.com:quentinrsl/traque
This commit is contained in:
@@ -11,6 +11,7 @@ export default class Game {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.teams = [];
|
this.teams = [];
|
||||||
this.state = GameState.SETUP;
|
this.state = GameState.SETUP;
|
||||||
|
this.zone = new ZoneManager(null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(newState) {
|
setState(newState) {
|
||||||
@@ -150,4 +151,12 @@ export default class Game {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setZone(newSettings) {
|
||||||
|
//cannot change zones while playing
|
||||||
|
if(game.state == GameState.PLAYING || game.state == GameState.FINISHED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.zone.udpateSettings(newSettings)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -95,6 +95,17 @@ io.of("admin").on("connection", (socket) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on("set_zone", (zone) => {
|
||||||
|
if (!loggedIn) {
|
||||||
|
socket.emit("error", "Not logged in");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!game.setZone(zone)) {
|
||||||
|
socket.emit("error", "Error changing zone");
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
//User is attempting to add a new team
|
//User is attempting to add a new team
|
||||||
socket.on("add_team", (teamName) => {
|
socket.on("add_team", (teamName) => {
|
||||||
if (!loggedIn) {
|
if (!loggedIn) {
|
||||||
|
|||||||
6
traque-back/package-lock.json
generated
6
traque-back/package-lock.json
generated
@@ -10,6 +10,7 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
"random-location": "^1.1.3",
|
||||||
"socket.io": "^4.7.5"
|
"socket.io": "^4.7.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -174,6 +175,11 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/random-location": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/random-location/-/random-location-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-+9SZa8R0JTfjrdgImCyq4TJRDzGHfUM9qghsA3D7zrMnUaQVn/xIDtFI+yPegJGO7KuIkduNlL8JXqu3M7Au7w=="
|
||||||
|
},
|
||||||
"node_modules/socket.io": {
|
"node_modules/socket.io": {
|
||||||
"version": "4.7.5",
|
"version": "4.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
"random-location": "^1.1.3",
|
||||||
"socket.io": "^4.7.5"
|
"socket.io": "^4.7.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
92
traque-back/zoneManager.js
Normal file
92
traque-back/zoneManager.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import randomLocation, { randomCirclePoint } from 'random-location'
|
||||||
|
import { isInCircle } from './map_utils';
|
||||||
|
|
||||||
|
class ZoneManager {
|
||||||
|
constructor(onZoneUpdate, onNextZoneUpdate) {
|
||||||
|
//Setings storing where the zone will start, end and how it should evolve
|
||||||
|
//The zone will start by staying at its mzx value for reductionInterval minutes
|
||||||
|
//and then reduce during reductionDuration minutes, then wait again...
|
||||||
|
//The reduction factor is such that after reductionCount the zone will be the min zone
|
||||||
|
//a call to onZoneUpdate will be made every updateIntervalSeconds when the zone is changing
|
||||||
|
//a call to onNextZoneUpdate will be made when the zone reduction ends and a new next zone is announced
|
||||||
|
this.zoneSettings = {
|
||||||
|
min: {center: null, radius: null},
|
||||||
|
max: {center: null, radius: null},
|
||||||
|
reductionCount: 2,
|
||||||
|
reductionDuration: 10,
|
||||||
|
reductionInterval: 10,
|
||||||
|
updateIntervalSeconds: 10,
|
||||||
|
}
|
||||||
|
this.shrinkFactor = null;
|
||||||
|
//Live location of the zone
|
||||||
|
this.currentZone = null;
|
||||||
|
this.currentDecrement = null;
|
||||||
|
|
||||||
|
//If the zone is shrinking, this is the target of the current shrinking
|
||||||
|
//If the zone is not shrinking, this will be the target of the next shrinking
|
||||||
|
this.nextZone = null;
|
||||||
|
|
||||||
|
this.startDate = null;
|
||||||
|
this.zoneSettings = zoneSettings;
|
||||||
|
this.started = false;
|
||||||
|
this.timeoutId = null;
|
||||||
|
|
||||||
|
this.onZoneUpdate = onZoneUpdate;
|
||||||
|
this.onNextZoneUpdate = onNextZoneUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
udpateSettings(newSettings) {
|
||||||
|
this.zoneSettings = {newSettings, ...this.zoneSettings};
|
||||||
|
this.shrinkFactor = Math.pow(this.zoneSettings.min.radius / this.zoneSettings.max.radius, 1/this.zoneSettings.reductionCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.currentZoneCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.started = true;
|
||||||
|
this.startDate = new Date();
|
||||||
|
requestAnimationFrame(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the center of the next zone, this center need to satisfy two properties
|
||||||
|
* - it needs to be included in the current zone, this means that this new point should lie in the circle of center currentZone.center and radius currentZone.radius - newRadius
|
||||||
|
* - it needs to include the last zone, which means that the center must lie in the center of center min.center and of radius newRadius - min.radius
|
||||||
|
* @param newRadius the radius that the new zone will have
|
||||||
|
* @returns the coordinates of the new center as an object with lat and long fields
|
||||||
|
*/
|
||||||
|
getRandomNextCenter(newRadius) {
|
||||||
|
let ok = false;
|
||||||
|
let res = null
|
||||||
|
while(!ok) {
|
||||||
|
res = randomCirclePoint({latitude: this.currentZone.lat, longitude: this.currentZone.long}, this.currentZone.radius - newRadius);
|
||||||
|
ok = (isInCircle({lat: res.latitude, long: res.longitude}, this.zoneSettings.min.center, newRadius - this.zoneSettings.min.radius))
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
lat: res.latitude,
|
||||||
|
long: res.longitude
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setNextZone() {
|
||||||
|
//At this point, nextZone == currentZone, we need to update the next zone, the raidus decrement, and start a timer before the next shrink
|
||||||
|
|
||||||
|
//last zone
|
||||||
|
if(this.currentZoneCount == this.zoneSettings.currentZoneCount - 1) {
|
||||||
|
//Copy values
|
||||||
|
this.nextZone = {center: [...this.zoneSettings.min.center],...this.zoneSettings.min}
|
||||||
|
}else {
|
||||||
|
//TODO : compute next zone
|
||||||
|
this.nextZone.center = this.getRandomNextCenter(this.nextZone.radius * this.shrinkFactor)
|
||||||
|
this.nextZone.radius *= this.shrinkFactor;
|
||||||
|
this.timeoutId = setTimeout(() => this.startShrinking(), 1000 * 60 * this.zoneSettings.reductionIntervalMinutes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startShrinking() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user