import { Ball } from "./Ball.js"; import { GameConfig } from "./GameConfig.js" import { MyPlayer } from "./MyPlayer.js"; import { Player } from "./Player.js"; class Game { /** * @param {Client} client */ constructor(client, id) { /** * @type {Client} */ this.client = client; this.id = id; this.keys_pressed = []; this.last_pos = null } 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.players = []; response_data.players_id.forEach(player_id => { let player = new Player(player_id, 0.5, 0, this, 0, 0, 0, 0); this.players.push(player); }); this.ball = new Ball(this); return 0; } draw_wall(ctx, stop_x, stop_y) { ctx.lineTo(stop_x, stop_y); } draw_sides(ctx, nb_sides) { let start_x, start_y, stop_x, stop_y; let radius = Math.min(this.config.size_x, this.config.size_y) / 2 - 10; for (let i = 0; i <= nb_sides; i++) { let angle = (i * 2 * Math.PI / nb_sides) + (Math.PI * 3 / 4); stop_x = this.config.center_x + radius * Math.cos(angle); stop_y = this.config.center_y + radius * Math.sin(angle); if (i == 0) ctx.moveTo(stop_x, start_y); if (i % 2 == 0) this.draw_wall(ctx, stop_x, stop_y); else this.players[(i - 1) / 2].draw(ctx); start_x = stop_x; start_y = stop_y; } } draw(ctx) { ctx.beginPath() ctx.clearRect(0, 0, this.config.size_x, this.config.size_y); this.draw_sides(ctx, (this.players_id.length) * 2); this.ball.draw(ctx); ctx.strokeStyle = "#000000"; ctx.lineWidth = 10; ctx.stroke(); } _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_ball(data) { this.ball.position_x = data.position_x; this.ball.position_y = data.position_y; this.ball.velocity_x = data.velocity_x; this.ball.velocity_y = data.velocity_y; } _update(data) { console.log("bozo2", data) if (data.detail === "update_paddles") this._update_paddles(data); else if (data.detail === "update_ball") this._update_ball(data); } 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); }; } leave() { this._socket.close(); this._socket = undefined; } } export { Game }