Change gameplay
This commit is contained in:
parent
d79900e3ea
commit
34dae300da
56 changed files with 906 additions and 400 deletions
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue