Oupsie
This commit is contained in:
@ -1,34 +0,0 @@
|
||||
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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
export { Game }
|
@ -20,7 +20,7 @@ class Account
|
||||
|
||||
if (response_data == "user created")
|
||||
{
|
||||
this._logged = true;
|
||||
await this.client._update_logged(true);
|
||||
return null;
|
||||
}
|
||||
return response_data
|
||||
@ -31,13 +31,13 @@ class Account
|
||||
let response = await this.client._delete("/api/accounts/delete", {password: password});
|
||||
let response_data = await response.json();
|
||||
|
||||
if (JSON.stringify(response_data) == JSON.stringify({'detail': 'Authentication credentials were not provided.'}))
|
||||
if (response.status === 403)
|
||||
{
|
||||
this.client._update_logged(false);
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
if (response_data == "user deleted")
|
||||
this.client._logged = false;
|
||||
this.client._update_logged(false);
|
||||
return response_data;
|
||||
}
|
||||
|
||||
@ -46,10 +46,10 @@ class Account
|
||||
let response = await this.client._get("/api/accounts/edit");
|
||||
let response_data = await response.json();
|
||||
|
||||
if (JSON.stringify(response_data) == JSON.stringify({'detail': 'Authentication credentials were not provided.'}))
|
||||
if (response.status === 403)
|
||||
{
|
||||
this.client._logged = false;
|
||||
return null;
|
||||
this.client._update_logged(false);
|
||||
return null;
|
||||
}
|
||||
return response_data;
|
||||
}
|
||||
@ -60,13 +60,13 @@ class Account
|
||||
let response = await this.client._patch_json("/api/accounts/edit", data);
|
||||
let response_data = await response.json();
|
||||
|
||||
if (JSON.stringify(response_data) == JSON.stringify({'detail': 'Authentication credentials were not provided.'}))
|
||||
if (response.status === 403)
|
||||
{
|
||||
this.client._;
|
||||
this.client._update_logged(false);
|
||||
return null;
|
||||
}
|
||||
return response_data;
|
||||
}
|
||||
}
|
||||
|
||||
export { Account }
|
||||
export { Account }
|
||||
|
@ -37,8 +37,8 @@ class Client
|
||||
async isAuthentificate()
|
||||
{
|
||||
if (this._logged == undefined)
|
||||
this.logged = await this._test_logged();
|
||||
return this.logged;
|
||||
this._logged = await this._test_logged();
|
||||
return this._logged;
|
||||
}
|
||||
|
||||
async _get(uri, data)
|
||||
@ -103,31 +103,40 @@ class Client
|
||||
|
||||
async _update_logged(state)
|
||||
{
|
||||
if (this.logged == state)
|
||||
if (this._logged == state)
|
||||
return;
|
||||
|
||||
if (state)
|
||||
{
|
||||
this.me = new MyProfile(this);
|
||||
await this.me.init();
|
||||
[...document.getElementById('nav-account-links').children].forEach(el => {
|
||||
if (el.matches('[logged-in]'))
|
||||
el.classList.remove('d-none');
|
||||
else
|
||||
el.classList.add('d-none');
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
this.me = undefined;
|
||||
[...document.getElementById('nav-account-links').children].forEach(el => {
|
||||
if (el.matches('[logged-in]'))
|
||||
el.classList.add('d-none');
|
||||
else
|
||||
el.classList.remove('d-none');
|
||||
});
|
||||
}
|
||||
this.logged = state;
|
||||
this._logged = state;
|
||||
}
|
||||
|
||||
async login(username, password)
|
||||
{
|
||||
let response = await this._post("/api/accounts/login", {username: username, password: password})
|
||||
|
||||
if (response.status != 200)
|
||||
return response.status;
|
||||
if (response.status == 200)
|
||||
await this._update_logged(true);
|
||||
|
||||
this._update_logged(true);
|
||||
|
||||
return 0;
|
||||
return response;
|
||||
}
|
||||
|
||||
async logout()
|
||||
|
14
frontend/static/js/api/game/Ball.js
Normal file
14
frontend/static/js/api/game/Ball.js
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
class Ball
|
||||
{
|
||||
constructor (position_x, position_y, velocity_x, velocity_y)
|
||||
{
|
||||
this.position_x = position_x;
|
||||
this.position_y = position_y;
|
||||
this.velocity_x = velocity_x;
|
||||
this.velocity_y = velocity_y;
|
||||
}
|
||||
}
|
||||
|
||||
export { Ball }
|
122
frontend/static/js/api/game/Game.js
Normal file
122
frontend/static/js/api/game/Game.js
Normal file
@ -0,0 +1,122 @@
|
||||
import { Ball } from "./Ball.js";
|
||||
import { GameConfig } from "./GameConfig.js"
|
||||
import { Player } from "./Player.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;
|
||||
|
||||
//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 !== 0)
|
||||
return ret;
|
||||
|
||||
this.players = [];
|
||||
response_data.players.forEach(player_data => {
|
||||
let player = new Player(player_data.id, player_data.pos, player_data.nb_goal);
|
||||
this.players.push(player);
|
||||
});
|
||||
|
||||
this.ball = new Ball(response_data.ball_pos_x, response_data.ball_pos_y, response_data.ball_vel_x, response_data.ball_vel_y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_send(data)
|
||||
{
|
||||
this._socket.send(JSON.stringify(data));
|
||||
}
|
||||
|
||||
_send_paddle()
|
||||
{
|
||||
this._send({"detail": "update_my_paddle_pos", "pos": this.players.find(player => player.id === this.client.me.id).pos});
|
||||
}
|
||||
|
||||
_update_paddles(data)
|
||||
{
|
||||
data.forEach(player_data => {
|
||||
let player = this.players.find(player_data2 => player_data2.id === player_data)
|
||||
|
||||
if (player === null)
|
||||
{
|
||||
console.error("error 1000: je ne comprends pas");
|
||||
return;
|
||||
}
|
||||
|
||||
player.pos = player_data.pos;
|
||||
});
|
||||
}
|
||||
|
||||
_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)
|
||||
{
|
||||
if (data.detail === "update_paddles")
|
||||
this._update_paddles(data);
|
||||
else if (data.detail === "update_ball")
|
||||
this._
|
||||
}
|
||||
|
||||
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 = WebSocket(url);
|
||||
|
||||
this._socket.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
this._update(data);
|
||||
};
|
||||
}
|
||||
|
||||
leave()
|
||||
{
|
||||
this._socket.close();
|
||||
this._socket = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export { Game }
|
43
frontend/static/js/api/game/GameConfig.js
Normal file
43
frontend/static/js/api/game/GameConfig.js
Normal file
@ -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 }
|
7
frontend/static/js/api/game/MyPlayer.js
Normal file
7
frontend/static/js/api/game/MyPlayer.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { Player } from "./Player";
|
||||
|
||||
|
||||
class MyPlayer extends Player
|
||||
{
|
||||
|
||||
}
|
12
frontend/static/js/api/game/Player.js
Normal file
12
frontend/static/js/api/game/Player.js
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
class Player
|
||||
{
|
||||
constructor(id, pos, nb_goal)
|
||||
{
|
||||
this.id = id;
|
||||
this.pos = pos;
|
||||
this.nb_goal = nb_goal;
|
||||
}
|
||||
}
|
||||
|
||||
export { Player }
|
@ -117,9 +117,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
document.body.addEventListener("click", e => {
|
||||
if (e.target.matches("[data-link]")) {
|
||||
e.preventDefault();
|
||||
document.querySelectorAll('[data-link]').forEach(e => {
|
||||
e.classList.remove('active');
|
||||
});
|
||||
document.querySelector('[data-link].active').classList.remove('active');
|
||||
e.target.classList.add('active');
|
||||
navigateTo(e.target.href.slice(location.origin.length));
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
let diff_x = rail_stop_x - rail_start_x,
|
||||
diff_y = rail_stop_y - rail_start_y;
|
||||
|
||||
let pos_x = rail_start_x + diff_x * pos,
|
||||
pos_y = rail_start_y + diff_y * pos;
|
||||
|
||||
let start_x = pos_x - (diff_x * (paddle_size / rail_size)),
|
||||
start_y = pos_y - (diff_y * (paddle_size / rail_size)),
|
||||
stop_x = pos_x + (diff_x * (paddle_size / rail_size)),
|
||||
stop_y = pos_y + (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);
|
||||
}
|
||||
|
||||
_down()
|
||||
{
|
||||
pl
|
||||
}
|
||||
|
||||
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 * 3 / 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 +0) * 2);
|
||||
this.draw_ball(ctx, this.game.ball_pos_x, this.game.ball_pos_y);
|
||||
|
||||
ctx.strokeStyle = "#000000";
|
||||
ctx.lineWidth = 10;
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
render_game()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
this.draw_game();
|
||||
// TODO remove the line below
|
||||
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.game.join()
|
||||
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 `
|
||||
<h1>Welcome back, Dom</h1>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
<a href="/posts" data-link>View recent posts</a>.
|
||||
</p>
|
||||
return /* HTML */ `
|
||||
<link rel="stylesheet" href="/static/css/game.css">
|
||||
<h2 id="game-state"></h2>
|
||||
<div id="player_list"></div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -7,16 +7,14 @@ async function login()
|
||||
let username = document.getElementById("username-input").value;
|
||||
let password = document.getElementById("password-input").value;
|
||||
|
||||
let response_data = await client.login(username, password);
|
||||
let response = await client.login(username, password);
|
||||
|
||||
if (response_data == null)
|
||||
{
|
||||
if (response.status == 200) {
|
||||
navigateTo("/home");
|
||||
return;
|
||||
} else {
|
||||
let error = await response.json();
|
||||
fill_errors(error, "innerHTML");
|
||||
}
|
||||
|
||||
clear("innerHTML", ["username", "user", "password"]);
|
||||
fill_errors(response_data, "innerHTML");
|
||||
}
|
||||
|
||||
export default class extends AbstractNonAuthentifiedView {
|
||||
@ -26,6 +24,17 @@ export default class extends AbstractNonAuthentifiedView {
|
||||
|
||||
async postInit()
|
||||
{
|
||||
let usernameField = document.getElementById('username-input');
|
||||
usernameField.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Enter')
|
||||
login();
|
||||
});
|
||||
usernameField.focus();
|
||||
let passwordField = document.getElementById('password-input');
|
||||
passwordField.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Enter')
|
||||
login();
|
||||
});
|
||||
document.getElementById("login-button").onclick = login;
|
||||
}
|
||||
|
||||
@ -35,11 +44,9 @@ export default class extends AbstractNonAuthentifiedView {
|
||||
<label>Login</label>
|
||||
<link rel="stylesheet" href="/static/css/accounts/login.css">
|
||||
<input type="text" id="username-input" placeholder="username">
|
||||
<span id="username"></span>
|
||||
<input type="password" id="password-input" placeholder="password">
|
||||
<span id="password"></span>
|
||||
<input type="button" value="Login" id="login-button">
|
||||
<span id="user"></span>
|
||||
<span id="error"></span>
|
||||
<a href="/register" class="nav__link" data-link>Register</a>
|
||||
</div>
|
||||
`;
|
||||
|
@ -5,7 +5,10 @@ export default class extends AbstractAuthentifiedView
|
||||
{
|
||||
constructor(params) {
|
||||
super(params, "Logout");
|
||||
client.logout();
|
||||
}
|
||||
|
||||
async postInit() {
|
||||
await client.logout();
|
||||
navigateTo("/login")
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,15 @@ async function register()
|
||||
{
|
||||
let username = document.getElementById("username-input").value;
|
||||
let password = document.getElementById("password-input").value;
|
||||
|
||||
if (username === '' || password === '') {
|
||||
clear("innerHTML", ["username", "password"]);
|
||||
if (username === '')
|
||||
document.getElementById('username').innerHTML = 'This field may not be blank.';
|
||||
if (password === '')
|
||||
document.getElementById('password').innerHTML = 'This field may not be blank.';
|
||||
return;
|
||||
}
|
||||
|
||||
let response_data = await client.account.create(username, password);
|
||||
|
||||
if (response_data == null)
|
||||
@ -26,6 +34,17 @@ export default class extends AbstractNonAuthentifiedView {
|
||||
|
||||
async postInit()
|
||||
{
|
||||
let usernameField = document.getElementById('username-input');
|
||||
usernameField.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Enter')
|
||||
register();
|
||||
});
|
||||
usernameField.focus();
|
||||
let passwordField = document.getElementById('password-input');
|
||||
passwordField.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Enter')
|
||||
register();
|
||||
});
|
||||
document.getElementById("register-button").onclick = register;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user