this merge with master should come with the right backend stuff to make friendship requests work
This commit is contained in:
@@ -1,53 +0,0 @@
|
|||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Bit5x3";
|
|
||||||
src: url("http://localhost:8080/Bit5x3.woff2") format("woff2"),
|
|
||||||
url("http://localhost:8080/Bit5x3.woff") format("woff");
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
#preload_font {
|
|
||||||
font-family: "Bit5x3";
|
|
||||||
opacity:0;
|
|
||||||
height:0;
|
|
||||||
width:0;
|
|
||||||
display:inline-block;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
background-color: #222425;
|
|
||||||
}
|
|
||||||
#canvas_container {
|
|
||||||
text-align: center;
|
|
||||||
/* border: dashed rgb(245, 245, 245) 5px; */
|
|
||||||
/* max-height: 80vh; */
|
|
||||||
/* overflow: hidden; */
|
|
||||||
}
|
|
||||||
#div_game_options {
|
|
||||||
text-align: center;
|
|
||||||
font-family: "Bit5x3";
|
|
||||||
color: rgb(245, 245, 245);
|
|
||||||
font-size: x-large;
|
|
||||||
}
|
|
||||||
#div_game_options fieldset {
|
|
||||||
max-width: 50vw;
|
|
||||||
width: auto;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
#div_game_options fieldset div {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
#play_pong_button {
|
|
||||||
font-family: "Bit5x3";
|
|
||||||
color: rgb(245, 245, 245);
|
|
||||||
background-color: #333333;
|
|
||||||
font-size: x-large;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
canvas {
|
|
||||||
background-color: #333333;
|
|
||||||
max-width: 75vw;
|
|
||||||
/* max-height: 100vh; */
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
||||||
<link rel="stylesheet" href="pong.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="preload_font">.</div>
|
|
||||||
|
|
||||||
<div id="div_game_options">
|
|
||||||
<fieldset>
|
|
||||||
<legend>game options</legend>
|
|
||||||
<div>
|
|
||||||
<input type="checkbox" id="multi_balls" name="multi_balls">
|
|
||||||
<label for="multi_balls">multiples balls</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<input type="checkbox" id="moving_walls" name="moving_walls">
|
|
||||||
<label for="moving_walls">moving walls</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label>sound :</label>
|
|
||||||
<input type="radio" id="sound_on" name="sound_selector" checked>
|
|
||||||
<label for="sound_on">on</label>
|
|
||||||
<input type="radio" id="sound_off" name="sound_selector">
|
|
||||||
<label for="sound_off">off</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button id="play_pong_button">PLAY</button>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="canvas_container">
|
|
||||||
<!-- <p> =) </p> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="http://localhost:8080/js/pong.js" type="module" defer></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
export * from "../shared_js/constants.js"
|
|
||||||
|
|
||||||
// 15ms == 1000/66.666
|
|
||||||
export const serverGameLoopIntervalMS = 15; // millisecond
|
|
||||||
export const fixedDeltaTime = serverGameLoopIntervalMS/1000; // second
|
|
||||||
|
|
||||||
// 33.333ms == 1000/30
|
|
||||||
export const clientsUpdateIntervalMS = 1000/30; // millisecond
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
export * from "../shared_js/utils.js"
|
|
||||||
|
|
||||||
function shortId(id: string): string {
|
|
||||||
return id.substring(0, id.indexOf("-"));
|
|
||||||
}
|
|
||||||
|
|
||||||
export {shortId}
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
@@ -2,8 +2,8 @@
|
|||||||
import { WebSocket } from "../wsServer.js";
|
import { WebSocket } from "../wsServer.js";
|
||||||
import { Racket } from "../../shared_js/class/Rectangle.js";
|
import { Racket } from "../../shared_js/class/Rectangle.js";
|
||||||
import { GameSession } from "./GameSession.js";
|
import { GameSession } from "./GameSession.js";
|
||||||
import * as ev from "../../shared_js/class/Event.js"
|
import * as ev from "./Event.js"
|
||||||
import * as en from "../../shared_js/enums.js"
|
import * as en from "../enums.js"
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
socket: WebSocket;
|
socket: WebSocket;
|
||||||
65
JEU2/src/server/class/GameComponents.ts
Normal file
65
JEU2/src/server/class/GameComponents.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
import * as c from "../constants.js"
|
||||||
|
import * as en from "../enums.js"
|
||||||
|
import { VectorInteger } from "./Vector.js";
|
||||||
|
import { Rectangle, MovingRectangle, Racket, Ball } from "./Rectangle.js";
|
||||||
|
import { random } from "../utils.js";
|
||||||
|
|
||||||
|
class GameComponents {
|
||||||
|
wallTop: Rectangle | MovingRectangle;
|
||||||
|
wallBottom: Rectangle | MovingRectangle;
|
||||||
|
playerLeft: Racket;
|
||||||
|
playerRight: Racket;
|
||||||
|
ballsArr: Ball[] = [];
|
||||||
|
constructor(options: en.MatchOptions)
|
||||||
|
{
|
||||||
|
const pos = new VectorInteger;
|
||||||
|
|
||||||
|
// Rackets
|
||||||
|
pos.assign(0+c.pw, c.h_mid-c.ph/2);
|
||||||
|
this.playerLeft = new Racket(pos, c.pw, c.ph, c.racketSpeed);
|
||||||
|
pos.assign(c.w-c.pw-c.pw, c.h_mid-c.ph/2);
|
||||||
|
this.playerRight = new Racket(pos, c.pw, c.ph, c.racketSpeed);
|
||||||
|
|
||||||
|
// Balls
|
||||||
|
let ballsCount = 1;
|
||||||
|
if (options & en.MatchOptions.multiBalls) {
|
||||||
|
ballsCount = c.multiBallsCount;
|
||||||
|
}
|
||||||
|
pos.assign(-c.ballSize, -c.ballSize); // ball out =)
|
||||||
|
while (this.ballsArr.length < ballsCount) {
|
||||||
|
this.ballsArr.push(new Ball(pos, c.ballSize, c.ballSpeed, c.ballSpeedIncrease))
|
||||||
|
}
|
||||||
|
this.ballsArr.forEach((ball) => {
|
||||||
|
ball.dir.x = 1;
|
||||||
|
if (random() > 0.5) {
|
||||||
|
ball.dir.x *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ball.dir.y = random(0, 0.2);
|
||||||
|
if (random() > 0.5) {
|
||||||
|
ball.dir.y *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ball.dir = ball.dir.normalized();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Walls
|
||||||
|
if (options & en.MatchOptions.movingWalls) {
|
||||||
|
pos.assign(0, 0);
|
||||||
|
this.wallTop = new MovingRectangle(pos, c.w, c.wallSize, c.movingWallSpeed);
|
||||||
|
(<MovingRectangle>this.wallTop).dir.y = -1;
|
||||||
|
pos.assign(0, c.h-c.wallSize);
|
||||||
|
this.wallBottom = new MovingRectangle(pos, c.w, c.wallSize, c.movingWallSpeed);
|
||||||
|
(<MovingRectangle>this.wallBottom).dir.y = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos.assign(0, 0);
|
||||||
|
this.wallTop = new Rectangle(pos, c.w, c.wallSize);
|
||||||
|
pos.assign(0, c.h-c.wallSize);
|
||||||
|
this.wallBottom = new Rectangle(pos, c.w, c.wallSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {GameComponents}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import * as c from "../constants.js"
|
import * as c from "../constants.js"
|
||||||
import * as en from "../../shared_js/enums.js"
|
import * as en from "../enums.js"
|
||||||
import { GameComponents } from "../../shared_js/class/GameComponents.js";
|
import { GameComponents } from "../../shared_js/class/GameComponents.js";
|
||||||
|
|
||||||
class GameComponentsServer extends GameComponents {
|
class GameComponentsServer extends GameComponents {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import * as en from "../../shared_js/enums.js"
|
import * as en from "../enums.js"
|
||||||
import * as ev from "../../shared_js/class/Event.js"
|
import * as ev from "./Event.js"
|
||||||
import * as c from "../constants.js"
|
import * as c from "../constants.js"
|
||||||
import { ClientPlayer } from "./Client";
|
import { ClientPlayer } from "./Client";
|
||||||
import { GameComponentsServer } from "./GameComponentsServer.js";
|
import { GameComponentsServer } from "./GameComponentsServer.js";
|
||||||
35
JEU2/src/server/constants.ts
Normal file
35
JEU2/src/server/constants.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
export * from "../shared_js/constants.js"
|
||||||
|
|
||||||
|
// 15ms == 1000/66.666
|
||||||
|
export const serverGameLoopIntervalMS = 15; // millisecond
|
||||||
|
export const fixedDeltaTime = serverGameLoopIntervalMS/1000; // second
|
||||||
|
|
||||||
|
// 33.333ms == 1000/30
|
||||||
|
export const clientsUpdateIntervalMS = 1000/30; // millisecond
|
||||||
|
|
||||||
|
export const CanvasWidth = 1500;
|
||||||
|
export const CanvasRatio = 1.66666;
|
||||||
|
/* ratio 5/3 (1.66) */
|
||||||
|
|
||||||
|
export const w = CanvasWidth;
|
||||||
|
export const h = CanvasWidth / CanvasRatio;
|
||||||
|
export const w_mid = Math.floor(w/2);
|
||||||
|
export const h_mid = Math.floor(h/2);
|
||||||
|
export const pw = Math.floor(w*0.017);
|
||||||
|
export const ph = pw*6;
|
||||||
|
export const ballSize = pw;
|
||||||
|
export const wallSize = Math.floor(w*0.01);
|
||||||
|
export const racketSpeed = Math.floor(w*0.66); // pixel per second
|
||||||
|
export const ballSpeed = Math.floor(w*0.66); // pixel per second
|
||||||
|
export const ballSpeedIncrease = Math.floor(ballSpeed*0.05); // pixel per second
|
||||||
|
|
||||||
|
export const normalizedSpeed = false; // for consistency in speed independent of direction
|
||||||
|
|
||||||
|
export const matchStartDelay = 3000; // millisecond
|
||||||
|
export const newRoundDelay = 1500; // millisecond
|
||||||
|
|
||||||
|
// Game Variantes
|
||||||
|
export const multiBallsCount = 3;
|
||||||
|
export const movingWallPosMax = Math.floor(w*0.12);
|
||||||
|
export const movingWallSpeed = Math.floor(w*0.08);
|
||||||
33
JEU2/src/server/utils.ts
Normal file
33
JEU2/src/server/utils.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { MovingRectangle } from "./class/Rectangle.js";
|
||||||
|
export * from "../shared_js/utils.js"
|
||||||
|
|
||||||
|
function shortId(id: string): string {
|
||||||
|
return id.substring(0, id.indexOf("-"));
|
||||||
|
}
|
||||||
|
|
||||||
|
export {shortId}
|
||||||
|
|
||||||
|
function random(min: number = 0, max: number = 1) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sleep (ms: number) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
function clamp(n: number, min: number, max: number) : number
|
||||||
|
{
|
||||||
|
if (n < min)
|
||||||
|
n = min;
|
||||||
|
else if (n > max)
|
||||||
|
n = max;
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Typescript hack, unused
|
||||||
|
function assertMovingRectangle(value: unknown): asserts value is MovingRectangle {
|
||||||
|
// if (value !== MovingRectangle) throw new Error("Not a MovingRectangle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {random, sleep, clamp, assertMovingRectangle}
|
||||||
@@ -8,8 +8,8 @@ export class WebSocket extends BaseLibWebSocket {
|
|||||||
import { IncomingMessage } from "http";
|
import { IncomingMessage } from "http";
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import * as en from "../shared_js/enums.js"
|
import * as en from "./enums.js"
|
||||||
import * as ev from "../shared_js/class/Event.js"
|
import * as ev from "./class/Event.js"
|
||||||
import { Client, ClientPlayer } from "./class/Client.js"
|
import { Client, ClientPlayer } from "./class/Client.js"
|
||||||
import { GameSession } from "./class/GameSession.js"
|
import { GameSession } from "./class/GameSession.js"
|
||||||
import { shortId } from "./utils.js";
|
import { shortId } from "./utils.js";
|
||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "group_transcendence",
|
|
||||||
"lockfileVersion": 2,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {}
|
|
||||||
}
|
|
||||||
@@ -3,9 +3,9 @@ import { FriendshipStatus } from '../entities/friendship.entity';
|
|||||||
|
|
||||||
export class CreateFriendshipDto {
|
export class CreateFriendshipDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
readonly requesterId: string;
|
readonly requesterUsername: string;
|
||||||
@IsString()
|
@IsString()
|
||||||
readonly addresseeId: string;
|
readonly addresseeUsername: string;
|
||||||
@IsEnum(FriendshipStatus)
|
@IsEnum(FriendshipStatus)
|
||||||
readonly status: FriendshipStatus;
|
readonly status: FriendshipStatus;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ export class Friendship {
|
|||||||
date : Date;
|
date : Date;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
@ManyToOne(type => User, user => user.requesterId)
|
@ManyToOne(type => User, user => user.username)
|
||||||
requesterId: string;
|
requesterUsername: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
@ManyToOne(type => User, user => user.addresseeId)
|
@ManyToOne(type => User, user => user.username)
|
||||||
addresseeId: string;
|
addresseeUsername: string;
|
||||||
|
|
||||||
@Column({ type: 'enum', enum: FriendshipStatus, default: FriendshipStatus.REQUESTED})
|
@Column({ type: 'enum', enum: FriendshipStatus, default: FriendshipStatus.REQUESTED})
|
||||||
status: FriendshipStatus;
|
status: FriendshipStatus;
|
||||||
|
|||||||
@@ -36,14 +36,8 @@ export class FriendshipController {
|
|||||||
@UseGuards(TwoFactorGuard)
|
@UseGuards(TwoFactorGuard)
|
||||||
create(@Body() createFriendshipDto: CreateFriendshipDto, @Req() req) {
|
create(@Body() createFriendshipDto: CreateFriendshipDto, @Req() req) {
|
||||||
const user = req.user;
|
const user = req.user;
|
||||||
|
console.log(`User id: ${user.id}\nFriend id: ${createFriendshipDto.requesterUsername}\nStatus: ${createFriendshipDto.status}`);
|
||||||
console.log("WHAT IS UP MY GUYS IT IS YOUR BOI THAT IDIOT YOU HATE 22222");
|
if (user.username === createFriendshipDto.requesterUsername)
|
||||||
|
|
||||||
// console.log(`User id: ${user.id}\nFriend id: ${createFriendshipDto.requesterId}\nStatus: ${createFriendshipDto.status}`);
|
|
||||||
// console.log(`My User id: ${createFriendshipDto.requesterId}`)
|
|
||||||
console.log(`My User id: ${user.id}`)
|
|
||||||
console.log(`User id: ${user.id}\nFriend id: ${createFriendshipDto.addresseeId}\nStatus: ${createFriendshipDto.status}`);
|
|
||||||
if (user.id === +createFriendshipDto.requesterId)
|
|
||||||
return this.friendshipService.create(createFriendshipDto, user);
|
return this.friendshipService.create(createFriendshipDto, user);
|
||||||
return new HttpException('You can\'t request a frienship for another user', HttpStatus.FORBIDDEN);
|
return new HttpException('You can\'t request a frienship for another user', HttpStatus.FORBIDDEN);
|
||||||
}
|
}
|
||||||
@@ -73,7 +67,7 @@ export class FriendshipController {
|
|||||||
@UseGuards(TwoFactorGuard)
|
@UseGuards(TwoFactorGuard)
|
||||||
findAllBlocked(@Req() req) {
|
findAllBlocked(@Req() req) {
|
||||||
const user = req.user;
|
const user = req.user;
|
||||||
return this.friendshipService.findAllBlockedFriends(user.id);
|
return this.friendshipService.findAllBlockedFriends(user.username);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET http://transcendance:8080/api/v2/network/pending
|
// GET http://transcendance:8080/api/v2/network/pending
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
import { User } from 'src/users/entities/user.entity';
|
import { User } from 'src/users/entities/user.entity';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { CreateFriendshipDto } from './dto/create-friendship.dto';
|
import { CreateFriendshipDto } from './dto/create-friendship.dto';
|
||||||
import { UpdateFriendshipDto } from './dto/update-friendship.dto';
|
|
||||||
import { Friendship, FriendshipStatus } from './entities/friendship.entity';
|
import { Friendship, FriendshipStatus } from './entities/friendship.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -17,8 +16,8 @@ export class FriendshipService {
|
|||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
|
||||||
async findOneFriend(friendshipId: string, userId: string) {
|
async findOneFriend(friendshipId: string, username: string) {
|
||||||
const friendship = await this.friendshipRepository.find({ where: { id: +friendshipId, requesterId: userId, status: FriendshipStatus.ACCEPTED } });
|
const friendship = await this.friendshipRepository.find({ where: { id: +friendshipId, requesterUsername: username, status: FriendshipStatus.ACCEPTED } });
|
||||||
if (!friendship)
|
if (!friendship)
|
||||||
throw new HttpException(`The requested friend not found.`, HttpStatus.NOT_FOUND);
|
throw new HttpException(`The requested friend not found.`, HttpStatus.NOT_FOUND);
|
||||||
return friendship;
|
return friendship;
|
||||||
@@ -31,12 +30,12 @@ export class FriendshipService {
|
|||||||
return friendship;
|
return friendship;
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAllFriends(userId: string) {
|
async findAllFriends(username: string) {
|
||||||
const friendship = await this.friendshipRepository
|
const friendship = await this.friendshipRepository
|
||||||
.createQueryBuilder('friendship')
|
.createQueryBuilder('friendship')
|
||||||
.where('friendship.status = :status', { status: FriendshipStatus.ACCEPTED })
|
.where('friendship.status = :status', { status: FriendshipStatus.ACCEPTED })
|
||||||
.andWhere('friendship.addresseeId = :addressee', { addressee: userId })
|
.andWhere('friendship.addresseeUsername = :addressee', { addressee: username })
|
||||||
.orWhere('friendship.requesterId = :requester', { requester: userId })
|
.orWhere('friendship.requesterUsername = :requester', { requester: username })
|
||||||
.andWhere('friendship.status = :status', { status: FriendshipStatus.ACCEPTED })
|
.andWhere('friendship.status = :status', { status: FriendshipStatus.ACCEPTED })
|
||||||
.getMany();
|
.getMany();
|
||||||
for (const friend of friendship)
|
for (const friend of friendship)
|
||||||
@@ -44,40 +43,39 @@ export class FriendshipService {
|
|||||||
return friendship;
|
return friendship;
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAllBlockedFriends(userId: string) {
|
async findAllBlockedFriends(username: string) {
|
||||||
return await this.friendshipRepository
|
return await this.friendshipRepository
|
||||||
.createQueryBuilder('friendship')
|
.createQueryBuilder('friendship')
|
||||||
.where('friendship.requesterId = :requestee', { requestee: userId })
|
.where('friendship.requesterUsername = :requestee', { requestee: username })
|
||||||
.orWhere('friendship.addresseeId = :addressee', { addressee: userId })
|
|
||||||
.andWhere('friendship.status = :status', { status: FriendshipStatus.BLOCKED })
|
.andWhere('friendship.status = :status', { status: FriendshipStatus.BLOCKED })
|
||||||
.getMany();
|
.getMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAllPendantRequestsForFriendship(userId: string) {
|
async findAllPendantRequestsForFriendship(username: string) {
|
||||||
return await this.friendshipRepository
|
return await this.friendshipRepository
|
||||||
.createQueryBuilder('friendship')
|
.createQueryBuilder('friendship')
|
||||||
.where('friendship.requesterId = :requestee', { requestee: userId })
|
.where('friendship.requesterUsername = :requestee', { requestee: username })
|
||||||
.andWhere('friendship.status = :status', { status: FriendshipStatus.REQUESTED })
|
.andWhere('friendship.status = :status', { status: FriendshipStatus.REQUESTED })
|
||||||
.getMany();
|
.getMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAllReceivedRequestsForFriendship(userId: string) {
|
async findAllReceivedRequestsForFriendship(username: string) {
|
||||||
return await this.friendshipRepository
|
return await this.friendshipRepository
|
||||||
.createQueryBuilder('friendship')
|
.createQueryBuilder('friendship')
|
||||||
.where('friendship.addresseeId = :addressee', { addressee: userId })
|
.where('friendship.addresseeUsername = :addressee', { addressee: username })
|
||||||
.andWhere('friendship.status = :status', { status: FriendshipStatus.REQUESTED })
|
.andWhere('friendship.status = :status', { status: FriendshipStatus.REQUESTED })
|
||||||
.getMany();
|
.getMany();
|
||||||
}
|
}
|
||||||
//GROS CHANTIER
|
//GROS CHANTIER
|
||||||
async create(createFriendshipDto: CreateFriendshipDto, creator : User) {
|
async create(createFriendshipDto: CreateFriendshipDto, creator : User) {
|
||||||
const addressee = await this.userRepository.findOneBy({ id: +createFriendshipDto.addresseeId });
|
const addressee = await this.userRepository.findOneBy({username: createFriendshipDto.requesterUsername});
|
||||||
if (!addressee)
|
if (!addressee)
|
||||||
throw new HttpException(`The addressee does not exist.`, HttpStatus.NOT_FOUND);
|
throw new HttpException(`The addressee does not exist.`, HttpStatus.NOT_FOUND);
|
||||||
if (creator.id === addressee.id)
|
if (creator.id === addressee.id)
|
||||||
throw new HttpException(`You can't add yourself.`, HttpStatus.FORBIDDEN);
|
throw new HttpException(`You can't add yourself.`, HttpStatus.FORBIDDEN);
|
||||||
if (createFriendshipDto.status !== FriendshipStatus.REQUESTED && createFriendshipDto.status !== FriendshipStatus.BLOCKED)
|
if (createFriendshipDto.status !== FriendshipStatus.REQUESTED && createFriendshipDto.status !== FriendshipStatus.BLOCKED)
|
||||||
throw new HttpException(`The status is not valid.`, HttpStatus.NOT_FOUND);
|
throw new HttpException(`The status is not valid.`, HttpStatus.NOT_FOUND);
|
||||||
const friendship = await this.friendshipRepository.findOneBy({ requesterId: createFriendshipDto.requesterId, addresseeId: createFriendshipDto.addresseeId });
|
const friendship = await this.friendshipRepository.findOneBy({ requesterUsername: createFriendshipDto.requesterUsername, addresseeUsername: createFriendshipDto.addresseeUsername });
|
||||||
if (friendship) {
|
if (friendship) {
|
||||||
if (friendship.status && friendship.status === FriendshipStatus.ACCEPTED)
|
if (friendship.status && friendship.status === FriendshipStatus.ACCEPTED)
|
||||||
throw new HttpException(`The friendship request has already been accepted.`, HttpStatus.OK);
|
throw new HttpException(`The friendship request has already been accepted.`, HttpStatus.OK);
|
||||||
@@ -96,7 +94,7 @@ export class FriendshipService {
|
|||||||
const relation = await this.friendshipRepository.findOneBy({ id: +relationshipId });
|
const relation = await this.friendshipRepository.findOneBy({ id: +relationshipId });
|
||||||
if (!relation)
|
if (!relation)
|
||||||
throw new HttpException(`The requested relationship not found.`, HttpStatus.NOT_FOUND);
|
throw new HttpException(`The requested relationship not found.`, HttpStatus.NOT_FOUND);
|
||||||
if (+relation.requesterId === user.id) {
|
if (+relation.requesterUsername === user.id) {
|
||||||
throw new HttpException(`You can't accept your own request.`, HttpStatus.NOT_FOUND);
|
throw new HttpException(`You can't accept your own request.`, HttpStatus.NOT_FOUND);
|
||||||
}
|
}
|
||||||
if (status === FriendshipStatus.ACCEPTED)
|
if (status === FriendshipStatus.ACCEPTED)
|
||||||
@@ -122,8 +120,8 @@ export class FriendshipService {
|
|||||||
async findIfUserIsBlockedOrHasBlocked(userConnectedId: string, userToCheckId: string) {
|
async findIfUserIsBlockedOrHasBlocked(userConnectedId: string, userToCheckId: string) {
|
||||||
const friendship = await this.friendshipRepository
|
const friendship = await this.friendshipRepository
|
||||||
.createQueryBuilder('friendship')
|
.createQueryBuilder('friendship')
|
||||||
.where('friendship.requesterId = :requestee', { requestee: userConnectedId })
|
.where('friendship.requesterUsername = :requestee', { requestee: userConnectedId })
|
||||||
.orWhere('friendship.requesterId = :requesteeBis', { requesteeBis: userToCheckId })
|
.orWhere('friendship.requesterUsername = :requesteeBis', { requesteeBis: userToCheckId })
|
||||||
.andWhere('friendship.status = :status', { status: FriendshipStatus.BLOCKED })
|
.andWhere('friendship.status = :status', { status: FriendshipStatus.BLOCKED })
|
||||||
.getOne();
|
.getOne();
|
||||||
if (friendship)
|
if (friendship)
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { IsBoolean, IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class CreateUsersDto {
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
readonly username: string;
|
||||||
|
readonly fortyTwoId: string;
|
||||||
|
@IsEmail()
|
||||||
|
readonly email: string;
|
||||||
|
@IsString()
|
||||||
|
readonly image_url: string;
|
||||||
|
@IsString()
|
||||||
|
readonly status: string;
|
||||||
|
@IsBoolean()
|
||||||
|
readonly isEnabledTwoFactorAuth: boolean;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Entity('gameParty')
|
||||||
|
export class gameParty {
|
||||||
|
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
playerOne: string
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
playerTwo: string
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
resultOfTheMatch: string
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
gameServerIdOfTheMatch: string
|
||||||
|
}
|
||||||
@@ -44,11 +44,11 @@ export class User {
|
|||||||
secretTwoFactorAuth: string;
|
secretTwoFactorAuth: string;
|
||||||
|
|
||||||
@JoinTable()
|
@JoinTable()
|
||||||
@OneToMany(type => Friendship , (friendship) => friendship.requesterId)
|
@OneToMany(type => Friendship , (friendship) => friendship.requesterUsername)
|
||||||
requesterId: Friendship[];
|
requesterId: Friendship[];
|
||||||
|
|
||||||
@JoinTable()
|
@JoinTable()
|
||||||
@OneToMany(type => Friendship , (friendship) => friendship.addresseeId)
|
@OneToMany(type => Friendship , (friendship) => friendship.addresseeUsername)
|
||||||
addresseeId: Friendship[];
|
addresseeId: Friendship[];
|
||||||
|
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
|
|||||||
107
srcs/requirements/svelte/api_front/public/game/class/Event.ts
Normal file
107
srcs/requirements/svelte/api_front/public/game/class/Event.ts
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
|
||||||
|
import * as en from "../enums.js"
|
||||||
|
|
||||||
|
/* From Server */
|
||||||
|
class ServerEvent {
|
||||||
|
type: en.EventTypes;
|
||||||
|
constructor(type: en.EventTypes = 0) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventAssignId extends ServerEvent {
|
||||||
|
id: string;
|
||||||
|
constructor(id: string) {
|
||||||
|
super(en.EventTypes.assignId);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventMatchmakingComplete extends ServerEvent {
|
||||||
|
side: en.PlayerSide;
|
||||||
|
constructor(side: en.PlayerSide) {
|
||||||
|
super(en.EventTypes.matchmakingComplete);
|
||||||
|
this.side = side;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventGameUpdate extends ServerEvent {
|
||||||
|
playerLeft = {
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
playerRight = {
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
ballsArr: {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
dirX: number,
|
||||||
|
dirY: number,
|
||||||
|
speed: number
|
||||||
|
}[] = [];
|
||||||
|
wallTop? = {
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
wallBottom? = {
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
lastInputId = 0;
|
||||||
|
constructor() { // TODO: constructor that take GameComponentsServer maybe ?
|
||||||
|
super(en.EventTypes.gameUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventScoreUpdate extends ServerEvent {
|
||||||
|
scoreLeft: number;
|
||||||
|
scoreRight: number;
|
||||||
|
constructor(scoreLeft: number, scoreRight: number) {
|
||||||
|
super(en.EventTypes.scoreUpdate);
|
||||||
|
this.scoreLeft = scoreLeft;
|
||||||
|
this.scoreRight = scoreRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventMatchEnd extends ServerEvent {
|
||||||
|
winner: en.PlayerSide;
|
||||||
|
constructor(winner: en.PlayerSide) {
|
||||||
|
super(en.EventTypes.matchEnd);
|
||||||
|
this.winner = winner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* From Client */
|
||||||
|
class ClientEvent {
|
||||||
|
type: en.EventTypes; // readonly ?
|
||||||
|
constructor(type: en.EventTypes = 0) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClientAnnounce extends ClientEvent {
|
||||||
|
role: en.ClientRole;
|
||||||
|
clientId: string;
|
||||||
|
matchOptions: en.MatchOptions;
|
||||||
|
constructor(role: en.ClientRole, matchOptions: en.MatchOptions, clientId: string = "") {
|
||||||
|
super(en.EventTypes.clientAnnounce);
|
||||||
|
this.role = role;
|
||||||
|
this.clientId = clientId;
|
||||||
|
this.matchOptions = matchOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventInput extends ClientEvent {
|
||||||
|
input: en.InputEnum;
|
||||||
|
id: number;
|
||||||
|
constructor(input: en.InputEnum = en.InputEnum.noInput, id: number = 0) {
|
||||||
|
super(en.EventTypes.clientInput);
|
||||||
|
this.input = input;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
ServerEvent, EventAssignId, EventMatchmakingComplete,
|
||||||
|
EventGameUpdate, EventScoreUpdate, EventMatchEnd,
|
||||||
|
ClientEvent, ClientAnnounce, EventInput
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
|
||||||
|
import { Vector, VectorInteger } from "./Vector.js";
|
||||||
|
import { Component, Moving } from "./interface.js";
|
||||||
|
import * as c from "../constants.js"
|
||||||
|
|
||||||
|
class Rectangle implements Component {
|
||||||
|
pos: VectorInteger;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
constructor(pos: VectorInteger, width: number, height: number) {
|
||||||
|
this.pos = new VectorInteger(pos.x, pos.y);
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
collision(collider: Rectangle): boolean {
|
||||||
|
const thisLeft = this.pos.x;
|
||||||
|
const thisRight = this.pos.x + this.width;
|
||||||
|
const thisTop = this.pos.y;
|
||||||
|
const thisBottom = this.pos.y + this.height;
|
||||||
|
const colliderLeft = collider.pos.x;
|
||||||
|
const colliderRight = collider.pos.x + collider.width;
|
||||||
|
const colliderTop = collider.pos.y;
|
||||||
|
const colliderBottom = collider.pos.y + collider.height;
|
||||||
|
if ((thisBottom < colliderTop)
|
||||||
|
|| (thisTop > colliderBottom)
|
||||||
|
|| (thisRight < colliderLeft)
|
||||||
|
|| (thisLeft > colliderRight)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MovingRectangle extends Rectangle implements Moving {
|
||||||
|
dir: Vector = new Vector(0,0);
|
||||||
|
speed: number;
|
||||||
|
readonly baseSpeed: number;
|
||||||
|
constructor(pos: VectorInteger, width: number, height: number, baseSpeed: number) {
|
||||||
|
super(pos, width, height);
|
||||||
|
this.baseSpeed = baseSpeed;
|
||||||
|
this.speed = baseSpeed;
|
||||||
|
}
|
||||||
|
move(delta: number) { // Math.floor WIP until VectorInteger debug
|
||||||
|
// console.log(`delta: ${delta}, speed: ${this.speed}, speed*delta: ${this.speed * delta}`);
|
||||||
|
// this.pos.x += Math.floor(this.dir.x * this.speed * delta);
|
||||||
|
// this.pos.y += Math.floor(this.dir.y * this.speed * delta);
|
||||||
|
this.pos.x += this.dir.x * this.speed * delta;
|
||||||
|
this.pos.y += this.dir.y * this.speed * delta;
|
||||||
|
}
|
||||||
|
moveAndCollide(delta: number, colliderArr: Rectangle[]) {
|
||||||
|
this._moveAndCollideAlgo(delta, colliderArr);
|
||||||
|
}
|
||||||
|
protected _moveAndCollideAlgo(delta: number, colliderArr: Rectangle[]) {
|
||||||
|
let oldPos = new VectorInteger(this.pos.x, this.pos.y);
|
||||||
|
this.move(delta);
|
||||||
|
if (colliderArr.some(this.collision, this)) {
|
||||||
|
this.pos = oldPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Racket extends MovingRectangle {
|
||||||
|
constructor(pos: VectorInteger, width: number, height: number, baseSpeed: number) {
|
||||||
|
super(pos, width, height, baseSpeed);
|
||||||
|
}
|
||||||
|
moveAndCollide(delta: number, colliderArr: Rectangle[]) {
|
||||||
|
// let oldPos = new VectorInteger(this.pos.x, this.pos.y); // debug
|
||||||
|
this._moveAndCollideAlgo(delta, colliderArr);
|
||||||
|
// console.log(`y change: ${this.pos.y - oldPos.y}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Ball extends MovingRectangle {
|
||||||
|
readonly speedIncrease: number;
|
||||||
|
ballInPlay: boolean = false;
|
||||||
|
constructor(pos: VectorInteger, size: number, baseSpeed: number, speedIncrease: number) {
|
||||||
|
super(pos, size, size, baseSpeed);
|
||||||
|
this.speedIncrease = speedIncrease;
|
||||||
|
}
|
||||||
|
bounce(collider?: Rectangle) {
|
||||||
|
this._bounceAlgo(collider);
|
||||||
|
}
|
||||||
|
protected _bounceAlgo(collider?: Rectangle) {
|
||||||
|
/* Could be more generic, but testing only Racket is enough,
|
||||||
|
because in Pong collider can only be Racket or Wall. */
|
||||||
|
if (collider instanceof Racket) {
|
||||||
|
this._bounceRacket(collider);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._bounceWall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
moveAndBounce(delta: number, colliderArr: Rectangle[]) {
|
||||||
|
this.move(delta);
|
||||||
|
let i = colliderArr.findIndex(this.collision, this);
|
||||||
|
if (i != -1)
|
||||||
|
{
|
||||||
|
this.bounce(colliderArr[i]);
|
||||||
|
this.move(delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected _bounceWall() { // Should be enough for Wall
|
||||||
|
this.dir.y = this.dir.y * -1;
|
||||||
|
}
|
||||||
|
protected _bounceRacket(racket: Racket) {
|
||||||
|
this._bounceRacketAlgo(racket);
|
||||||
|
}
|
||||||
|
protected _bounceRacketAlgo(racket: Racket) {
|
||||||
|
this.speed += this.speedIncrease;
|
||||||
|
|
||||||
|
let x = this.dir.x * -1;
|
||||||
|
|
||||||
|
const angleFactorDegree = 60;
|
||||||
|
const angleFactor = angleFactorDegree / 90;
|
||||||
|
const racketHalf = racket.height/2;
|
||||||
|
const ballMid = this.pos.y + this.height/2;
|
||||||
|
const racketMid = racket.pos.y + racketHalf;
|
||||||
|
|
||||||
|
let impact = ballMid - racketMid;
|
||||||
|
const horizontalMargin = racketHalf * 0.15;
|
||||||
|
if (impact < horizontalMargin && impact > -horizontalMargin) {
|
||||||
|
impact = 0;
|
||||||
|
}
|
||||||
|
else if (impact > 0) {
|
||||||
|
impact = impact - horizontalMargin;
|
||||||
|
}
|
||||||
|
else if (impact < 0) {
|
||||||
|
impact = impact + horizontalMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
let y = impact / (racketHalf - horizontalMargin) * angleFactor;
|
||||||
|
|
||||||
|
this.dir.assign(x, y);
|
||||||
|
// Normalize Vector (for consistency in speed independent of direction)
|
||||||
|
if (c.normalizedSpeed) {
|
||||||
|
this.dir = this.dir.normalized();
|
||||||
|
}
|
||||||
|
// console.log(`x: ${this.dir.x}, y: ${this.dir.y}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {Rectangle, MovingRectangle, Racket, Ball}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
class Vector {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
constructor(x: number = 0, y: number = 0) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
assign(x: number, y: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
normalized() : Vector {
|
||||||
|
const normalizationFactor = Math.abs(this.x) + Math.abs(this.y);
|
||||||
|
return new Vector(this.x/normalizationFactor, this.y/normalizationFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VectorInteger extends Vector {
|
||||||
|
// PLACEHOLDER
|
||||||
|
// VectorInteger with set/get dont work (No draw on the screen). Why ?
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
class VectorInteger {
|
||||||
|
// private _x: number = 0;
|
||||||
|
// private _y: number = 0;
|
||||||
|
// constructor(x: number = 0, y: number = 0) {
|
||||||
|
// this._x = x;
|
||||||
|
// this._y = y;
|
||||||
|
// }
|
||||||
|
// get x(): number {
|
||||||
|
// return this._x;
|
||||||
|
// }
|
||||||
|
// set x(v: number) {
|
||||||
|
// // this._x = Math.floor(v);
|
||||||
|
// this._x = v;
|
||||||
|
// }
|
||||||
|
// get y(): number {
|
||||||
|
// return this._y;
|
||||||
|
// }
|
||||||
|
// set y(v: number) {
|
||||||
|
// // this._y = Math.floor(v);
|
||||||
|
// this._y = v;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export {Vector, VectorInteger}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
import { Vector, VectorInteger } from "./Vector.js";
|
||||||
|
|
||||||
|
interface Component {
|
||||||
|
pos: VectorInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GraphicComponent extends Component {
|
||||||
|
ctx: CanvasRenderingContext2D;
|
||||||
|
color: string;
|
||||||
|
update: () => void;
|
||||||
|
clear: (pos?: VectorInteger) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Moving {
|
||||||
|
dir: Vector;
|
||||||
|
speed: number; // pixel per second
|
||||||
|
move(delta: number): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {Component, GraphicComponent, Moving}
|
||||||
47
srcs/requirements/svelte/api_front/public/game/enums.ts
Normal file
47
srcs/requirements/svelte/api_front/public/game/enums.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
enum EventTypes {
|
||||||
|
// Class Implemented
|
||||||
|
gameUpdate = 1,
|
||||||
|
scoreUpdate,
|
||||||
|
matchEnd,
|
||||||
|
assignId,
|
||||||
|
matchmakingComplete,
|
||||||
|
|
||||||
|
// Generic
|
||||||
|
matchmakingInProgress,
|
||||||
|
matchStart,
|
||||||
|
matchNewRound, // unused
|
||||||
|
matchPause, // unused
|
||||||
|
matchResume, // unused
|
||||||
|
|
||||||
|
// Client
|
||||||
|
clientAnnounce,
|
||||||
|
clientPlayerReady,
|
||||||
|
clientInput,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
enum InputEnum {
|
||||||
|
noInput = 0,
|
||||||
|
up = 1,
|
||||||
|
down,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PlayerSide {
|
||||||
|
left = 1,
|
||||||
|
right
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ClientRole {
|
||||||
|
player = 1,
|
||||||
|
spectator
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MatchOptions {
|
||||||
|
// binary flags, can be mixed
|
||||||
|
noOption = 0b0,
|
||||||
|
multiBalls = 1 << 0,
|
||||||
|
movingWalls = 1 << 1
|
||||||
|
}
|
||||||
|
|
||||||
|
export {EventTypes, InputEnum, PlayerSide, ClientRole, MatchOptions}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
import * as c from "./constants.js";
|
||||||
|
import { MovingRectangle } from "../shared_js/class/Rectangle.js";
|
||||||
|
import { GameComponents } from "./class/GameComponents.js";
|
||||||
|
|
||||||
|
function wallsMovements(delta: number, gc: GameComponents)
|
||||||
|
{
|
||||||
|
const wallTop = <MovingRectangle>gc.wallTop;
|
||||||
|
const wallBottom = <MovingRectangle>gc.wallBottom;
|
||||||
|
if (wallTop.pos.y <= 0 || wallTop.pos.y >= c.movingWallPosMax) {
|
||||||
|
wallTop.dir.y *= -1;
|
||||||
|
}
|
||||||
|
if (wallBottom.pos.y >= c.h-c.wallSize || wallBottom.pos.y <= c.h-c.movingWallPosMax) {
|
||||||
|
wallBottom.dir.y *= -1;
|
||||||
|
}
|
||||||
|
wallTop.moveAndCollide(delta, [gc.playerLeft, gc.playerRight]);
|
||||||
|
wallBottom.moveAndCollide(delta, [gc.playerLeft, gc.playerRight]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {wallsMovements}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
<script>
|
||||||
|
import "public/game/pong.js"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="preload_font">.</div>
|
||||||
|
|
||||||
|
<div id="div_game_options">
|
||||||
|
<fieldset>
|
||||||
|
<legend>game options</legend>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="multi_balls" name="multi_balls">
|
||||||
|
<label for="multi_balls">multiples balls</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="moving_walls" name="moving_walls">
|
||||||
|
<label for="moving_walls">moving walls</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>sound :</label>
|
||||||
|
<input type="radio" id="sound_on" name="sound_selector" checked>
|
||||||
|
<label for="sound_on">on</label>
|
||||||
|
<input type="radio" id="sound_off" name="sound_selector">
|
||||||
|
<label for="sound_off">off</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button id="play_pong_button">PLAY</button>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="canvas_container">
|
||||||
|
<!-- <p> =) </p> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="public/game/pong.js" type="module" defer></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bit5x3";
|
||||||
|
src: url("/fonts/Bit5x3.woff2") format("woff2"),local("Bit5x3"), url("/fonts/Bit5x3.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
#preload_font {
|
||||||
|
font-family: "Bit5x3";
|
||||||
|
opacity:0;
|
||||||
|
height:0;
|
||||||
|
width:0;
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background-color: #222425;
|
||||||
|
}
|
||||||
|
#canvas_container {
|
||||||
|
text-align: center;
|
||||||
|
/* border: dashed rgb(245, 245, 245) 5px; */
|
||||||
|
/* max-height: 80vh; */
|
||||||
|
/* overflow: hidden; */
|
||||||
|
}
|
||||||
|
#div_game_options {
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Bit5x3";
|
||||||
|
color: rgb(245, 245, 245);
|
||||||
|
font-size: x-large;
|
||||||
|
}
|
||||||
|
#div_game_options fieldset {
|
||||||
|
max-width: 50vw;
|
||||||
|
width: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
#div_game_options fieldset div {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
#play_pong_button {
|
||||||
|
font-family: "Bit5x3";
|
||||||
|
color: rgb(245, 245, 245);
|
||||||
|
background-color: #333333;
|
||||||
|
font-size: x-large;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
background-color: #333333;
|
||||||
|
max-width: 75vw;
|
||||||
|
/* max-height: 100vh; */
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||||
|
|
||||||
"include": ["src/**/*"],
|
"include": ["src/**/*", "public/game"],
|
||||||
"exclude": ["node_modules/*", "__sapper__/*", "public/*"]
|
"exclude": ["node_modules/*", "__sapper__/*", "public/*"]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user