HTML game modes selector
+ pong.css in a separate file
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -18,6 +18,7 @@ Thumbs.db
|
||||
node_modules
|
||||
*.js
|
||||
www/**/*.html
|
||||
www/**/*.css
|
||||
|
||||
large
|
||||
old
|
||||
|
||||
1
make.sh
1
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/
|
||||
|
||||
2
memo.txt
2
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() ?)
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
export {pong, gc} from "./pong.js"
|
||||
export {pong, gc, matchOptions} from "./pong.js"
|
||||
export {socket, clientInfo} from "./ws.js"
|
||||
|
||||
53
src/client/pong.css
Normal file
53
src/client/pong.css
Normal 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%;
|
||||
}
|
||||
@@ -2,46 +2,35 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<style>
|
||||
@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>
|
||||
<link rel="stylesheet" href="pong.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="preloadfont">.</div>
|
||||
<div id="canvas-container">
|
||||
<div id="preload_font">.</div>
|
||||
|
||||
<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> -->
|
||||
</div>
|
||||
|
||||
<script src="http://localhost:8080/js/pong.js" type="module" defer></script>
|
||||
</body>
|
||||
|
||||
|
||||
@@ -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:"+(<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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user