diff --git a/frontend/static/css/game.css b/frontend/static/css/game.css new file mode 100644 index 0000000..daf5c35 --- /dev/null +++ b/frontend/static/css/game.css @@ -0,0 +1,7 @@ +#canva { + background-color: white; + border: 1px; + display: block; + margin-left: auto; + margin-right: auto; +} \ No newline at end of file diff --git a/frontend/static/js/api/Game.js b/frontend/static/js/api/game/Game.js similarity index 59% rename from frontend/static/js/api/Game.js rename to frontend/static/js/api/game/Game.js index daf6cf7..ae9023a 100644 --- a/frontend/static/js/api/Game.js +++ b/frontend/static/js/api/game/Game.js @@ -1,3 +1,5 @@ +import { GameConfig } from "./GameConfig.js" + class Game { /** @@ -27,6 +29,22 @@ class Game this.finished = response_data.finished; this.winner_id = this.finished ? response_data.winner_id : undefined; + //TODO invert line + if (false) + //if (this.finished === true || this.started === false) + return 0; + + this.config = new GameConfig(this.client); + + let ret = await this.config.init(); + if (ret) + return ret; + + this.players = response_data.players; + + this.ball_pos_x = this.config.ball_spawn_x; + this.ball_pos_y = this.config.ball_spawn_y; + return 0; } } diff --git a/frontend/static/js/api/game/GameConfig.js b/frontend/static/js/api/game/GameConfig.js new file mode 100644 index 0000000..8c0e9f4 --- /dev/null +++ b/frontend/static/js/api/game/GameConfig.js @@ -0,0 +1,43 @@ +class GameConfig +{ + /** + * @param {Client} client + */ + constructor(client) + { + /** + * @type {Client} + */ + this.client = client; + } + + async init() + { + let response = await this.client._get("/api/games/"); + + if (response.status !== 200) + return response.status; + + let response_data = await response.json(); + + + this.size_x = response_data.MAP_SIZE_X; + this.size_y = response_data.MAP_SIZE_Y; + this.center_x = this.size_x / 2; + this.center_y = this.size_y / 2; + + this.paddle_ratio = response_data.PADDLE_RATIO; + this.wall_ratio = response_data.WALL_RATIO; + + this.ball_speed_inc = response_data.BALL_SPEED_INC; + this.ball_speed_start = response_data.BALL_SPEED_START; + + this.ball_size = response_data.BALL_SIZE; + this.ball_spawn_x = this.center_x; + this.ball_spawn_y = this.center_y; + + return 0; + } +} + +export { GameConfig } \ No newline at end of file diff --git a/frontend/static/js/views/GameView.js b/frontend/static/js/views/GameView.js index bfd2a78..709b18f 100644 --- a/frontend/static/js/views/GameView.js +++ b/frontend/static/js/views/GameView.js @@ -1,5 +1,5 @@ import { client } from "../index.js"; -import { Game } from "../api/Game.js"; +import { Game } from "../api/game/Game.js"; import AbstractView from "./abstracts/AbstractView.js"; export default class extends AbstractView @@ -10,24 +10,137 @@ export default class extends AbstractView this.game = new Game(client, params.id); } + draw_wall(ctx, stop_x, stop_y) + { + ctx.lineTo(stop_x, stop_y); + } + + draw_paddle(ctx, rail_start_x, rail_start_y, rail_stop_x, rail_stop_y, pos) + { + let rail_size = Math.abs(rail_stop_x - rail_start_x) + Math.abs(rail_stop_y - rail_start_y) + + let paddle_size = rail_size * this.game.config.paddle_ratio; + + console.log(paddle_size) + + let diff_x = rail_stop_x - rail_start_x, + diff_y = rail_stop_y - rail_start_y; + + console.log("diff", diff_x, diff_y) + + let pos_x = rail_start_x + diff_x * pos, + pos_y = rail_start_y + diff_y * pos; + + console.log("pos", pos_x, pos_y) + + let start_x = pos_x - paddle_size * (diff_x * (paddle_size / rail_size)), + start_y = pos_y - paddle_size * (diff_y * (paddle_size / rail_size)), + stop_x = pos_x + paddle_size * (diff_x * (paddle_size / rail_size)), + stop_y = pos_y + paddle_size * (diff_y * (paddle_size / rail_size)); + + console.log(start_x, start_y, stop_x, stop_y); + ctx.moveTo(start_x, start_y); + ctx.lineTo(stop_x, stop_y); + + ctx.moveTo(rail_stop_x, rail_stop_y); + } + + draw_ball(ctx, x, y) + { + ctx.rect(x, y, this.game.config.ball_size, this.game.config.ball_size); + } + + draw_sides(ctx, nb_sides) + { + let start_x, + start_y, + stop_x, + stop_y; + + for (let i = 0; i <= nb_sides; i++) + { + let angle = (i * 2 * Math.PI / nb_sides) + (Math.PI / 4); + + stop_x = this.game.config.center_x + 400 * Math.cos(angle); + stop_y = this.game.config.center_y + 400 * 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.draw_paddle(ctx, start_x, start_y, stop_x, stop_y, 0.5); + + start_x = stop_x; + start_y = stop_y; + } + } + + draw_game() + { + let ctx = document.getElementById('canva').getContext('2d'); + + ctx.beginPath() + + this.draw_sides(ctx, (this.game.players_id.length +10) * 2); + this.draw_ball(ctx, this.game.ball_pos_x, this.game.ball_pos_y); + + ctx.strokeStyle = "#000000"; + ctx.lineWidth = 4; + ctx.stroke(); + } + + render_game() + { + while (true) + { + this.draw_game(); + break; + } + } + + start_game() + { + let canva = document.createElement("canvas"); + + canva.height = this.game.config.size_x; + canva.width = this.game.config.size_y; + canva.id = "canva"; + + document.getElementById("app").appendChild(canva); + + this.render_game(); + } + + async update_game_state() + { + await this.game.init(); + + document.getElementById("game-state").innerText = this.game.state; + + //TODO invert line + //if (this.game.started === true && this.game.finished === false) + if (true) + this.start_game(); + } + async postInit() { let error_code = await this.game.init(); if (error_code) return error_code; + + await this.update_game_state(); } async getHtml() { - return ` -
- Fugiat voluptate et nisi Lorem cillum anim sit do eiusmod occaecat irure do. Reprehenderit anim fugiat sint exercitation consequat. Sit anim laborum sit amet Lorem adipisicing ullamco duis. Anim in do magna ea pariatur et. -
-- View recent posts. -
+ return /* HTML */ ` + + + `; } } diff --git a/games/config.py b/games/config.py index feed4aa..134c484 100644 --- a/games/config.py +++ b/games/config.py @@ -1,8 +1,10 @@ PADDLE_SPEED_MAX = 1 -PADDLE_SIZE_HEIGHT = 10 -PADDLE_SIZE_WIDTH = 100 +PADDLE_RATIO = 0.1 -PADDLE_RAIL = PADDLE_SIZE_WIDTH * 5 +MAP_SIZE_X = 900 +MAP_SIZE_Y = 900 + +WALL_RATIO = 1 BALL_SPEED_INC = 1 BALL_SPEED_START = 1 diff --git a/games/views.py b/games/views.py index 2675031..0ad580d 100644 --- a/games/views.py +++ b/games/views.py @@ -10,13 +10,17 @@ class GameConfigView(APIView): permission_classes = (permissions.AllowAny,) - def get(self, request): + def get(self, request: HttpRequest): config_data = { - "BALL_SIZE": config.BALL_SIZE, + "MAP_SIZE_X": config.MAP_SIZE_X, + "MAP_SIZE_Y": config.MAP_SIZE_Y, + + "WALL_RATIO": config.WALL_RATIO, + "PADDLE_SPEED_MAX": config.PADDLE_SPEED_MAX, - "PADDLE_SIZE_HEIGHT": config.PADDLE_SIZE_HEIGHT, - "PADDLE_SIZE_WIDTH": config.PADDLE_SIZE_WIDTH, - "PADDLE_RAIL": config.PADDLE_RAIL, + "PADDLE_RATIO": config.PADDLE_RATIO, + + "BALL_SIZE": config.BALL_SIZE, "BALL_SPEED_INC": config.BALL_SPEED_INC, "BALL_SPEED_START": config.BALL_SPEED_START }