bugfix with countdown() on early pong.destroy call
+ svelte reactivity with forfeit button + little matchmaking changes + Wip audio rework
This commit is contained in:
@@ -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}
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user