From a7fff2f1a2e51ac407d6fe5ca4677a90356d4b02 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Thu, 22 Feb 2024 06:01:56 +0100 Subject: [PATCH] 3D working --- frontend/static/js/3D/cube.js | 8 +++++- frontend/static/js/3D/shaders.js | 2 +- frontend/static/js/api/game/Ball.js | 9 +++--- frontend/static/js/api/game/Game.js | 4 +-- frontend/static/js/api/game/GameConfig.js | 8 +++--- frontend/static/js/api/game/Player.js | 11 ++++---- frontend/static/js/api/game/Point.js | 4 +-- frontend/static/js/api/game/Segment.js | 21 ++++++++------ frontend/static/js/api/game/Wall.js | 8 +++--- frontend/static/js/index.js | 4 +-- frontend/static/js/views/GameView.js | 7 +++++ frontend/static/js/views/GameView3D.js | 31 +++++++++++++-------- frontend/static/js/views/MatchMakingView.js | 4 +-- 13 files changed, 71 insertions(+), 50 deletions(-) diff --git a/frontend/static/js/3D/cube.js b/frontend/static/js/3D/cube.js index 8fc59fa..6bfb80d 100644 --- a/frontend/static/js/3D/cube.js +++ b/frontend/static/js/3D/cube.js @@ -14,7 +14,7 @@ function renderCube(ctx, x, y, z, angle = 0, sx = 1, sy = 1, sz = 1) modelMatrix, modelMatrix, angle, - [0, 1, 1], + [0, 1, 0], ); mat4.scale( @@ -23,6 +23,12 @@ function renderCube(ctx, x, y, z, angle = 0, sx = 1, sy = 1, sz = 1) [sx, sy, sz] ); + mat4.translate( + modelMatrix, + modelMatrix, + [-1, 0, 0] // wtf, this works ? + ); + const normalMatrix = mat4.create(); mat4.invert(normalMatrix, modelMatrix); mat4.transpose(normalMatrix, normalMatrix); diff --git a/frontend/static/js/3D/shaders.js b/frontend/static/js/3D/shaders.js index 641364b..638ebbb 100644 --- a/frontend/static/js/3D/shaders.js +++ b/frontend/static/js/3D/shaders.js @@ -15,7 +15,7 @@ const vertex_shader_source = ` highp vec3 ambientLight = vec3(0.3, 0.3, 0.3); highp vec3 directionalLightColor = vec3(1, 1, 1); - highp vec3 directionalVector = normalize(vec3(1, 15, -1.75)); + highp vec3 directionalVector = vec3(-10, 2, -10); highp vec4 transformedNormal = uNormalMat * vec4(aNormal, 1.0); diff --git a/frontend/static/js/api/game/Ball.js b/frontend/static/js/api/game/Ball.js index 40ae9c3..f373e26 100644 --- a/frontend/static/js/api/game/Ball.js +++ b/frontend/static/js/api/game/Ball.js @@ -52,9 +52,10 @@ class Ball } else if(ctx instanceof WebGLRenderingContext) { - const posx = (this.position.x - this.size / 2) / 2; - const posy = (this.position.y - this.size / 2) / 2; - renderCube(ctx, posx, 0, posy, 0, this.size * 5, this.size * 5, this.size * 5); + const size = this.size * 3; + const posx = (this.position.x - this.size / 2) - this.game.config.size_x / 2; + const posy = (this.position.y - this.size / 2) - this.game.config.size_y / 2; + renderCube(ctx, posx, 0, posy, 0, size, size, size); } else { @@ -76,7 +77,7 @@ class Ball this.draw(ctx); } - from_json (data) + from_json(data) { this.position = this.position.from_json(data.position); this.size = data.size; diff --git a/frontend/static/js/api/game/Game.js b/frontend/static/js/api/game/Game.js index 7ca43d2..cba955c 100644 --- a/frontend/static/js/api/game/Game.js +++ b/frontend/static/js/api/game/Game.js @@ -75,7 +75,7 @@ class Game * @type {GameConfig} */ this.config = new GameConfig(this.client); - + let ret = await this.config.init(); if (ret !== 0) @@ -186,7 +186,7 @@ class Game this.walls = []; const walls_data = data.walls; walls_data.forEach((wall_data) => { - this.walls.push(new Wall().from_json(wall_data)); + this.walls.push(new Wall(this).from_json(wall_data)); }); /** diff --git a/frontend/static/js/api/game/GameConfig.js b/frontend/static/js/api/game/GameConfig.js index e89a784..bf49c63 100644 --- a/frontend/static/js/api/game/GameConfig.js +++ b/frontend/static/js/api/game/GameConfig.js @@ -14,8 +14,8 @@ class GameConfig async init() { let response = await this.client._get("/api/games/"); - - if (response.status !== 200) + + if (response.status !== 200) return response.status; let response_data = await response.json(); @@ -24,7 +24,7 @@ class GameConfig * @type {Number} */ this.size_x = response_data.MAP_SIZE_X; - + /** * @type {Number} */ @@ -86,4 +86,4 @@ class GameConfig } } -export { GameConfig }; \ No newline at end of file +export { GameConfig }; diff --git a/frontend/static/js/api/game/Player.js b/frontend/static/js/api/game/Player.js index 889c80b..065bd80 100644 --- a/frontend/static/js/api/game/Player.js +++ b/frontend/static/js/api/game/Player.js @@ -1,7 +1,6 @@ import { Game } from "./Game.js"; import { Point } from "./Point.js"; import { Segment } from "./Segment.js"; -import { renderCube } from "../../3D/cube.js" class Player { @@ -44,7 +43,7 @@ class Player /** * @type {Segment} */ - this.rail = rail === undefined ? new Segment() : rail; + this.rail = rail === undefined ? new Segment(game) : rail; /** * @type {String} @@ -89,12 +88,12 @@ class Player paddle_start_y = paddle_center.y - (diff_y * (paddle_length / 2 / rail_length)), paddle_stop_x = paddle_center.x + (diff_x * (paddle_length / 2 / rail_length)), paddle_stop_y = paddle_center.y + (diff_y * (paddle_length / 2 / rail_length)); - + let paddle_start = new Point(paddle_start_x, paddle_start_y), paddle_stop = new Point (paddle_stop_x, paddle_stop_y); - - let paddle = new Segment(paddle_start, paddle_stop); - + + let paddle = new Segment(this.game, paddle_start, paddle_stop); + paddle.draw(ctx); } diff --git a/frontend/static/js/api/game/Point.js b/frontend/static/js/api/game/Point.js index 1ee59d2..ce163b8 100644 --- a/frontend/static/js/api/game/Point.js +++ b/frontend/static/js/api/game/Point.js @@ -1,5 +1,3 @@ - - class Point { /** @@ -27,4 +25,4 @@ class Point } } -export { Point }; \ No newline at end of file +export { Point }; diff --git a/frontend/static/js/api/game/Segment.js b/frontend/static/js/api/game/Segment.js index d33bdb6..a0dba7b 100644 --- a/frontend/static/js/api/game/Segment.js +++ b/frontend/static/js/api/game/Segment.js @@ -7,13 +7,15 @@ class Segment * @param {Point} start * @param {Point} stop */ - constructor(start, stop) + constructor(game, start, stop) { /** * @type {Point} */ this.start = start === undefined ? new Point() : start; + this.game = game; + /** * @type {Point} */ @@ -37,11 +39,8 @@ class Segment return (x ** 2 + y ** 2) ** (1 / 2); } - /** - * @param {CanvasRenderingContext2D} ctx - */ - draw(ctx) - { + draw(ctx) + { if(ctx instanceof CanvasRenderingContext2D) { ctx.moveTo(this.start.x, this.start.y); @@ -49,19 +48,23 @@ class Segment } else if(ctx instanceof WebGLRenderingContext) { - renderCube(ctx, this.start.x, -3, this.start.y, 0, 0.5, 0.5, 0.5); + const size = this.game.config.ball_size * 2; + const sizex = this.len() / 2; + const posx = (this.start.x - this.game.config.center_x); + const posy = (this.start.y - this.game.config.center_y); + renderCube(ctx, posx, 0, posy, -this.angle(), sizex, size, size); } else { alert('Unknown rendering context type'); } - } + } from_json(data) { this.start = this.start.from_json(data.start); this.stop = this.stop.from_json(data.stop); - + return this; } } diff --git a/frontend/static/js/api/game/Wall.js b/frontend/static/js/api/game/Wall.js index 2cb46a6..1db93ea 100644 --- a/frontend/static/js/api/game/Wall.js +++ b/frontend/static/js/api/game/Wall.js @@ -5,18 +5,18 @@ class Wall /** * @param {Segment} start */ - constructor (rail) + constructor (game, rail) { /** * @type {Segment} */ - this.rail = rail === undefined ? new Segment() : rail; + this.rail = rail === undefined ? new Segment(game) : rail; } - draw(ctx) + draw(ctx) { this.rail.draw(ctx); - } + } from_json(data) { diff --git a/frontend/static/js/index.js b/frontend/static/js/index.js index 6af61cb..c6491a8 100644 --- a/frontend/static/js/index.js +++ b/frontend/static/js/index.js @@ -90,8 +90,8 @@ const router = async(uri) => { { path: "/matchmaking", view: MatchMakingView }, { path: "/games/offline", view: GameOfflineView }, { path: "/tictactoe", view: TicTacToeView }, - { path: "/games/0/:id", view: GameView2D }, - { path: "/games/1/:id", view: GameView3D }, + { path: "/games/:id/0", view: GameView2D }, + { path: "/games/:id/1", view: GameView3D }, ]; // Test each route for potential match diff --git a/frontend/static/js/views/GameView.js b/frontend/static/js/views/GameView.js index 3d20f86..67aa36b 100644 --- a/frontend/static/js/views/GameView.js +++ b/frontend/static/js/views/GameView.js @@ -145,6 +145,11 @@ export default class extends AbstractView }); } + toggle3D() + { + window.location.replace(location.href.substring(0, location.href.lastIndexOf('/')) + "/1"); + } + async postInit() { let error_code = await this.game.init(); @@ -154,6 +159,7 @@ export default class extends AbstractView await this.update_game_state(); this.display_players_list(); + document.getElementById("game-mode").onclick = this.toggle3D; } async leavePage() @@ -171,6 +177,7 @@ export default class extends AbstractView return /* HTML */ `

+ diff --git a/frontend/static/js/views/GameView3D.js b/frontend/static/js/views/GameView3D.js index d4755d6..42c3aa7 100644 --- a/frontend/static/js/views/GameView3D.js +++ b/frontend/static/js/views/GameView3D.js @@ -4,28 +4,28 @@ import AbstractView from "./abstracts/AbstractView.js"; import { initShaderProgram, shaderInfos } from "../3D/shaders.js" import { initBuffers } from "../3D/buffers.js" import "../3D/maths/gl-matrix-min.js" -import { renderCube } from "../3D/cube.js" import { MyPlayer } from "../api/game/MyPlayer.js"; import { lang } from "../index.js"; +import { navigateTo } from "../index.js"; export default class extends AbstractView { constructor(params) { super(params, "Game"); - this.game = new Game(client, params.id); + this.game = new Game(client, params.id, this.update_goal); this.keys_pressed = []; this.my_player = undefined; this.gl = null; this.shader_prog = null; this.buffers = null; - this.cam_pos = [0, 500, 0]; + this.cam_pos = [0, 400, 0]; this.cam_target = [0, 0, 0]; - this.cam_up = [1, 0, 0]; + this.cam_up = [0, 0, -1]; } keyReleaseHandler(event) - { + { const idx = this.keys_pressed.indexOf(event.key); if (idx != -1) this.keys_pressed.splice(idx, 1); @@ -39,7 +39,7 @@ export default class extends AbstractView initGL() { - const canvas = document.getElementById('glcanva'); + const canvas = document.getElementById('canva'); this.gl = canvas.getContext("webgl"); if(this.gl === null) @@ -51,8 +51,8 @@ export default class extends AbstractView this.shader_prog = initShaderProgram(this.gl); this.buffers = initBuffers(this.gl); - this.gl.enable(this.gl.CULL_FACE); - this.gl.cullFace(this.gl.BACK); + //this.gl.enable(this.gl.CULL_FACE); + //this.gl.cullFace(this.gl.BACK); } update_goal(data) @@ -82,7 +82,7 @@ export default class extends AbstractView canvas.height = this.game.config.size_x; canvas.width = this.game.config.size_y; - canvas.id = "glcanva"; + canvas.id = "canva"; document.getElementById("app").appendChild(canvas); @@ -99,7 +99,7 @@ export default class extends AbstractView this.game.players[index] = this.my_player; } - this.register_key(); + this.register_key(); this.initGL(); @@ -108,7 +108,7 @@ export default class extends AbstractView draw() { - const canvas = document.getElementById('glcanva'); + const canvas = document.getElementById('canva'); if(canvas === null) return 1; @@ -217,6 +217,11 @@ export default class extends AbstractView }); } + toggle2D() + { + window.location.replace(location.href.substring(0, location.href.lastIndexOf('/')) + "/0"); + } + async postInit() { let error_code = await this.game.init(); @@ -224,8 +229,9 @@ export default class extends AbstractView if (error_code) return error_code; - await this.update_game_state(); await this.update_game_state(); + this.display_players_list(); + document.getElementById("game-mode").onclick = this.toggle2D; } async leavePage() @@ -243,6 +249,7 @@ export default class extends AbstractView return /* HTML */ `

+
diff --git a/frontend/static/js/views/MatchMakingView.js b/frontend/static/js/views/MatchMakingView.js index 07a0b2f..6c94fe0 100644 --- a/frontend/static/js/views/MatchMakingView.js +++ b/frontend/static/js/views/MatchMakingView.js @@ -51,7 +51,7 @@ export default class extends AbstractAuthenticatedView { { if (data.detail === "game_found") { - navigateTo(`/games/${this.game_mode}/${data.game_id}`); + navigateTo(`/games/${data.game_id}/${this.game_mode}`); return; } this.display_data(data); @@ -95,7 +95,7 @@ export default class extends AbstractAuthenticatedView { ["change", "oninput"].forEach((event_name) => { input.addEventListener(event_name, update); }); - document.getElementById("game-mode").onclick = this.press_button_game_mode.bind(this) + document.getElementById("game-mode").onclick = this.press_button_game_mode.bind(this); } async getHtml() {