Change gameplay

This commit is contained in:
schmelczerandras 2020-10-24 22:24:27 +02:00
parent d79900e3ea
commit 34dae300da
56 changed files with 906 additions and 400 deletions

View file

@ -6,6 +6,12 @@ import {
settings,
ServerInformation,
PlayerInformation,
serializable,
UpdateGameState,
serialize,
CharacterTeam,
GameEnd,
GameStart,
} from 'shared';
import { createWorld } from './map/create-world';
import { DeltaTimeCalculator } from './helper/delta-time-calculator';
@ -15,22 +21,40 @@ import { PlayerContainer } from './players/player-container';
const playerCountSubscribedRoom = 'playerCountUpdates';
export class GameServer {
private objects = new PhysicalContainer();
private players: PlayerContainer;
private deltaTimes: Array<number> = [];
private deltaTimeCalculator = new DeltaTimeCalculator();
private objects!: PhysicalContainer;
private players!: PlayerContainer;
private deltaTimes!: Array<number>;
private deltaTimeCalculator!: DeltaTimeCalculator;
private declaPoints = 0;
private redPoints = 0;
private isInEndGame = false;
private timeScaling = 1;
private serverName: string;
private playerLimit: number;
constructor(private readonly io: ioserver.Server, options: Options) {
private initialize() {
const previousPlayers = this.players;
this.objects = new PhysicalContainer();
this.players = new PlayerContainer(this.objects);
this.deltaTimeCalculator = new DeltaTimeCalculator();
this.deltaTimes = [];
this.declaPoints = 0;
this.redPoints = 0;
this.isInEndGame = false;
this.timeScaling = 1;
createWorld(this.objects, this.options.worldSize);
this.objects.initialize();
previousPlayers?.sendOnSocket(serialize(new GameStart()));
}
constructor(private readonly io: ioserver.Server, private options: Options) {
this.serverName = options.name;
this.playerLimit = options.playerLimit;
createWorld(this.objects, options.worldSize);
this.objects.initialize();
this.initialize();
io.on('connection', (socket: SocketIO.Socket) => {
socket.on(TransportEvents.PlayerJoining, (playerInfo: PlayerInformation) => {
@ -40,33 +64,61 @@ export class GameServer {
player.sendCommand(command);
});
this.sendPlayerCountUpdate();
this.sendServerStateUpdate();
socket.on('disconnect', () => {
player.destroy();
this.players.deletePlayer(player);
this.sendPlayerCountUpdate();
this.sendServerStateUpdate();
});
});
socket.on(TransportEvents.SubscribeForPlayerCount, () => {
socket.on(TransportEvents.SubscribeForServerInfoUpdates, () => {
socket.join(playerCountSubscribedRoom);
});
});
}
public sendPlayerCountUpdate() {
private timeSinceLastServerStateUpdate = 0;
public sendServerStateUpdate() {
this.io
.to(playerCountSubscribedRoom)
.emit(TransportEvents.PlayerCountUpdate, this.players.count);
.emit(TransportEvents.ServerInfoUpdate, [this.players.count, this.gameProgress]);
}
public start() {
this.handlePhysics();
}
private updatePoints() {
if (this.isInEndGame) {
return;
}
const { decla, red } = this.objects.getPointsGenerated();
this.declaPoints += decla;
this.redPoints += red;
if (this.declaPoints >= this.options.scoreLimit) {
this.endGame(CharacterTeam.decla);
} else if (this.redPoints >= this.options.scoreLimit) {
this.endGame(CharacterTeam.red);
}
}
private endGame(winningTeam: CharacterTeam) {
this.isInEndGame = true;
const endTitleLength = 6000;
this.players.sendOnSocket(
serialize(new GameEnd(winningTeam, endTitleLength / 1000, true)),
);
setTimeout(() => this.destroy(), endTitleLength * 1.1);
}
private destroy() {
this.initialize();
}
private handlePhysics() {
const delta = this.deltaTimeCalculator.getNextDeltaTimeInSeconds();
let delta = this.deltaTimeCalculator.getNextDeltaTimeInSeconds();
const framesBetweenDeltaTimeCalculation = 1000;
if (this.deltaTimes.length > framesBetweenDeltaTimeCalculation) {
@ -82,8 +134,25 @@ export class GameServer {
this.deltaTimes = [];
}
if ((this.timeSinceLastServerStateUpdate += delta) > 5) {
this.timeSinceLastServerStateUpdate = 0;
this.sendServerStateUpdate();
}
if (this.isInEndGame) {
this.timeScaling *= Math.pow(settings.endGameDeltaScaling, delta);
delta /= this.timeScaling;
}
this.objects.stepObjects(delta);
this.updatePoints();
this.players.sendOnSocket(
serialize(
new UpdateGameState(this.declaPoints, this.redPoints, this.options.scoreLimit),
),
);
this.players.step(delta);
this.objects.resetRemoteCalls();
const physicsDelta = this.deltaTimeCalculator.getDeltaTimeInSeconds() * 1000;
this.deltaTimes.push(physicsDelta);
@ -96,11 +165,16 @@ export class GameServer {
}
}
private get gameProgress(): number {
return (Math.max(this.declaPoints, this.redPoints) / this.options.scoreLimit) * 100;
}
public get serverInfo(): ServerInformation {
return {
serverName: this.serverName,
playerCount: this.players.count,
playerLimit: this.playerLimit,
gameStatePercent: this.gameProgress,
};
}
}