Wip fetch() from gameServer to nestServer
+ miscs (html, css, svelte warning, ...)
This commit is contained in:
@@ -17,6 +17,8 @@ export class Client {
|
||||
}
|
||||
|
||||
export class ClientPlayer extends Client {
|
||||
token: string;
|
||||
username: string;
|
||||
matchOptions: en.MatchOptions = 0;
|
||||
inputBuffer: ev.EventInput = new ev.EventInput();
|
||||
lastInputId: number = 0;
|
||||
|
||||
@@ -24,15 +24,18 @@ export class GameSession {
|
||||
spectatorsUpdateInterval: NodeJS.Timer | number = 0;
|
||||
components: GameComponentsServer;
|
||||
matchOptions: en.MatchOptions;
|
||||
isPrivateMatch: boolean; // WIP: could be used to separate leaderboards for example.
|
||||
matchEnded: boolean = false;
|
||||
lastStateSnapshot: ev.EventGameUpdate;
|
||||
|
||||
actual_time: number;
|
||||
last_time: number;
|
||||
delta_time: number;
|
||||
|
||||
constructor(id: string, matchOptions: en.MatchOptions) {
|
||||
constructor(id: string, matchOptions: en.MatchOptions, isPrivateMatch: boolean = false) {
|
||||
this.id = id;
|
||||
this.matchOptions = matchOptions;
|
||||
this.isPrivateMatch = isPrivateMatch;
|
||||
this.components = new GameComponentsServer(this.matchOptions);
|
||||
}
|
||||
start() {
|
||||
@@ -51,6 +54,7 @@ export class GameSession {
|
||||
});
|
||||
|
||||
s.actual_time = Date.now();
|
||||
s.lastStateSnapshot = s._gameStateSnapshot();
|
||||
s.gameLoopInterval = setInterval(s._gameLoop, c.serverGameLoopIntervalMS, s);
|
||||
s.playersUpdateInterval = setInterval(s._playersUpdate, c.playersUpdateIntervalMS, s);
|
||||
s.spectatorsUpdateInterval = setInterval(s._spectatorsUpdate, c.spectatorsUpdateIntervalMS, s);
|
||||
@@ -139,16 +143,16 @@ export class GameSession {
|
||||
});
|
||||
}
|
||||
private _playersUpdate(s: GameSession) {
|
||||
const gameState: ev.EventGameUpdate = s._gameStateSnapshot();
|
||||
s.lastStateSnapshot = s._gameStateSnapshot();
|
||||
s.playersMap.forEach( (client) => {
|
||||
gameState.lastInputId = client.lastInputId;
|
||||
client.socket.send(JSON.stringify(gameState));
|
||||
s.lastStateSnapshot.lastInputId = client.lastInputId;
|
||||
client.socket.send(JSON.stringify(s.lastStateSnapshot));
|
||||
});
|
||||
}
|
||||
private _spectatorsUpdate(s: GameSession) {
|
||||
const gameState = s._gameStateSnapshot();
|
||||
s.lastStateSnapshot.lastInputId = 0;
|
||||
s.spectatorsMap.forEach( (client) => {
|
||||
client.socket.send(JSON.stringify(gameState));
|
||||
client.socket.send(JSON.stringify(s.lastStateSnapshot));
|
||||
});
|
||||
}
|
||||
private _gameStateSnapshot() : ev.EventGameUpdate {
|
||||
@@ -182,7 +186,12 @@ export class GameSession {
|
||||
{
|
||||
if (Math.abs(gc.scoreLeft - gc.scoreRight) >= 2)
|
||||
{
|
||||
s._matchEnd(s);
|
||||
if (gc.scoreLeft > gc.scoreRight) {
|
||||
s._matchEnd(en.PlayerSide.left);
|
||||
}
|
||||
else {
|
||||
s._matchEnd(en.PlayerSide.right);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -197,45 +206,54 @@ export class GameSession {
|
||||
this.matchEnded = true;
|
||||
if (this.playersMap.size != 0)
|
||||
{
|
||||
console.log("Forfeit Ending");
|
||||
const gc = this.components;
|
||||
const luckyWinner: ClientPlayer = this.playersMap.values().next().value;
|
||||
let eventEnd: ev.EventMatchEnd;
|
||||
if (luckyWinner.racket === gc.playerLeft) {
|
||||
eventEnd = new ev.EventMatchEnd(en.PlayerSide.left, true);
|
||||
console.log("Player Left WIN (by forfeit)");
|
||||
this._matchEnd(en.PlayerSide.left, true);
|
||||
}
|
||||
else {
|
||||
eventEnd = new ev.EventMatchEnd(en.PlayerSide.right, true);
|
||||
console.log("Player Right WIN (by forfeit)");
|
||||
this._matchEnd(en.PlayerSide.right, true);
|
||||
}
|
||||
luckyWinner.socket.send(JSON.stringify(eventEnd));
|
||||
this.spectatorsMap.forEach( (client) => {
|
||||
client.socket.send(JSON.stringify(eventEnd));
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private _matchEnd(s: GameSession) {
|
||||
s.matchEnded = true;
|
||||
const gc = s.components;
|
||||
|
||||
private async _matchEnd(winner: en.PlayerSide, forfeit_flag: boolean = false)
|
||||
{
|
||||
this.matchEnded = true;
|
||||
let eventEnd: ev.EventMatchEnd;
|
||||
if (gc.scoreLeft > gc.scoreRight) {
|
||||
eventEnd = new ev.EventMatchEnd(en.PlayerSide.left);
|
||||
eventEnd = new ev.EventMatchEnd(winner, forfeit_flag);
|
||||
this.playersMap.forEach( (client) => {
|
||||
client.socket.send(JSON.stringify(eventEnd));
|
||||
});
|
||||
this.spectatorsMap.forEach( (client) => {
|
||||
client.socket.send(JSON.stringify(eventEnd));
|
||||
});
|
||||
|
||||
/* // WIP nest , send match result
|
||||
const gc = this.components;
|
||||
await fetch(c.addressBackEnd + "/game/matchEnd",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: this.id,
|
||||
scoreLeft: gc.scoreLeft,
|
||||
scoreRight: gc.scoreRight,
|
||||
isPrivateMatch: this.isPrivateMatch,
|
||||
})
|
||||
}); */
|
||||
|
||||
// logs
|
||||
if (winner === en.PlayerSide.left) {
|
||||
console.log("Player Left WIN");
|
||||
}
|
||||
else {
|
||||
eventEnd = new ev.EventMatchEnd(en.PlayerSide.right);
|
||||
console.log("Player Right WIN");
|
||||
}
|
||||
|
||||
s.playersMap.forEach( (client) => {
|
||||
client.socket.send(JSON.stringify(eventEnd));
|
||||
});
|
||||
s.spectatorsMap.forEach( (client) => {
|
||||
client.socket.send(JSON.stringify(eventEnd));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,3 +8,5 @@ export const fixedDeltaTime = serverGameLoopIntervalMS/1000; // second
|
||||
// 33.333ms == 1000/30
|
||||
export const playersUpdateIntervalMS = 1000/30; // millisecond
|
||||
export const spectatorsUpdateIntervalMS = 1000/30; // millisecond
|
||||
|
||||
export const addressBackEnd = "http://backend_dev:3000";
|
||||
|
||||
@@ -10,16 +10,17 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import * as en from "../shared_js/enums.js"
|
||||
import * as ev from "../shared_js/class/Event.js"
|
||||
import * as c from "./constants.js"
|
||||
import { Client, ClientPlayer, ClientSpectator } from "./class/Client.js"
|
||||
import { GameSession } from "./class/GameSession.js"
|
||||
import { shortId } from "./utils.js";
|
||||
import { gameSessionIdPLACEHOLDER } from "./constants.js";
|
||||
|
||||
// pas indispensable d'avoir un autre port si le WebSocket est relié à un serveur http préexistant ?
|
||||
const wsPort = 8042;
|
||||
export const wsServer = new WebSocketServer<WebSocket>({host: "0.0.0.0", port: wsPort, path: "/pong"});
|
||||
const clientsMap: Map<string, Client> = new Map; // socket.id/Client
|
||||
const matchmakingPlayersMap: Map<string, ClientPlayer> = new Map; // socket.id/ClientPlayer (duplicates with clientsMap)
|
||||
const matchmakingPlayersMap: Map<string, ClientPlayer> = new Map; // socket.id/ClientPlayer (duplicates with clientsMap) // TODO: rename in matchmakingMap
|
||||
const privateMatchmakingMap: Map<string, ClientPlayer> = new Map; // socket.id/ClientPlayer (duplicates with clientsMap)
|
||||
const gameSessionsMap: Map<string, GameSession> = new Map; // GameSession.id(url)/GameSession
|
||||
|
||||
wsServer.on("connection", connectionListener);
|
||||
@@ -54,7 +55,7 @@ function connectionListener(socket: WebSocket, request: IncomingMessage)
|
||||
}
|
||||
|
||||
|
||||
function clientAnnounceListener(this: WebSocket, data: string)
|
||||
async function clientAnnounceListener(this: WebSocket, data: string)
|
||||
{
|
||||
try {
|
||||
const msg : ev.ClientAnnounce = JSON.parse(data);
|
||||
@@ -65,11 +66,44 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
||||
if (msg.role === en.ClientRole.player)
|
||||
{
|
||||
const announce: ev.ClientAnnouncePlayer = <ev.ClientAnnouncePlayer>msg;
|
||||
|
||||
/* // WIP nest, fetch token validation
|
||||
const response = await fetch(c.addressBackEnd + "/game/validateToken",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
token: announce.token,
|
||||
username: announce.username,
|
||||
})
|
||||
});
|
||||
switch (response.status)
|
||||
{
|
||||
case 200:
|
||||
case 204:
|
||||
break;
|
||||
case 403:
|
||||
default:
|
||||
// send message to client ? or just gtfo ?
|
||||
clientTerminate(clientsMap.get(this.id));
|
||||
return;
|
||||
} */
|
||||
|
||||
const player = clientsMap.get(this.id) as ClientPlayer;
|
||||
player.matchOptions = announce.matchOptions;
|
||||
player.token = announce.token;
|
||||
player.username = announce.username;
|
||||
|
||||
this.send(JSON.stringify( new ev.EventAssignId(this.id) ));
|
||||
this.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchmakingInProgress) ));
|
||||
matchmaking(player);
|
||||
if (announce.privateMatch) {
|
||||
privateMatchmaking(player);
|
||||
}
|
||||
else {
|
||||
publicMatchmaking(player);
|
||||
}
|
||||
}
|
||||
else if (msg.role === en.ClientRole.spectator)
|
||||
{
|
||||
@@ -77,6 +111,7 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
||||
const gameSession = gameSessionsMap.get(announce.gameSessionId);
|
||||
if (!gameSession) {
|
||||
// WIP: send "invalid game session"
|
||||
clientTerminate(clientsMap.get(this.id));
|
||||
return;
|
||||
}
|
||||
const spectator = clientsMap.get(this.id) as ClientSpectator;
|
||||
@@ -97,12 +132,12 @@ function clientAnnounceListener(this: WebSocket, data: string)
|
||||
}
|
||||
|
||||
|
||||
function matchmaking(player: ClientPlayer)
|
||||
function publicMatchmaking(player: ClientPlayer)
|
||||
{
|
||||
const minPlayersNumber = 2;
|
||||
const maxPlayersNumber = 2;
|
||||
const matchOptions = player.matchOptions;
|
||||
matchmakingPlayersMap.set(player.id, player);
|
||||
const matchOptions = player.matchOptions;
|
||||
|
||||
const compatiblePlayers: ClientPlayer[] = [];
|
||||
for (const [id, client] of matchmakingPlayersMap)
|
||||
@@ -116,17 +151,52 @@ function matchmaking(player: ClientPlayer)
|
||||
}
|
||||
}
|
||||
|
||||
if (compatiblePlayers.length < minPlayersNumber) {
|
||||
return;
|
||||
if (compatiblePlayers.length >= minPlayersNumber) {
|
||||
compatiblePlayers.forEach((client) => {
|
||||
matchmakingPlayersMap.delete(client.id);
|
||||
});
|
||||
createGameSession(compatiblePlayers, matchOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function privateMatchmaking(player: ClientPlayer)
|
||||
{
|
||||
const minPlayersNumber = 2;
|
||||
const maxPlayersNumber = 2;
|
||||
privateMatchmakingMap.set(player.id, player);
|
||||
const matchOptions = player.matchOptions;
|
||||
|
||||
const token = player.token;
|
||||
const compatiblePlayers: ClientPlayer[] = [];
|
||||
for (const [id, client] of privateMatchmakingMap)
|
||||
{
|
||||
if (client.token === token)
|
||||
{
|
||||
compatiblePlayers.push(client);
|
||||
if (compatiblePlayers.length === maxPlayersNumber) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (compatiblePlayers.length >= minPlayersNumber) {
|
||||
compatiblePlayers.forEach((client) => {
|
||||
privateMatchmakingMap.delete(client.id);
|
||||
});
|
||||
createGameSession(compatiblePlayers, matchOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function createGameSession(playersArr: ClientPlayer[], matchOptions: en.MatchOptions)
|
||||
{
|
||||
// const id = gameSessionIdPLACEHOLDER; // Force ID, TESTING SPECTATOR
|
||||
const id = uuidv4();
|
||||
const gameSession = new GameSession(id, matchOptions);
|
||||
gameSessionsMap.set(id, gameSession);
|
||||
|
||||
compatiblePlayers.forEach((client) => {
|
||||
matchmakingPlayersMap.delete(client.id);
|
||||
playersArr.forEach((client) => {
|
||||
client.gameSession = gameSession;
|
||||
gameSession.playersMap.set(client.id, client);
|
||||
gameSession.unreadyPlayersMap.set(client.id, client);
|
||||
@@ -134,15 +204,15 @@ function matchmaking(player: ClientPlayer)
|
||||
|
||||
// WIP: Not pretty, hardcoded two players.
|
||||
// Could be done in gameSession maybe ?
|
||||
compatiblePlayers[0].racket = gameSession.components.playerRight;
|
||||
compatiblePlayers[1].racket = gameSession.components.playerLeft;
|
||||
playersArr[0].racket = gameSession.components.playerRight;
|
||||
playersArr[1].racket = gameSession.components.playerLeft;
|
||||
|
||||
compatiblePlayers.forEach((client) => {
|
||||
playersArr.forEach((client) => {
|
||||
client.socket.once("message", playerReadyConfirmationListener);
|
||||
});
|
||||
|
||||
compatiblePlayers[0].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) ));
|
||||
compatiblePlayers[1].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) ));
|
||||
playersArr[0].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) ));
|
||||
playersArr[1].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) ));
|
||||
|
||||
setTimeout(function abortMatch() {
|
||||
if (gameSession.unreadyPlayersMap.size !== 0)
|
||||
@@ -155,6 +225,18 @@ function matchmaking(player: ClientPlayer)
|
||||
});
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
/* // WIP nest , send gameSession.id
|
||||
await fetch(c.addressBackEnd + "/game/newGameSession",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: id,
|
||||
})
|
||||
}); */
|
||||
}
|
||||
|
||||
|
||||
@@ -250,6 +332,9 @@ function clientTerminate(client: Client)
|
||||
if (matchmakingPlayersMap.has(client.id)) {
|
||||
matchmakingPlayersMap.delete(client.id);
|
||||
}
|
||||
else if (privateMatchmakingMap.has(client.id)) {
|
||||
privateMatchmakingMap.delete(client.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -89,12 +89,17 @@ export class ClientAnnounce extends ClientEvent {
|
||||
}
|
||||
|
||||
export class ClientAnnouncePlayer extends ClientAnnounce {
|
||||
clientId: string;
|
||||
clientId: string; // unused
|
||||
matchOptions: en.MatchOptions;
|
||||
constructor(matchOptions: en.MatchOptions, clientId: string = "") {
|
||||
token: string;
|
||||
username: string;
|
||||
privateMatch: boolean;
|
||||
constructor(matchOptions: en.MatchOptions, token: string, username: string, privateMatch: boolean = false) {
|
||||
super(en.ClientRole.player);
|
||||
this.clientId = clientId;
|
||||
this.matchOptions = matchOptions;
|
||||
this.token = token;
|
||||
this.username = username;
|
||||
this.privateMatch = privateMatch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import { Vector, VectorInteger } from "./Vector.js";
|
||||
import { Component, Moving } from "./interface.js";
|
||||
import type { Component, Moving } from "./interface.js";
|
||||
import * as c from "../constants.js"
|
||||
|
||||
export class Rectangle implements Component {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { Vector, VectorInteger } from "./Vector.js";
|
||||
import type { Vector, VectorInteger } from "./Vector.js";
|
||||
|
||||
export interface Component {
|
||||
pos: VectorInteger;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { MovingRectangle } from "./class/Rectangle.js";
|
||||
import type { MovingRectangle } from "./class/Rectangle.js";
|
||||
|
||||
export function random(min: number = 0, max: number = 1) {
|
||||
return Math.random() * (max - min) + min;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import * as c from "./constants.js";
|
||||
import { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
||||
import { GameComponents } from "./class/GameComponents.js";
|
||||
import type { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
||||
import type { GameComponents } from "./class/GameComponents.js";
|
||||
|
||||
export function wallsMovements(delta: number, gc: GameComponents)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ POSTGRES_DATABASE=transcendance_db
|
||||
|
||||
# OAUTH2 42 API
|
||||
FORTYTWO_CLIENT_ID=u-s4t2ud-49dc7b539bcfe1acb48b928b2b281671c99fc5bfab1faca57a536ab7e0075500
|
||||
FORTYTWO_CLIENT_SECRET=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
|
||||
FORTYTWO_CLIENT_SECRET=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
|
||||
FORTYTWO_CALLBACK_URL=http://transcendance:8080/api/v2/auth/redirect
|
||||
COOKIE_SECRET=248cdc831110eec8796d7c1edbf79835
|
||||
# JWT
|
||||
|
||||
@@ -15,25 +15,30 @@
|
||||
|
||||
let optionsAreNotSet = true
|
||||
|
||||
let sound = false;
|
||||
let soundMutedFlag = false;
|
||||
let multi_balls = false;
|
||||
let moving_walls = false;
|
||||
let matchOption : enumeration.MatchOptions = enumeration.MatchOptions.noOption;
|
||||
let matchOptions : enumeration.MatchOptions = enumeration.MatchOptions.noOption;
|
||||
|
||||
|
||||
// En async au cas où pour la suite mais apriori inutile, les check se feront sûrement au onMount
|
||||
const init = async() => {
|
||||
if (multi_balls === true)
|
||||
matchOption |= enumeration.MatchOptions.multiBalls
|
||||
if (moving_walls === true )
|
||||
matchOption |= enumeration.MatchOptions.movingWalls
|
||||
initAudio(sound)
|
||||
initMatchOptions(matchOption)
|
||||
optionsAreNotSet = false
|
||||
initPong(new GameArea())
|
||||
initGc(new GameComponentsClient(matchOption, pong.ctx))
|
||||
initStartFunction(start)
|
||||
initWebSocket(matchOption)
|
||||
console.log(soundMutedFlag);
|
||||
|
||||
initAudio(soundMutedFlag);
|
||||
if (multi_balls === true) {
|
||||
matchOptions |= enumeration.MatchOptions.multiBalls;
|
||||
}
|
||||
if (moving_walls === true) {
|
||||
matchOptions |= enumeration.MatchOptions.movingWalls;
|
||||
}
|
||||
initMatchOptions(matchOptions);
|
||||
optionsAreNotSet = false;
|
||||
|
||||
initPong(new GameArea());
|
||||
initGc(new GameComponentsClient(matchOptions, pong.ctx));
|
||||
initStartFunction(start);
|
||||
initWebSocket(matchOptions);
|
||||
}
|
||||
|
||||
function start() : void {
|
||||
@@ -65,28 +70,31 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="preload_font">.</div>
|
||||
{#if optionsAreNotSet}
|
||||
<form on:submit|preventDefault={init}>
|
||||
<div id="div_game_options">
|
||||
<fieldset>
|
||||
<legend>game options</legend>
|
||||
<div>
|
||||
<input type="checkbox" id="multi_balls" name="multi_balls" bind:checked={multi_balls}>
|
||||
<label for="multi_balls">Multiples balls</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="moving_walls" name="moving_walls" bind:checked={moving_walls}>
|
||||
<label for="moving_walls">Moving walls</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="moving_walls" name="moving_walls" bind:checked={sound}>
|
||||
<label for="moving_walls">Sound</label>
|
||||
</div>
|
||||
<div>
|
||||
<button id="play_pong_button" >PLAY</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>game options</legend>
|
||||
<div>
|
||||
<input type="checkbox" id="multi_balls" name="multi_balls">
|
||||
<label for="multi_balls">multiples balls</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="moving_walls" name="moving_walls">
|
||||
<label for="moving_walls">moving walls</label>
|
||||
</div>
|
||||
<div>
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label>sound :</label>
|
||||
<input type="radio" id="sound_on" name="sound_selector" bind:group={soundMutedFlag} value=false checked>
|
||||
<label for="sound_on">on</label>
|
||||
<input type="radio" id="sound_off" name="sound_selector" bind:group={soundMutedFlag} value=true>
|
||||
<label for="sound_off">off</label>
|
||||
</div>
|
||||
<div>
|
||||
<button id="play_pong_button">PLAY</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</form>
|
||||
<div id="div_game_instructions">
|
||||
@@ -106,29 +114,33 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "Bit5x3";
|
||||
src: url("/fonts/Bit5x3.woff2") format("woff2"),local("Bit5x3"), url("/fonts/Bit5x3.woff") format("woff");
|
||||
src:
|
||||
url("/fonts/Bit5x3.woff2") format("woff2"),
|
||||
local("Bit5x3"),
|
||||
url("/fonts/Bit5x3.woff") format("woff");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
#preload_font {
|
||||
font-family: "Bit5x3";
|
||||
opacity:0;
|
||||
height:0;
|
||||
width:0;
|
||||
display:inline-block;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #222425;
|
||||
}
|
||||
#canvas_container {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
/* border: dashed rgb(245, 245, 245) 5px; */
|
||||
/* max-height: 80vh; */
|
||||
/* overflow: hidden; */
|
||||
}
|
||||
#div_game_instructions {
|
||||
text-align: center;
|
||||
font-family: "Bit5x3";
|
||||
color: rgb(245, 245, 245);
|
||||
font-size: large;
|
||||
}
|
||||
#div_game_options {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
font-family: "Bit5x3";
|
||||
color: rgb(245, 245, 245);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
||||
import { TextElem, TextNumericValue } from "./Text.js";
|
||||
import { RectangleClient, MovingRectangleClient, RacketClient, BallClient, Line } from "./RectangleClient.js";
|
||||
import { GameComponents } from "../../shared_js/class/GameComponents.js";
|
||||
import { MovingRectangle } from "../../shared_js/class/Rectangle.js";
|
||||
import type { MovingRectangle } from "../../shared_js/class/Rectangle.js";
|
||||
|
||||
class GameComponentsExtensionForClient extends GameComponents {
|
||||
wallTop: RectangleClient | MovingRectangleClient;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import * as en from "../../shared_js/enums.js"
|
||||
import * as ev from "../../shared_js/class/Event.js"
|
||||
import type * as en from "../../shared_js/enums.js"
|
||||
import type * as ev from "../../shared_js/class/Event.js"
|
||||
|
||||
export class InputHistory {
|
||||
input: en.InputEnum;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
||||
import { Component, GraphicComponent, Moving } from "../../shared_js/class/interface.js";
|
||||
import type { GraphicComponent } from "../../shared_js/class/interface.js";
|
||||
import { Rectangle, MovingRectangle, Racket, Ball } from "../../shared_js/class/Rectangle.js";
|
||||
import { soundPongArr } from "../audio.js"
|
||||
import { random } from "../utils.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
||||
import { Component } from "../../shared_js/class/interface.js";
|
||||
import type { Component } from "../../shared_js/class/interface.js";
|
||||
|
||||
// conflict with Text
|
||||
export class TextElem implements Component {
|
||||
|
||||
@@ -3,8 +3,8 @@ import * as c from "./constants.js";
|
||||
import * as en from "../shared_js/enums.js"
|
||||
import { gc, matchOptions, clientInfo, clientInfoSpectator} from "./global.js";
|
||||
import { wallsMovements } from "../shared_js/wallsMovement.js";
|
||||
import { RacketClient } from "./class/RectangleClient.js";
|
||||
import { VectorInteger } from "../shared_js/class/Vector.js";
|
||||
import type { RacketClient } from "./class/RectangleClient.js";
|
||||
import type { VectorInteger } from "../shared_js/class/Vector.js";
|
||||
|
||||
let actual_time: number = Date.now();
|
||||
let last_time: number;
|
||||
|
||||
@@ -30,11 +30,15 @@ export let socket: WebSocket; /* TODO: A way to still use "const" not "let" ? */
|
||||
export const clientInfo = new ClientInfo();
|
||||
export const clientInfoSpectator = new ClientInfoSpectator(); // WIP, could refactor this
|
||||
|
||||
|
||||
const tokenPLACEHOLDER = "";
|
||||
const usernamePLACEHOLDER = "";
|
||||
const privateMatchPLACEHOLDER = false;
|
||||
export function initWebSocket(options: en.MatchOptions)
|
||||
{
|
||||
socket = new WebSocket(wsUrl, "json");
|
||||
socket.addEventListener("open", (event) => {
|
||||
socket.send(JSON.stringify( new ev.ClientAnnouncePlayer(options, clientInfo.id) ));
|
||||
socket.send(JSON.stringify( new ev.ClientAnnouncePlayer(options, tokenPLACEHOLDER, usernamePLACEHOLDER, privateMatchPLACEHOLDER) ));
|
||||
});
|
||||
// socket.addEventListener("message", logListener); // for testing purpose
|
||||
socket.addEventListener("message", preMatchListener);
|
||||
|
||||
@@ -89,12 +89,17 @@ export class ClientAnnounce extends ClientEvent {
|
||||
}
|
||||
|
||||
export class ClientAnnouncePlayer extends ClientAnnounce {
|
||||
clientId: string;
|
||||
clientId: string; // unused
|
||||
matchOptions: en.MatchOptions;
|
||||
constructor(matchOptions: en.MatchOptions, clientId: string = "") {
|
||||
token: string;
|
||||
username: string;
|
||||
privateMatch: boolean;
|
||||
constructor(matchOptions: en.MatchOptions, token: string, username: string, privateMatch: boolean = false) {
|
||||
super(en.ClientRole.player);
|
||||
this.clientId = clientId;
|
||||
this.matchOptions = matchOptions;
|
||||
this.token = token;
|
||||
this.username = username;
|
||||
this.privateMatch = privateMatch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import { Vector, VectorInteger } from "./Vector.js";
|
||||
import { Component, Moving } from "./interface.js";
|
||||
import type { Component, Moving } from "./interface.js";
|
||||
import * as c from "../constants.js"
|
||||
|
||||
export class Rectangle implements Component {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { Vector, VectorInteger } from "./Vector.js";
|
||||
import type { Vector, VectorInteger } from "./Vector.js";
|
||||
|
||||
export interface Component {
|
||||
pos: VectorInteger;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { MovingRectangle } from "./class/Rectangle.js";
|
||||
import type { MovingRectangle } from "./class/Rectangle.js";
|
||||
|
||||
export function random(min: number = 0, max: number = 1) {
|
||||
return Math.random() * (max - min) + min;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import * as c from "./constants.js";
|
||||
import { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
||||
import { GameComponents } from "./class/GameComponents.js";
|
||||
import type { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
||||
import type { GameComponents } from "./class/GameComponents.js";
|
||||
|
||||
export function wallsMovements(delta: number, gc: GameComponents)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user