HTML game modes selector

+ pong.css in a separate file
This commit is contained in:
LuckyLaszlo
2022-12-06 01:56:39 +01:00
parent 7355a70821
commit 9dde821f67
11 changed files with 133 additions and 64 deletions

1
.gitignore vendored
View File

@@ -18,6 +18,7 @@ Thumbs.db
node_modules node_modules
*.js *.js
www/**/*.html www/**/*.html
www/**/*.css
large large
old old

View File

@@ -3,6 +3,7 @@ npx tsc
mkdir -p www mkdir -p www
cp ./src/client/*.html ./www/ cp ./src/client/*.html ./www/
cp ./src/client/*.css ./www/
mkdir -p www/js mkdir -p www/js
cp ./src/client/*.js ./www/js/ cp ./src/client/*.js ./www/js/

View File

@@ -14,8 +14,10 @@ Done:
- Détruire les GameSession une fois finies. - Détruire les GameSession une fois finies.
- mode multi-balles - mode multi-balles
- mode murs mouvant (la zone de jeu rétréci / agrandi en continu) - mode murs mouvant (la zone de jeu rétréci / agrandi en continu)
- Selection des modes de jeu via HTML
TODO: TODO:
- Match Abort si tout les joueurs ne sont pas pret assez vite (~15 secondes)
- mode spectateur - mode spectateur
- certaines utilisations de Math.floor() superflu ? Vérifier les appels. - certaines utilisations de Math.floor() superflu ? Vérifier les appels.
(éventuellement Math.round() ?) (éventuellement Math.round() ?)

View File

@@ -13,7 +13,7 @@ class GameArea {
this.ctx = this.canvas.getContext("2d") as CanvasRenderingContext2D; this.ctx = this.canvas.getContext("2d") as CanvasRenderingContext2D;
this.canvas.width = c.CanvasWidth; this.canvas.width = c.CanvasWidth;
this.canvas.height = c.CanvasWidth / c.CanvasRatio; this.canvas.height = c.CanvasWidth / c.CanvasRatio;
let container = document.getElementById("canvas-container"); let container = document.getElementById("canvas_container");
if (container) if (container)
container.insertBefore(this.canvas, container.childNodes[0]); container.insertBefore(this.canvas, container.childNodes[0]);
} }

View File

@@ -8,19 +8,12 @@ export const gridSize = Math.floor(w/500);
// min interval on Firefox seems to be 15. Chrome can go lower. // min interval on Firefox seems to be 15. Chrome can go lower.
export const handleInputIntervalMS = 15; // millisecond export const handleInputIntervalMS = 15; // millisecond
export const sendLoopIntervalMS = 15; // millisecond export const sendLoopIntervalMS = 15; // millisecond // unused
export const gameLoopIntervalMS = 15; // millisecond export const gameLoopIntervalMS = 15; // millisecond
export const drawLoopIntervalMS = 15; // millisecond export const drawLoopIntervalMS = 15; // millisecond
export const fixedDeltaTime = gameLoopIntervalMS/1000; // second 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 soundRobloxVolume = 0.3; // between 0 and 1
export const soundPongVolume = 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;

View File

@@ -1,7 +1,7 @@
import * as c from "./constants.js"; import * as c from "./constants.js";
import * as en from "../shared_js/enums.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"; import { wallsMovements } from "../shared_js/wallsMovement.js";
let actual_time: number = Date.now(); let actual_time: number = Date.now();
@@ -28,7 +28,7 @@ function gameLoop()
ball.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]); 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); wallsMovements(delta_time, gc);
} }
} }

View File

@@ -1,3 +1,3 @@
export {pong, gc} from "./pong.js" export {pong, gc, matchOptions} from "./pong.js"
export {socket, clientInfo} from "./ws.js" export {socket, clientInfo} from "./ws.js"

53
src/client/pong.css Normal file
View File

@@ -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%;
}

View File

@@ -2,46 +2,35 @@
<html> <html>
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style> <link rel="stylesheet" href="pong.css">
@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;
}
#preloadfont {
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 red 5px;
/* max-height: 80vh; */
/* overflow: hidden; */
}
canvas {
background-color: #333333;
max-width: 75vw;
/* max-height: 100vh; */
width: 80%;
}
</style>
</head> </head>
<body> <body>
<div id="preloadfont">.</div> <div id="preload_font">.</div>
<div id="canvas-container">
<div id="div_game_options">
<fieldset>
<legend>Game options</legend>
<div>
<input type="checkbox" id="multiBalls" name="multiBalls">
<label for="multiBalls">Multiples balls</label>
</div>
<div>
<input type="checkbox" id="movingWalls" name="movingWalls">
<label for="movingWalls">Moving walls</label>
</div>
<div>
<button id="play_pong_button">Play</button>
</div>
</fieldset>
</div>
<div id="canvas_container">
<!-- <p> =) </p> --> <!-- <p> =) </p> -->
</div> </div>
<script src="http://localhost:8080/js/pong.js" type="module" defer></script> <script src="http://localhost:8080/js/pong.js" type="module" defer></script>
</body> </body>

