Vive le rouge !

This commit is contained in:
batche
2022-12-20 20:23:15 +01:00
parent fb7bfa0097
commit 77857a873d
11 changed files with 311 additions and 86 deletions

View File

@@ -82,7 +82,7 @@ export class GameSession {
else if (input === en.InputEnum.down) { else if (input === en.InputEnum.down) {
client.racket.dir.y = 1; client.racket.dir.y = 1;
} }
if (input !== en.InputEnum.noInput) { if (input !== en.InputEnum.noInput) {
client.racket.moveAndCollide(delta, [gc.wallTop, gc.wallBottom]); client.racket.moveAndCollide(delta, [gc.wallTop, gc.wallBottom]);
} }
@@ -220,7 +220,7 @@ export class GameSession {
} }
return false; return false;
} }
private async _matchEnd(winner: en.PlayerSide, forfeit_flag: boolean = false) private async _matchEnd(winner: en.PlayerSide, forfeit_flag: boolean = false)
{ {
this.matchEnded = true; this.matchEnded = true;
let eventEnd: ev.EventMatchEnd; let eventEnd: ev.EventMatchEnd;
@@ -232,7 +232,6 @@ export class GameSession {
client.socket.send(JSON.stringify(eventEnd)); client.socket.send(JSON.stringify(eventEnd));
}); });
/* // WIP nest , send match result
const gc = this.components; const gc = this.components;
await fetch(c.addressBackEnd + "/game/matchEnd", await fetch(c.addressBackEnd + "/game/matchEnd",
{ {
@@ -245,7 +244,7 @@ export class GameSession {
scoreLeft: gc.scoreLeft, scoreLeft: gc.scoreLeft,
scoreRight: gc.scoreRight, scoreRight: gc.scoreRight,
}) })
}); */ });
// logs // logs
if (winner === en.PlayerSide.left) { if (winner === en.PlayerSide.left) {

View File

@@ -9,4 +9,4 @@ export const fixedDeltaTime = serverGameLoopIntervalMS/1000; // second
export const playersUpdateIntervalMS = 1000/30; // millisecond export const playersUpdateIntervalMS = 1000/30; // millisecond
export const spectatorsUpdateIntervalMS = 1000/30; // millisecond export const spectatorsUpdateIntervalMS = 1000/30; // millisecond
export const addressBackEnd = "http://backend_dev:3000"; export const addressBackEnd = "http://backend_dev:3000/api/v2";

View File

@@ -66,7 +66,7 @@ async function clientAnnounceListener(this: WebSocket, data: string)
if (msg.role === en.ClientRole.player) if (msg.role === en.ClientRole.player)
{ {
const announce: ev.ClientAnnouncePlayer = <ev.ClientAnnouncePlayer>msg; const announce: ev.ClientAnnouncePlayer = <ev.ClientAnnouncePlayer>msg;
// WIP nest, fetch token validation // WIP nest, fetch token validation
const body = { const body = {
playerOneUsername: announce.username, playerOneUsername: announce.username,
@@ -78,7 +78,7 @@ async function clientAnnounceListener(this: WebSocket, data: string)
if (announce.privateMatch) { if (announce.privateMatch) {
body.playerTwoUsername = announce.playerTwoUsername; body.playerTwoUsername = announce.playerTwoUsername;
} }
const response = await fetch(c.addressBackEnd + "/game/validateToken", const response = await fetch(c.addressBackEnd + "/game/gameserver/validate",
{ {
method: "POST", method: "POST",
headers: { headers: {
@@ -163,12 +163,12 @@ function publicMatchmaking(player: ClientPlayer)
function privateMatchmaking(player: ClientPlayer) function privateMatchmaking(player: ClientPlayer)
{ {
const minPlayersNumber = 2; const minPlayersNumber = 2;
const maxPlayersNumber = 2; const maxPlayersNumber = 2;
privateMatchmakingMap.set(player.id, player); privateMatchmakingMap.set(player.id, player);
const matchOptions = player.matchOptions; const matchOptions = player.matchOptions;
const token = player.token; const token = player.token;
const compatiblePlayers: ClientPlayer[] = []; const compatiblePlayers: ClientPlayer[] = [];
for (const [id, client] of privateMatchmakingMap) for (const [id, client] of privateMatchmakingMap)
@@ -243,17 +243,18 @@ async function playerReadyConfirmationListener(this: WebSocket, data: string)
{ {
// WIP nest , send gameSession.id // WIP nest , send gameSession.id
const gameSessionPlayersIterator = gameSession.playersMap.values(); const gameSessionPlayersIterator = gameSession.playersMap.values();
const response = await fetch(c.addressBackEnd + "/game/newGameSession", const response = await fetch(c.addressBackEnd + "/game/gameserver/creategame",
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
id: gameSession.id, gameServerIdOfTheMatch : gameSession.id,
gameOptions: gameSession.matchOptions, gameOptions: gameSession.matchOptions,
playerOneUsername: (<ClientPlayer>gameSessionPlayersIterator.next().value).username, playerOneUsername: (<ClientPlayer>gameSessionPlayersIterator.next().value).username,
playerTwoUsername: (<ClientPlayer>gameSessionPlayersIterator.next().value).username, playerTwoUsername: (<ClientPlayer>gameSessionPlayersIterator.next().value).username,
}) })
}); });
if (!response.ok) if (!response.ok)

View File

@@ -0,0 +1,15 @@
import { IsBoolean, IsNotEmpty, IsNumber, IsString } from "class-validator";
export class CreateGameDto {
@IsString()
@IsNotEmpty()
gameServerIdOfTheMatch : string
@IsNumber()
@IsNotEmpty()
gameOptions: number
@IsString()
@IsNotEmpty()
playerOneUsername : string
@IsString()
playerTwoUsername : string
}

View File

@@ -0,0 +1,12 @@
import { IsBoolean, IsNotEmpty, IsNumber, IsString } from "class-validator";
export class UpdateGameDto {
@IsNumber()
@IsNotEmpty()
playerOneUsernameResult : number
@IsNumber()
@IsNotEmpty()
playerTwoUsernameResult : number
@IsBoolean()
isMatchIsFinished : boolean
}

View File

@@ -11,15 +11,15 @@ export class Game {
@Column() @Column()
playerTwoUsername: string playerTwoUsername: string
@Column() @Column({default : 0, nullable : true})
playerOneUsernameResult : number playerOneUsernameResult : number
@Column() @Column({default : 0, nullable : true})
playerTwoUsernameResult : number playerTwoUsernameResult : number
@Column() @Column()
gameServerIdOfTheMatch: string gameServerIdOfTheMatch: string
@Column({default: false}) //éric pourra trouver un meilleur mot : ongoing ? @Column({default: false, nullable : true}) //éric pourra trouver un meilleur mot : ongoing ?
isMatchIsFinished: boolean isMatchIsFinished: boolean
} }

View File

@@ -1,9 +1,11 @@
import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, UseGuards } from '@nestjs/common'; import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, UseGuards } from '@nestjs/common';
import { Console } from 'console';
import { request } from 'http'; import { request } from 'http';
import { use } from 'passport'; import { use } from 'passport';
import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards'; import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards';
import { User } from 'src/users/entities/user.entity'; import { User } from 'src/users/entities/user.entity';
import { UsersService } from 'src/users/users.service'; import { UsersService } from 'src/users/users.service';
import { CreateGameDto } from './dto/createGame.dto';
import { GrantTicketDto } from './dto/grantTicket.dto'; import { GrantTicketDto } from './dto/grantTicket.dto';
import { ValidateTicketDto } from './dto/validateTicket.dto'; import { ValidateTicketDto } from './dto/validateTicket.dto';
import { TokenGame } from './entity/tokenGame.entity'; import { TokenGame } from './entity/tokenGame.entity';
@@ -21,8 +23,8 @@ export class GameController {
const user : User = req.user const user : User = req.user
if (grantTicketDto.playerOneUsername != user.username) if (grantTicketDto.playerOneUsername != user.username)
return new HttpException('You can\'t request a game for another person.', 403 ) return new HttpException('You can\'t request a game for another person.', 403 )
else if (user.status !== "connected") // else if (user.status !== "connected")
return new HttpException('You must not be in game...', HttpStatus.FORBIDDEN ) // return new HttpException('You must not be in game...', HttpStatus.FORBIDDEN )
return this.gameService.generateToken(user, grantTicketDto); return this.gameService.generateToken(user, grantTicketDto);
} }
@@ -37,11 +39,12 @@ export class GameController {
//N'est valable que pour le game-serveur. //N'est valable que pour le game-serveur.
@Post('gameServer/validate') @Post('gameserver/validate')
async validateTicket(@Body() validateTicketDto : ValidateTicketDto, @Req() request) async validateTicket(@Body() validateTicketDto : ValidateTicketDto, @Req() request)
{ {
if (await this.gameService.validateToken(validateTicketDto) === false) if (await this.gameService.validateToken(validateTicketDto) === false)
return new HttpException("The token is not valid", HttpStatus.NOT_FOUND); return new HttpException("The token is not valid", HttpStatus.NOT_FOUND);
console.log("200 retourné côté nest")
return HttpStatus.OK; return HttpStatus.OK;
} }
@@ -72,4 +75,12 @@ export class GameController {
return this.gameService.findInvitations(user); return this.gameService.findInvitations(user);
} }
@Post('gameserver/creategame')
async createGame(@Body() creategameDto : CreateGameDto)
{
return this.gameService.createGame(creategameDto);
}
} }

View File

@@ -9,6 +9,7 @@ import { Game } from './entity/game.entity';
import { ValidateTicketDto } from './dto/validateTicket.dto'; import { ValidateTicketDto } from './dto/validateTicket.dto';
import { TokenGame } from './entity/tokenGame.entity'; import { TokenGame } from './entity/tokenGame.entity';
import { UsersService } from 'src/users/users.service'; import { UsersService } from 'src/users/users.service';
import { CreateGameDto } from './dto/createGame.dto';
@Injectable() @Injectable()
export class GameService { export class GameService {
@@ -37,9 +38,10 @@ export class GameService {
async generateToken(user : User, grantTicketDto : GrantTicketDto) async generateToken(user : User, grantTicketDto : GrantTicketDto)
{ {
if (user.status === "In Game") // if (user.status === "In Game")
return new HttpException("You can't play two games", HttpStatus.FORBIDDEN); // return new HttpException("You can't play two games", HttpStatus.FORBIDDEN);
else if (grantTicketDto.isGameIsWithInvitation === true) // else
if (grantTicketDto.isGameIsWithInvitation === true)
{ {
const secondUser : Partial<User> = await this.userService.findOneByUsername(user.id.toString(), grantTicketDto.playerTwoUsername) const secondUser : Partial<User> = await this.userService.findOneByUsername(user.id.toString(), grantTicketDto.playerTwoUsername)
if (!secondUser) if (!secondUser)
@@ -141,8 +143,8 @@ export class GameService {
async declineInvitation(user : User, token : string) async declineInvitation(user : User, token : string)
{ {
if (user.status === "In Game") // if (user.status === "In Game")
return new HttpException("You must finish your game before decline.", HttpStatus.FORBIDDEN) // return new HttpException("You must finish your game before decline.", HttpStatus.FORBIDDEN)
const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame') const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame')
.andWhere('tokengame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username}) .andWhere('tokengame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username})
.andWhere('tokengame.token = :token', {token : token}) .andWhere('tokengame.token = :token', {token : token})
@@ -154,8 +156,8 @@ export class GameService {
async acceptInvitation(user : User, token : string) async acceptInvitation(user : User, token : string)
{ {
if (user.status === "In Game") // if (user.status === "In Game")
return new HttpException("You must finish your game before accept.", HttpStatus.FORBIDDEN) // return new HttpException("You must finish your game before accept.", HttpStatus.FORBIDDEN)
const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokenGame') const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokenGame')
.andWhere('tokenGame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username}) .andWhere('tokenGame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username})
.andWhere('tokenGame.token = :token', {token : token}) .andWhere('tokenGame.token = :token', {token : token})
@@ -170,8 +172,8 @@ export class GameService {
} }
async requestIfAnotherUserHasRespondToquestForGame(user : User, token : string) { async requestIfAnotherUserHasRespondToquestForGame(user : User, token : string) {
if (user.status === "In Game") // if (user.status === "In Game")
return new HttpException("You can't do that.", HttpStatus.BAD_REQUEST) // return new HttpException("You can't do that.", HttpStatus.BAD_REQUEST)
const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokenGame') const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokenGame')
.where('tokenGame.token = :token', {token : token}) .where('tokenGame.token = :token', {token : token})
.andWhere('tokenGame.isSecondUserAcceptedRequest = :isSecondUserAcceptedRequest', {isSecondUserAcceptedRequest : true}) .andWhere('tokenGame.isSecondUserAcceptedRequest = :isSecondUserAcceptedRequest', {isSecondUserAcceptedRequest : true})
@@ -183,5 +185,16 @@ export class GameService {
else if (!tokenGame) else if (!tokenGame)
return new HttpException("Not Found", HttpStatus.NOT_FOUND) return new HttpException("Not Found", HttpStatus.NOT_FOUND)
} }
async createGame(creategameDto : CreateGameDto)
{
const game = this.gameRepository.create(creategameDto)
this.gameRepository.save(game);
if (!game)
return HttpStatus.INTERNAL_SERVER_ERROR
console.log("200 retourné pour la création de partie")
return HttpStatus.OK
}
} }

View File

@@ -0,0 +1,186 @@
<script lang="ts">
import * as enumeration from './shared_js/enums'
import * as constants from './client/constants'
import { initPong, initGc, initMatchOptions, initStartFunction } from './client/global'
import { GameArea } from './client/class/GameArea';
import { GameComponentsClient } from './client/class/GameComponentsClient';
import { handleInput } from './client/handleInput';
import {gameLoop} from './client/gameLoop'
import { drawLoop } from './client/draw';
import {countdown} from './client/utils'
import { initWebSocket } from './client/ws';
import { initAudio } from './client/audio';
import { pong, gc} from './client/global'
let optionsAreNotSet = true
let sound = "on"; // possible de faire un boolean avec svelte et radio buttons ?
let multi_balls = false;
let moving_walls = false;
let matchOptions : enumeration.MatchOptions = enumeration.MatchOptions.noOption;
const init = async() => {
// WIP nest, fetch token generation
// const address = "http://transcendance:8080";
// const responsePromise = fetch(address + "/token");
if (sound === "off") {
initAudio(true);
}
else if (sound === "on") {
initAudio(false);
}
console.log(sound); //debug
if (multi_balls === true) {
matchOptions |= enumeration.MatchOptions.multiBalls;
}
if (moving_walls === true) {
matchOptions |= enumeration.MatchOptions.movingWalls;
}
initMatchOptions(matchOptions);
optionsAreNotSet = false;
initPong(new GameArea());
initGc(new GameComponentsClient(matchOptions, pong.ctx));
initStartFunction(start);
// const response = await responsePromise;
// if (!response.ok) {
// console.log("Token retrieve failed"); // TODO: error message
// return;
// }
// const responseJson = await response.json();
initWebSocket(matchOptions, "yolo", "usernamePLACEHOLDER");
// ou est stocké le username dans le front svelte ?
}
function start() : void {
gc.text1.pos.assign(constants.w*0.5, constants.h*0.75);
countdown(constants.matchStartDelay/1000, (count: number) => {
gc.text1.clear();
gc.text1.text = `${count}`;
gc.text1.update();
}, resume);
}
function resume(): void {
gc.text1.text = "";
window.addEventListener('keydown', function (e) {
pong.addKey(e.key);
});
window.addEventListener('keyup', function (e) {
pong.deleteKey(e.key);
});
pong.handleInputInterval = window.setInterval(handleInput, constants.handleInputIntervalMS);
// pong.handleInputInterval = window.setInterval(sendLoop, c.sendLoopIntervalMS);
pong.gameLoopInterval = window.setInterval(gameLoop, constants.gameLoopIntervalMS);
pong.drawLoopInterval = window.setInterval(drawLoop, constants.drawLoopIntervalMS);
}
</script>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
{#if optionsAreNotSet}
<form on:submit|preventDefault={init}>
<div id="div_game_options">
<fieldset>
<legend>game options</legend>
<div>
<input type="checkbox" id="multi_balls" name="multi_balls">
<label for="multi_balls">multiples balls</label>
</div>
<div>
<input type="checkbox" id="moving_walls" name="moving_walls">
<label for="moving_walls">moving walls</label>
</div>
<div>
<!-- svelte-ignore a11y-label-has-associated-control -->
<label>sound :</label>
<input type="radio" id="sound_on" name="sound_selector" bind:group={sound} value="on">
<label for="sound_on">on</label>
<input type="radio" id="sound_off" name="sound_selector" bind:group={sound} value="off">
<label for="sound_off">off</label>
</div>
<div>
<button id="play_pong_button">PLAY</button>
</div>
</fieldset>
</div>
</form>
<div id="div_game_instructions">
<h2>--- keys ---</h2>
<p>move up: 'w' or 'up arrow'</p>
<p>move down: 's' OR 'down arrow'</p>
<p>grid on/off: 'g'</p>
</div>
{/if}
<div id="canvas_container">
<!-- <p> =) </p> -->
</div>
</body>
<style>
@font-face {
font-family: "Bit5x3";
src:
url("/fonts/Bit5x3.woff2") format("woff2"),
local("Bit5x3"),
url("/fonts/Bit5x3.woff") format("woff");
font-weight: normal;
font-style: normal;
font-display: swap;
}
body {
margin: 0;
background-color: #222425;
}
#canvas_container {
margin-top: 20px;
text-align: center;
/* border: dashed rgb(245, 245, 245) 5px; */
/* max-height: 80vh; */
/* overflow: hidden; */
}
#div_game_instructions {
text-align: center;
font-family: "Bit5x3";
color: rgb(245, 245, 245);
font-size: large;
}
#div_game_options {
margin-top: 20px;
text-align: center;
font-family: "Bit5x3";
color: rgb(245, 245, 245);
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: rgb(245, 245, 245);
background-color: #333333;
font-size: x-large;
padding: 10px;
}
canvas {
background-color: #333333;
max-width: 75vw;
/* max-height: 100vh; */
width: 80%;
}
</style>

View File

@@ -20,21 +20,13 @@
let user; let user;
let allUsers; let allUsers;
//init function
let isSecondPlayerAnsweredYes = false;
let isSecondPlayerRefused = false;
let isSomethingWentWrong = true;
//Game's stuff nest side //Game's stuff nest side
let optionsAreNotSet = true; let optionsAreNotSet = true;
let invite_someone = false; let isSomeoneIsIvited = false;
let playerTwoUsername = ""; let playerTwoUsername = "";
let token = "";
//Game's stuff gameserver side //Game's stuff gameserver side
let sound = ""; let sound = "on";
let multi_balls = false; let multi_balls = false;
let moving_walls = false; let moving_walls = false;
let matchOption : enumeration.MatchOptions = enumeration.MatchOptions.noOption; let matchOption : enumeration.MatchOptions = enumeration.MatchOptions.noOption;
@@ -44,6 +36,7 @@
let showInvitations = false; let showInvitations = false;
let showGameOption = true; let showGameOption = true;
let showError = false; let showError = false;
let showCanvas = false;
let isThereAnyInvitation = false; let isThereAnyInvitation = false;
let invitations; let invitations;
@@ -51,8 +44,6 @@
let waitingMessage = "Please wait..." let waitingMessage = "Please wait..."
let errorMessageWhenAttemptingToGetATicket = ""; let errorMessageWhenAttemptingToGetATicket = "";
let responseToCheckIfOtherUserHasAnswered;
onMount( async() => { onMount( async() => {
user = await fetch('http://transcendance:8080/api/v2/user') user = await fetch('http://transcendance:8080/api/v2/user')
.then( x => x.json() ); .then( x => x.json() );
@@ -68,23 +59,24 @@
matchOption |= enumeration.MatchOptions.multiBalls matchOption |= enumeration.MatchOptions.multiBalls
if (moving_walls === true ) if (moving_walls === true )
matchOption |= enumeration.MatchOptions.movingWalls matchOption |= enumeration.MatchOptions.movingWalls
const res = await fetch("http://transcendance:8080/api/v2/game/ticket", {
const responseWhenGrantToken = fetch("http://transcendance:8080/api/v2/game/ticket", {
method : "POST", method : "POST",
headers : {'Content-Type': 'application/json'}, headers : {'Content-Type': 'application/json'},
body : JSON.stringify({ body : JSON.stringify({
playerOneUsername : user.username, playerOneUsername : user.username,
playerTwoUsername : playerTwoUsername, playerTwoUsername : playerTwoUsername,
gameOptions : matchOption, gameOptions : matchOption,
isGameIsWithInvitation : invite_someone isGameIsWithInvitation : isSomeoneIsIvited
}) })
}) })
.then(x => x.json()) const responseFromServer = await responseWhenGrantToken;
.catch(error => { console.log("Response.ok : " + responseFromServer.ok )
console.log(error) console.log("//")
}) const responseInjson = await responseFromServer.json()
if (res.status === 403 || res.status === 404 || res.status === 500) if (!responseFromServer.ok || !responseInjson.token)
{ {
errorMessageWhenAttemptingToGetATicket = res.message; errorMessageWhenAttemptingToGetATicket = responseInjson.message;
showError = true; showError = true;
setTimeout(() => { setTimeout(() => {
showError = false; showError = false;
@@ -92,40 +84,27 @@
optionsAreNotSet = true optionsAreNotSet = true
playerTwoUsername = ""; playerTwoUsername = "";
matchOption = 0; matchOption = 0;
token = ""
}, 5000) }, 5000)
return ;
} }
else if (res.status === 200) else
{ {
initAudio(sound) showError = false
showWaitPage = false
const token = responseInjson.token
console.log("Token === " + token)
if (sound === "off") {
initAudio(true);
}
else if (sound === "on") {
initAudio(false);
}
initMatchOptions(matchOption) initMatchOptions(matchOption)
initPong(new GameArea()) initPong(new GameArea())
initGc(new GameComponentsClient(matchOption, pong.ctx)) initGc(new GameComponentsClient(matchOption, pong.ctx))
initStartFunction(start) initStartFunction(start)
initWebSocket(matchOption) console.log("Avant init websocket")
initWebSocket(matchOption, token, user.username)
} }
// const fetch = await fetch("http://transcendance:8080/api/v2/game/gameServer/validate", {
// method : "POST",
// headers : {'Content-Type': 'application/json'},
// body : JSON.stringify({
// playerOneUsername : user.username,
// playerTwoUsername : playerTwoUsername,
// gameOptions : matchOption,
// isGameIsWithInvitation : invite_someone,
// token : token
// })
// })
// .then(x => x.json())
// .catch(error => {
// console.log(error)
// })
// if (res.status !== 200)
// {
// showError = true;
// errorMessageWhenAttemptingToGetATicket = "Your session is not valid. Please try again."
// return ;
// }
} }
function start() : void { function start() : void {
@@ -134,10 +113,10 @@
gc.text1.clear(); gc.text1.clear();
gc.text1.text = `${count}`; gc.text1.text = `${count}`;
gc.text1.update(); gc.text1.update();
}, resume); }, responseWhenGrantTokenume);
} }
function resume(): void { function responseWhenGrantTokenume(): void {
gc.text1.text = ""; gc.text1.text = "";
window.addEventListener('keydown', function (e) { window.addEventListener('keydown', function (e) {
pong.addKey(e.key); pong.addKey(e.key);
@@ -160,6 +139,7 @@
showInvitations = true; showInvitations = true;
invitations = await fetch("http://transcendance:8080/api/v2/game/invitations") invitations = await fetch("http://transcendance:8080/api/v2/game/invitations")
.then(x => x.json()) .then(x => x.json())
console.log(...invitations)
} }
const rejectInvitation = async() => { const rejectInvitation = async() => {
@@ -188,12 +168,13 @@
<body> <body>
<div id="preload_font">.</div> <div id="preload_font">.</div>
{#if showError === true} {#if showError === true}
<div id="div_game"> <div id="div_game">
<fieldset> <fieldset>
<legend>Error</legend> <legend>Error</legend>
<p>{errorMessageWhenAttemptingToGetATicket}</p> <p>{errorMessageWhenAttemptingToGetATicket}</p>
<button id="pong_button" on:click={() => push('/game')}>Retry</button> <button id="pong_button">Retry</button>
</fieldset> </fieldset>
</div> </div>
{/if} {/if}
@@ -223,14 +204,18 @@
<label for="moving_walls">Moving walls</label> <label for="moving_walls">Moving walls</label>
</div> </div>
<div> <div>
<input type="checkbox" id="moving_walls" name="moving_walls" bind:checked={sound}> <!-- svelte-ignore a11y-label-has-associated-control -->
<label for="moving_walls">Sound</label> <label>sound :</label>
<input type="radio" id="sound_on" name="sound_selector" bind:group={sound} value="on">
<label for="sound_on">on</label>
<input type="radio" id="sound_off" name="sound_selector" bind:group={sound} value="off">
<label for="sound_off">off</label>
</div> </div>
<div> <div>
<input type="checkbox" id="invite_someone" name="moving_walls" bind:checked={invite_someone}> <input type="checkbox" id="isSomeoneIsIvited" name="moving_walls" bind:checked={isSomeoneIsIvited}>
<label for="moving_walls">Invite a friend</label> <label for="moving_walls">Invite a friend</label>
</div> </div>
{#if invite_someone === true} {#if isSomeoneIsIvited === true}
<select bind:value={playerTwoUsername}> <select bind:value={playerTwoUsername}>
{#each allUsers as user } {#each allUsers as user }
<option value={user.username}>{user.username}</option> <option value={user.username}>{user.username}</option>
@@ -266,12 +251,13 @@
</div> </div>
{/if} {/if}
{/if} {/if}
<div id="canvas_container"> <div id="canvas_container">
<!-- <p> =) </p> --> <canvas id="gameArea"></canvas>
</div> </div>
</body> </body>
<style> <style>
@font-face { @font-face {
@@ -312,6 +298,7 @@ body {
color: rgb(143, 19, 19); color: rgb(143, 19, 19);
font-size: x-large; font-size: x-large;
} }
#div_game fieldset { #div_game fieldset {
max-width: 50vw; max-width: 50vw;
width: auto; width: auto;
@@ -328,7 +315,7 @@ body {
padding: 10px; padding: 10px;
} }
canvas { canvas {
background-color: #333333; background-color: #ff0000;
max-width: 75vw; max-width: 75vw;
/* max-height: 100vh; */ /* max-height: 100vh; */
width: 80%; width: 80%;

View File

@@ -9,13 +9,14 @@ export class GameArea {
canvas: HTMLCanvasElement; canvas: HTMLCanvasElement;
ctx: CanvasRenderingContext2D; ctx: CanvasRenderingContext2D;
constructor() { constructor() {
this.canvas = document.createElement("canvas"); this.canvas = document.getElementById("gameArea");
if (this.canvas)
console.log("Le canvas a été trouvé !")
else
console.log("Le canvas a été mangé par un être mystérieux...")
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");
if (container)
container.insertBefore(this.canvas, container.childNodes[0]);
} }
addKey(key: string) { addKey(key: string) {
key = key.toLowerCase(); key = key.toLowerCase();