diff --git a/.gitignore b/.gitignore index ad799a41..ad53a4d3 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ Thumbs.db node_modules *.js www/**/*.html +www/**/*.css large old diff --git a/make.sh b/make.sh index 71ec2fb2..ebce024a 100644 --- a/make.sh +++ b/make.sh @@ -3,6 +3,7 @@ npx tsc mkdir -p www cp ./src/client/*.html ./www/ +cp ./src/client/*.css ./www/ mkdir -p www/js cp ./src/client/*.js ./www/js/ diff --git a/memo.txt b/memo.txt index 882a3339..be25ed46 100644 --- a/memo.txt +++ b/memo.txt @@ -14,8 +14,10 @@ Done: - Détruire les GameSession une fois finies. - mode multi-balles - mode murs mouvant (la zone de jeu rétréci / agrandi en continu) + - Selection des modes de jeu via HTML TODO: +- Match Abort si tout les joueurs ne sont pas pret assez vite (~15 secondes) - mode spectateur - certaines utilisations de Math.floor() superflu ? Vérifier les appels. (éventuellement Math.round() ?) diff --git a/src/client/class/GameArea.ts b/src/client/class/GameArea.ts index 9cd92302..e6921e4e 100644 --- a/src/client/class/GameArea.ts +++ b/src/client/class/GameArea.ts @@ -13,7 +13,7 @@ class GameArea { this.ctx = this.canvas.getContext("2d") as CanvasRenderingContext2D; this.canvas.width = c.CanvasWidth; this.canvas.height = c.CanvasWidth / c.CanvasRatio; - let container = document.getElementById("canvas-container"); + let container = document.getElementById("canvas_container"); if (container) container.insertBefore(this.canvas, container.childNodes[0]); } diff --git a/src/client/constants.ts b/src/client/constants.ts index 786d0f99..39a3a043 100644 --- a/src/client/constants.ts +++ b/src/client/constants.ts @@ -8,19 +8,12 @@ export const gridSize = Math.floor(w/500); // min interval on Firefox seems to be 15. Chrome can go lower. export const handleInputIntervalMS = 15; // millisecond -export const sendLoopIntervalMS = 15; // millisecond +export const sendLoopIntervalMS = 15; // millisecond // unused export const gameLoopIntervalMS = 15; // millisecond export const drawLoopIntervalMS = 15; // millisecond export const fixedDeltaTime = gameLoopIntervalMS/1000; // second -export const soundMutedFlag = true; +export const soundMutedFlag = true; // TODO: Radio selector on website export const soundRobloxVolume = 0.3; // between 0 and 1 export const soundPongVolume = 0.3; // between 0 and 1 - -// TODO: replace by a selector on the website -import * as en from "../shared_js/enums.js" -export const optionsPLACEHOLDER = en.MatchOptions.noOption; -// export const optionsPLACEHOLDER = en.MatchOptions.multiBalls; -// export const optionsPLACEHOLDER = en.MatchOptions.movingWalls; -// export const optionsPLACEHOLDER = en.MatchOptions.movingWalls | en.MatchOptions.multiBalls; diff --git a/src/client/gameLoop.ts b/src/client/gameLoop.ts index b911641a..593d1eaa 100644 --- a/src/client/gameLoop.ts +++ b/src/client/gameLoop.ts @@ -1,7 +1,7 @@ import * as c from "./constants.js"; import * as en from "../shared_js/enums.js" -import { gc, clientInfo } from "./global.js"; +import { gc, matchOptions, clientInfo } from "./global.js"; import { wallsMovements } from "../shared_js/wallsMovement.js"; let actual_time: number = Date.now(); @@ -28,7 +28,7 @@ function gameLoop() ball.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]); }); - if (c.optionsPLACEHOLDER & en.MatchOptions.movingWalls) { + if (matchOptions & en.MatchOptions.movingWalls) { wallsMovements(delta_time, gc); } } diff --git a/src/client/global.ts b/src/client/global.ts index 70564ece..7d0a7126 100644 --- a/src/client/global.ts +++ b/src/client/global.ts @@ -1,3 +1,3 @@ -export {pong, gc} from "./pong.js" +export {pong, gc, matchOptions} from "./pong.js" export {socket, clientInfo} from "./ws.js" diff --git a/src/client/pong.css b/src/client/pong.css new file mode 100644 index 00000000..cc90b07e --- /dev/null +++ b/src/client/pong.css @@ -0,0 +1,53 @@ + +@font-face { + font-family: "Bit5x3"; + src: url("http://localhost:8080/Bit5x3.woff2") format("woff2"), + url("http://localhost:8080/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 { + text-align: center; + /* border: dashed white 5px; */ + /* max-height: 80vh; */ + /* overflow: hidden; */ +} +#div_game_options { + text-align: center; + font-family: "Bit5x3"; + color: white; + font-size: x-large; +} +#div_game_options fieldset { + max-width: 50vw; + width: auto; + margin: 0 auto; +} +#div_game_options fieldset div { + padding: 10px; +} +#play_pong_button { + font-family: "Bit5x3"; + color: white; + background-color: #333333; + font-size: x-large; + padding: 10px; +} +canvas { + background-color: #333333; + max-width: 75vw; + /* max-height: 100vh; */ + width: 80%; +} diff --git a/src/client/pong.html b/src/client/pong.html index 0e443c3b..f4d97fa5 100644 --- a/src/client/pong.html +++ b/src/client/pong.html @@ -2,46 +2,35 @@ - + -
.
-
+
.
+ +
+
+ Game options +
+ + +
+ +
+ + +
+ +
+ +
+
+
+ +
+ diff --git a/src/client/pong.ts b/src/client/pong.ts index 44eab63c..dfb857ac 100644 --- a/src/client/pong.ts +++ b/src/client/pong.ts @@ -1,5 +1,11 @@ +initDom(); +function initDom() { + document.getElementById("play_pong_button").addEventListener("click", init); +} + import * as c from "./constants.js" +import * as en from "../shared_js/enums.js" import { GameArea } from "./class/GameArea.js"; import { GameComponentsClient } from "./class/GameComponentsClient.js"; import { handleInput } from "./handleInput.js"; @@ -7,16 +13,37 @@ import { handleInput } from "./handleInput.js"; import { gameLoop } from "./gameLoop.js" import { drawLoop } from "./draw.js"; import { countdown } from "./utils.js"; +import {initWebSocket} from "./ws.js"; -import {socket} from "./ws.js"; socket; // no-op, just for loading /* Keys Racket: W/S OR Up/Down Grid On-Off: G */ -export const pong = new GameArea(); -export const gc = new GameComponentsClient(c.optionsPLACEHOLDER, pong.ctx); +/* TODO: A way to delay the init of variables, but still use "const" not "let" ? */ +export let pong: GameArea; +export let gc: GameComponentsClient; +export let matchOptions: en.MatchOptions = en.MatchOptions.noOption; + +function init() +{ + console.log("multiBalls:"+(document.getElementById("multiBalls")).checked); + console.log("movingWalls:"+(document.getElementById("movingWalls")).checked); + + if ( (document.getElementById("multiBalls")).checked ) { + matchOptions |= en.MatchOptions.multiBalls; + } + if ( (document.getElementById("movingWalls")).checked ) { + matchOptions |= en.MatchOptions.movingWalls; + } + + document.getElementById("div_game_options").hidden = true; + + pong = new GameArea(); + gc = new GameComponentsClient(matchOptions, pong.ctx); + initWebSocket(matchOptions); +} function matchmaking() { diff --git a/src/client/ws.ts b/src/client/ws.ts index fd97756c..60f1ab87 100644 --- a/src/client/ws.ts +++ b/src/client/ws.ts @@ -1,6 +1,6 @@ import * as c from "./constants.js" -import { gc } from "./global.js" +import { gc, matchOptions } from "./global.js" import * as ev from "../shared_js/class/Event.js" import * as en from "../shared_js/enums.js" import { matchmaking, matchmakingComplete, startGame } from "./pong.js"; @@ -10,10 +10,6 @@ import { soundRoblox } from "./audio.js" import { sleep } from "./utils.js"; import { Vector, VectorInteger } from "../shared_js/class/Vector.js"; -const wsPort = 8042; -const wsUrl = "ws://" + document.location.hostname + ":" + wsPort + "/pong"; -export const socket = new WebSocket(wsUrl, "json"); - class ClientInfo { id = ""; side: en.PlayerSide; @@ -22,20 +18,27 @@ class ClientInfo { opponentNextPos: VectorInteger; } +const wsPort = 8042; +const wsUrl = "ws://" + document.location.hostname + ":" + wsPort + "/pong"; +export let socket: WebSocket; /* TODO: A way to still use "const" not "let" ? */ export const clientInfo = new ClientInfo(); -socket.addEventListener("open", (event) => { - socket.send(JSON.stringify( new ev.ClientAnnounce(en.ClientRole.player, c.optionsPLACEHOLDER, clientInfo.id) )); -}); - -// socket.addEventListener("message", logListener); // for testing purpose -socket.addEventListener("message", preMatchListener); +export function initWebSocket(options: en.MatchOptions) +{ + socket = new WebSocket(wsUrl, "json"); + socket.addEventListener("open", (event) => { + socket.send(JSON.stringify( new ev.ClientAnnounce(en.ClientRole.player, options, clientInfo.id) )); + }); + // socket.addEventListener("message", logListener); // for testing purpose + socket.addEventListener("message", preMatchListener); +} function logListener(this: WebSocket, event: MessageEvent) { console.log("%i: " + event.data, Date.now()); } -function preMatchListener(this: WebSocket, event: MessageEvent) { +function preMatchListener(this: WebSocket, event: MessageEvent) +{ const data: ev.ServerEvent = JSON.parse(event.data); switch (data.type) { case en.EventTypes.assignId: @@ -90,7 +93,7 @@ function gameUpdate(data: ev.EventGameUpdate) { console.log("gameUpdate"); - if (c.optionsPLACEHOLDER & en.MatchOptions.movingWalls) { + if (matchOptions & en.MatchOptions.movingWalls) { gc.wallTop.pos.y = data.wallTop.y; gc.wallBottom.pos.y = data.wallBottom.y; }