View File

@@ -1,5 +1,11 @@
initDom();
function initDom() {
document.getElementById("play_pong_button").addEventListener("click", init);
}
import * as c from "./constants.js" import * as c from "./constants.js"
import * as en from "../shared_js/enums.js"
import { GameArea } from "./class/GameArea.js"; import { GameArea } from "./class/GameArea.js";
import { GameComponentsClient } from "./class/GameComponentsClient.js"; import { GameComponentsClient } from "./class/GameComponentsClient.js";
import { handleInput } from "./handleInput.js"; import { handleInput } from "./handleInput.js";
@@ -7,16 +13,37 @@ import { handleInput } from "./handleInput.js";
import { gameLoop } from "./gameLoop.js" import { gameLoop } from "./gameLoop.js"
import { drawLoop } from "./draw.js"; import { drawLoop } from "./draw.js";
import { countdown } from "./utils.js"; import { countdown } from "./utils.js";
import {initWebSocket} from "./ws.js";
import {socket} from "./ws.js"; socket; // no-op, just for loading
/* Keys /* Keys
Racket: W/S OR Up/Down Racket: W/S OR Up/Down
Grid On-Off: G Grid On-Off: G
*/ */
export const pong = new GameArea(); /* TODO: A way to delay the init of variables, but still use "const" not "let" ? */
export const gc = new GameComponentsClient(c.optionsPLACEHOLDER, pong.ctx); export let pong: GameArea;
export let gc: GameComponentsClient;
export let matchOptions: en.MatchOptions = en.MatchOptions.noOption;
function init()
{
console.log("multiBalls:"+(<HTMLInputElement>document.getElementById("multiBalls")).checked);
console.log("movingWalls:"+(<HTMLInputElement>document.getElementById("movingWalls")).checked);
if ( (<HTMLInputElement>document.getElementById("multiBalls")).checked ) {
matchOptions |= en.MatchOptions.multiBalls;
}
if ( (<HTMLInputElement>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() function matchmaking()
{ {

View File

@@ -1,6 +1,6 @@
import * as c from "./constants.js" 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 ev from "../shared_js/class/Event.js"
import * as en from "../shared_js/enums.js" import * as en from "../shared_js/enums.js"
import { matchmaking, matchmakingComplete, startGame } from "./pong.js"; import { matchmaking, matchmakingComplete, startGame } from "./pong.js";
@@ -10,10 +10,6 @@ import { soundRoblox } from "./audio.js"
import { sleep } from "./utils.js"; import { sleep } from "./utils.js";
import { Vector, VectorInteger } from "../shared_js/class/Vector.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 { class ClientInfo {
id = ""; id = "";
side: en.PlayerSide; side: en.PlayerSide;
@@ -22,20 +18,27 @@ class ClientInfo {
opponentNextPos: VectorInteger; 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(); export const clientInfo = new ClientInfo();
export function initWebSocket(options: en.MatchOptions)
{
socket = new WebSocket(wsUrl, "json");
socket.addEventListener("open", (event) => { socket.addEventListener("open", (event) => {
socket.send(JSON.stringify( new ev.ClientAnnounce(en.ClientRole.player, c.optionsPLACEHOLDER, clientInfo.id) )); socket.send(JSON.stringify( new ev.ClientAnnounce(en.ClientRole.player, options, clientInfo.id) ));
}); });
// socket.addEventListener("message", logListener); // for testing purpose // socket.addEventListener("message", logListener); // for testing purpose
socket.addEventListener("message", preMatchListener); socket.addEventListener("message", preMatchListener);
}
function logListener(this: WebSocket, event: MessageEvent) { function logListener(this: WebSocket, event: MessageEvent) {
console.log("%i: " + event.data, Date.now()); 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); const data: ev.ServerEvent = JSON.parse(event.data);
switch (data.type) { switch (data.type) {
case en.EventTypes.assignId: case en.EventTypes.assignId:
@@ -90,7 +93,7 @@ function gameUpdate(data: ev.EventGameUpdate)
{ {
console.log("gameUpdate"); console.log("gameUpdate");
if (c.optionsPLACEHOLDER & en.MatchOptions.movingWalls) { if (matchOptions & en.MatchOptions.movingWalls) {
gc.wallTop.pos.y = data.wallTop.y; gc.wallTop.pos.y = data.wallTop.y;
gc.wallBottom.pos.y = data.wallBottom.y; gc.wallBottom.pos.y = data.wallBottom.y;
} }