import { sleep } from "../../utils/sleep.js"; import { Ball } from "./Ball.js"; import { GameConfig } from "./GameConfig.js" import { MyPlayer } from "./MyPlayer.js"; import { Player } from "./Player.js"; import { Time } from "./Time.js"; import { Wall } from "./Wall.js"; class Game { /** * @param {Client} client */ constructor(client, id) { /** * @type {Client} */ this.client = client; this.id = id; } async init() { let response = await this.client._get(`/api/games/${this.id}`); if (response.status !== 200) return response.status; let response_data = await response.json(); this.players_id = response_data.players_id; this.state = response_data.state; this.started = response_data.started; this.finished = response_data.finished; this.winner_id = this.finished ? response_data.winner_id : undefined; if (this.finished === true || this.started === false) return 0; this.config = new GameConfig(this.client); let ret = await this.config.init(); if (ret !== 0) return ret; this.time = new Time(); this.last_pos = null this._inited = false; return 0; } draw_sides(ctx) { this.walls.forEach(wall => { wall.draw(ctx); }); this.players.forEach(player => { player.draw(ctx); }); } draw(ctx) { ctx.clearRect(0, 0, this.config.size_x, this.config.size_y); this.draw_sides(ctx); this.ball.draw(ctx); } _send(data) { if (this._socket === undefined) return; const loop_id = setInterval(() => { if (this._socket.readyState === WebSocket.OPEN) { this._socket.send(JSON.stringify(data)); clearInterval(loop_id); } }, 500); } _send_paddle(position, time) { if (this.last_pos !== null && this.last_pos.time >= time) return; this.last_pos = {"time": time, "position": position}; this._send({"detail": "update_my_paddle_pos", ...this.last_pos}); } _update_paddles(data) { console.log(data) data.players.forEach((player_data) => { let player = this.players.find((player) => player.id === player_data.id); if (player === null) return player.update_pos(player_data.position, player_data.time); }) } _update(data) { if (data.detail === "update_paddles") this._update_paddles(data); else if (data.detail === "update_ball") this._update_ball(data); else if (data.detail === "init_game") this._init_game(data) } _init_game(data) { const ball_data = data.ball; this.ball = new Ball(this, ball_data.position_x, ball_data.position_y, ball_data.velocity_x, ball_data.velocity_y); this.walls = []; const walls_data = data.walls; walls_data.forEach((wall_data) => { this.walls.push(new Wall(wall_data.rail_start_x, wall_data.rail_start_y, wall_data.rail_stop_x, wall_data.rail_stop_y)); }); this.players = [] const players_data = data.players; players_data.forEach((player_data) => { this.players.push(new Player(player_data.user_id, this, player_data.rail_start_x, player_data.rail_start_y, player_data.rail_stop_x, player_data.rail_stop_y, player_data.nb_goal, player_data.position )); }); this._inited = true; } async wait_init() { while (this._inited !== true) await sleep(100); } async join() { if (this.started !== true || this.finished === true) { console.error("The Game is not currently ongoing."); return; } let url = `${window.location.protocol[4] === 's' ? 'wss' : 'ws'}://${window.location.host}/ws/games/${this.id}`; this._socket = new WebSocket(url); this._socket.onmessage = (event) => { const data = JSON.parse(event.data); this._update(data); }; return this.wait_init(); } leave() { this._socket.close(); this._socket = undefined; } } export { Game }