bugfix with countdown() on early pong.destroy call

+ svelte reactivity with forfeit button
+ little matchmaking changes
+ Wip audio rework
This commit is contained in:
LuckyLaszlo
2023-01-05 20:18:59 +01:00
parent b35082148c
commit 68ae8ac333
11 changed files with 117 additions and 114 deletions

View File

@@ -30,9 +30,10 @@
let isThereAnyInvitation = false;
let invitations = [];
let waitingMessage = "Please wait..."
let waitingMessage = "Please wait...";
let errorMessageWhenAttemptingToGetATicket = "";
let idOfIntevalCheckTerminationOfTheMatch;
let watchGameStateInterval;
const watchGameStateIntervalRate = 142;
onMount( async() => {
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
@@ -43,7 +44,7 @@
})
onDestroy( async() => {
clearInterval(idOfIntevalCheckTerminationOfTheMatch);
clearInterval(watchGameStateInterval);
pong.destroy();
})
@@ -84,7 +85,7 @@
}
else if (token)
{
idOfIntevalCheckTerminationOfTheMatch = setInterval(matchTermitation, 1000);
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
// options.isInvitedPerson = false // ???
pong.init(options, gameAreaId, token);
hiddenGame = false;
@@ -101,7 +102,7 @@
console.log(invitation)
if (invitation.token)
{
idOfIntevalCheckTerminationOfTheMatch = setInterval(matchTermitation, 1000);
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
options.playerOneUsername = invitation.playerOneUsername;
options.playerTwoUsername = invitation.playerTwoUsername;
options.isSomeoneIsInvited = true;
@@ -112,23 +113,28 @@
}
}
const matchTermitation = () => {
console.log("Ping matchTermitation")
if (gameState.matchAbort || gameState.matchEnded)
const watchGameState = () => {
console.log("watchGameState")
if (gameState) { // trigger Svelte reactivity
gameState.matchStarted = gameState.matchStarted;
gameState.matchEnded = gameState.matchEnded;
gameState.matchAborted = gameState.matchAborted;
}
if (gameState.matchAborted || gameState.matchEnded)
{
clearInterval(idOfIntevalCheckTerminationOfTheMatch);
console.log("matchTermitation was called")
clearInterval(watchGameStateInterval);
console.log("watchGameState, end")
showWaitPage = false
gameState.matchAbort ?
gameState.matchAborted ?
errorMessageWhenAttemptingToGetATicket = "The match has been aborted"
: errorMessageWhenAttemptingToGetATicket = "The match is finished !"
gameState.matchAbort ? showError = true : showMatchEnded = true;
gameState.matchAborted ? showError = true : showMatchEnded = true;
setTimeout(() => {
resetPage();
errorMessageWhenAttemptingToGetATicket = "";
isThereAnyInvitation = false;
invitations = []; // ???
console.log("matchTermitation : setTimeout")
console.log("watchGameState : setTimeout")
}, 5000);
}
}
@@ -183,6 +189,7 @@
}
function leaveMatch() {
clearInterval(watchGameStateInterval);
resetPage();
};
@@ -221,9 +228,15 @@
<canvas id={gameAreaId}/>
</div>
{#if !hiddenGame}
<div id="div_game">
<button id="pong_button" on:click={leaveMatch}>forfeit</button>
</div>
{#if !hiddenGame && gameState.matchStarted && !gameState.matchEnded}
<div id="div_game">
<button id="pong_button" on:click={leaveMatch}>forfeit</button>
</div>
{:else if !hiddenGame && !gameState.matchStarted}
<div id="div_game">
<button id="pong_button" on:click={leaveMatch}>leave matchmaking</button>
</div>
{/if}
{/if}

View File

@@ -8,7 +8,6 @@
import * as pongSpectator from "./client/pongSpectator";
import { gameState } from "./client/ws";
import { gameSessionIdPLACEHOLDER } from "./shared_js/constants";
//user's stuff
let user;
@@ -17,32 +16,6 @@
//Game's stuff client side only
const gameAreaId = "game_area";
let sound = "off";
// const dummyMatchList = [
// {
// gameSessionId: gameSessionIdPLACEHOLDER,
// matchOptions: pongSpectator.MatchOptions.noOption,
// playerOneUsername: "toto",
// playerTwoUsername: "bruno",
// },
// {
// gameSessionId: gameSessionIdPLACEHOLDER,
// matchOptions: pongSpectator.MatchOptions.multiBalls,
// playerOneUsername: "pl1",
// playerTwoUsername: "pl2",
// },
// {
// gameSessionId: "id6543",
// matchOptions: pongSpectator.MatchOptions.movingWalls | pongSpectator.MatchOptions.multiBalls,
// playerOneUsername: "bertand",
// playerTwoUsername: "cassandre",
// },
// {
// gameSessionId: "id3452",
// matchOptions: pongSpectator.MatchOptions.multiBalls,
// playerOneUsername: "madeleine",
// playerTwoUsername: "jack",
// },
// ];
let matchList = [];
//html boolean for pages
@@ -55,14 +28,12 @@
.then( x => x.json() );
allUsers = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/all`)
.then( x => x.json() );
// WIP: fetch for match list here
const responseForMatchList = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/match/all`)
const jsonForMatchList = await responseForMatchList.json();
matchList = jsonForMatchList;
console.log("matchList");
if (matchList.length <= 0)
if (matchList.length <= 0) {
hiddenMatchList = true;
console.log(matchList);
}
})
onDestroy( async() => {
@@ -81,13 +52,11 @@
async function resetPage() {
hiddenGame = true;
pongSpectator.destroy();
// WIP: fetch for match list here
matchList = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/match/all`)
.then( x => x.json() );
console.log("matchList");
if (matchList.length <= 0)
if (matchList.length <= 0) {
hiddenMatchList = true;
console.log(matchList);
}
};
</script>

View File

@@ -2,11 +2,8 @@
import * as c from "./constants.js"
// export const soundPongArr: HTMLAudioElement[] = [];
export const soundPongArr: HTMLAudioElement[] = [
new Audio("http://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/sound/pong/"+1+".ogg"),
new Audio("http://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/sound/pong/"+2+".ogg")
];
export const soundRoblox = new Audio("http://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/sound/roblox-oof.ogg");
export const soundPongArr: HTMLAudioElement[] = [];
export let soundRoblox: HTMLAudioElement;
export function initAudio(sound: string)
{
@@ -18,10 +15,15 @@ export function initAudio(sound: string)
muteFlag = true;
}
soundPongArr.length = 0;
soundPongArr.push(new Audio("http://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/sound/pong/"+1+".ogg"));
soundPongArr.push(new Audio("http://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/sound/pong/"+2+".ogg"));
soundPongArr.forEach((value) => {
value.volume = c.soundRobloxVolume;
value.muted = muteFlag;
});
soundRoblox = new Audio("http://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/sound/roblox-oof.ogg");
soundRoblox.volume = c.soundRobloxVolume;
soundRoblox.muted = muteFlag;
}

View File

@@ -6,6 +6,7 @@ export class GameArea {
handleInputInterval: number = 0;
gameLoopInterval: number = 0;
drawLoopInterval: number = 0;
timeoutArr: number[] = [];
canvas: HTMLCanvasElement;
ctx: CanvasRenderingContext2D;
constructor(canvas_id: string) {

View File

@@ -34,15 +34,28 @@ export function initBase(matchOptions: en.MatchOptions, sound: string, gameAreaI
export function destroyBase()
{
if (pong)
{
clearInterval(pong.handleInputInterval);
clearInterval(pong.gameLoopInterval);
clearInterval(pong.drawLoopInterval);
setPong(null);
}
if (socket && socket.OPEN) {
if (socket && (socket.OPEN || socket.CONNECTING)) {
socket.close();
}
if (pong)
{
pong.timeoutArr.forEach((value) => {
clearTimeout(value);
});
pong.timeoutArr = [];
clearInterval(pong.handleInputInterval);
pong.handleInputInterval = null;
clearInterval(pong.gameLoopInterval);
pong.gameLoopInterval = null;
clearInterval(pong.drawLoopInterval);
pong.drawLoopInterval = null;
setPong(null);
}
setGc(null);
setMatchOptions(null);
resetGameState();
}

View File

@@ -4,7 +4,7 @@ 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 { gameState, initWebSocket } from "./ws.js";
import type { InitOptions } from "./class/InitOptions.js";
export { InitOptions } from "./class/InitOptions.js";
import { initBase, destroyBase, computeMatchOptions } from "./init.js";
@@ -47,11 +47,12 @@ export function destroy()
function start()
{
gc.text1.pos.assign(c.w*0.5, c.h*0.75);
countdown(c.matchStartDelay/1000, (count: number) => {
const countdownArr = countdown(c.matchStartDelay, 1000, (count: number) => {
gc.text1.clear();
gc.text1.text = `${count}`;
gc.text1.text = `${count/1000}`;
gc.text1.update();
}, start_after_countdown);
pong.timeoutArr = pong.timeoutArr.concat(countdownArr);
}
function start_after_countdown()
@@ -66,11 +67,12 @@ function start_after_countdown()
abortControllerKeyup = new AbortController();
window.addEventListener(
'keyup',
(e) => { pong.deleteKey(e.key);},
(e) => { pong.deleteKey(e.key); },
{signal: abortControllerKeyup.signal}
);
resume();
gameState.matchStarted = true;
}
function resume()

View File

@@ -1,16 +1,25 @@
export * from "../shared_js/utils.js"
export function countdown(count: number, callback?: (count: number) => void, endCallback?: () => void)
export function countdown(count: number, step: number, callback: (count: number) => void, endCallback?: () => void) : number[]
{
console.log("countdown ", count);
if (count > 0) {
if (callback) {
const timeoutArr: number[] = [];
if (endCallback) {
timeoutArr.push( window.setTimeout(endCallback, count) );
}
let reverseCount = 0;
while (count > 0)
{
timeoutArr.push( window.setTimeout((count: number) => {
console.log("countdown ", count);
callback(count);
}
setTimeout(countdown, 1000, --count, callback, endCallback);
}
else if (endCallback) {
endCallback();
}, reverseCount, count)
);
count -= step;
reverseCount += step;
}
return timeoutArr;
}

View File

@@ -11,13 +11,15 @@ import { sleep } from "./utils.js";
import { Vector, VectorInteger } from "../shared_js/class/Vector.js";
export const gameState = {
matchStarted: false,
matchEnded: false,
matchAbort: false
matchAborted: false
}
export function resetGameState() {
gameState.matchStarted = false;
gameState.matchEnded = false;
gameState.matchAbort = false;
gameState.matchAborted = false;
}
class ClientInfo {
@@ -36,7 +38,7 @@ class ClientInfoSpectator {
}
const wsUrl = "ws://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/pong";
export let socket: WebSocket; /* TODO: A way to still use "const" not "let" ? */
export let socket: WebSocket;
export const clientInfo = new ClientInfo();
export const clientInfoSpectator = new ClientInfoSpectator(); // WIP, could refactor this
@@ -104,7 +106,7 @@ function preMatchListener(this: WebSocket, event: MessageEvent)
startFunction();
break;
case en.EventTypes.matchAbort:
gameState.matchAbort = true;
gameState.matchAborted = true;
socket.removeEventListener("message", preMatchListener);
msg.matchAbort();
break;