From 4aafbac1a59ae50189fdfbf0cee303e929d39a9b Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Fri, 25 Nov 2022 14:54:17 +0100 Subject: [PATCH] collision algo with Hugo + ball.dir added to EventGameUpdate --- src/client/class/RectangleClient.ts | 4 +- src/client/ws.ts | 20 ++++++--- src/server/class/GameSession.ts | 16 +++++-- src/shared_js/class/Event.ts | 16 +++++-- src/shared_js/class/Rectangle.ts | 68 ++++++++++++++++++++--------- src/shared_js/constants.ts | 6 +-- 6 files changed, 93 insertions(+), 37 deletions(-) diff --git a/src/client/class/RectangleClient.ts b/src/client/class/RectangleClient.ts index da2e9396..526b7744 100644 --- a/src/client/class/RectangleClient.ts +++ b/src/client/class/RectangleClient.ts @@ -93,8 +93,8 @@ class BallClient extends Ball implements GraphicComponent { this._bounceAlgo(collider); soundPongArr[ Math.floor(random(0, soundPongArr.length)) ].play(); } - /* protected _bouncePlayer(collider: Racket) { - this._bouncePlayerAlgo(collider); + /* protected _bounceRacket(collider: Racket) { + this._bounceRacketAlgo(collider); soundRoblox.play(); } */ } diff --git a/src/client/ws.ts b/src/client/ws.ts index 28e2d6a1..16084660 100644 --- a/src/client/ws.ts +++ b/src/client/ws.ts @@ -81,12 +81,20 @@ function inGameListener(event: MessageEvent) function gameUpdate(data: ev.EventGameUpdate) { console.log("gameUpdate"); - gc.playerLeft.pos.y = Math.floor(data.playerLeft.y); - gc.playerRight.pos.y = Math.floor(data.playerRight.y); - gc.ball.pos.x = Math.floor(data.ball.x); - gc.ball.pos.y = Math.floor(data.ball.y); - gc.ball.speed = Math.floor(data.ball.speed); - + + gc.playerLeft.pos.y = data.playerLeft.y; + gc.playerRight.pos.y = data.playerRight.y; + gc.ball.pos.x = data.ball.x; + gc.ball.pos.y = data.ball.y; + gc.ball.speed = data.ball.speed; + + gc.ball.dir.x = data.ball.dirX; + gc.ball.dir.y = data.ball.dirY; + + // ERROR: Uncaught TypeError: gc.ball.pos.assign is not a function + // Why ? + // gc.ball.pos.assign( data.ball.x, data.ball.y ); + repeatInput(data.lastInputId); // server reconciliation } diff --git a/src/server/class/GameSession.ts b/src/server/class/GameSession.ts index cfe0c4c0..c6b00095 100644 --- a/src/server/class/GameSession.ts +++ b/src/server/class/GameSession.ts @@ -97,9 +97,19 @@ class GameSession { const gc = s.components; const update: ev.EventGameUpdate = { type: en.EventTypes.gameUpdate, - playerLeft: {y: gc.playerLeft.pos.y}, - playerRight: {y: gc.playerRight.pos.y}, - ball: {x: gc.ball.pos.x, y: gc.ball.pos.y, speed: gc.ball.speed}, + playerLeft: { + y: gc.playerLeft.pos.y + }, + playerRight: { + y: gc.playerRight.pos.y + }, + ball:{ + x: gc.ball.pos.x, + y: gc.ball.pos.y, + dirX: gc.ball.dir.x, + dirY: gc.ball.dir.y, + speed: gc.ball.speed + }, lastInputId: 0 }; s.playersMap.forEach( (client) => { diff --git a/src/shared_js/class/Event.ts b/src/shared_js/class/Event.ts index da0da306..d35d1f0d 100644 --- a/src/shared_js/class/Event.ts +++ b/src/shared_js/class/Event.ts @@ -26,9 +26,19 @@ class EventMatchmakingComplete extends ServerEvent { } class EventGameUpdate extends ServerEvent { - playerLeft = {y: 0}; - playerRight = {y: 0}; - ball = {x: 0, y: 0, speed: 0}; + playerLeft = { + y: 0 + }; + playerRight = { + y: 0 + }; + ball = { + x: 0, + y: 0, + dirX: 0, + dirY: 0, + speed: 0 + }; lastInputId = 0; constructor() { // TODO: constructor that take GameComponentsServer maybe ? super(en.EventTypes.gameUpdate); diff --git a/src/shared_js/class/Rectangle.ts b/src/shared_js/class/Rectangle.ts index 8ebd6415..c3ad81ad 100644 --- a/src/shared_js/class/Rectangle.ts +++ b/src/shared_js/class/Rectangle.ts @@ -11,23 +11,24 @@ class Rectangle implements Component { this.width = width; this.height = height; } - collision(collider: Rectangle): boolean { // Collision WIP. To redo - var myleft = this.pos.x; - var myright = this.pos.x + (this.width); - var mytop = this.pos.y; - var mybottom = this.pos.y + (this.height); - var otherleft = collider.pos.x; - var otherright = collider.pos.x + (collider.width); - var othertop = collider.pos.y; - var otherbottom = collider.pos.y + (collider.height); - if ((mybottom < othertop) - || (mytop > otherbottom) - || (myright < otherleft) - || (myleft > otherright)) { + 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 + else { return true; + } } } @@ -75,7 +76,7 @@ class Ball extends MovingRectangle { /* 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._bouncePlayer(collider); + this._bounceRacket(collider); } else { this._bounceWall(); @@ -93,13 +94,40 @@ class Ball extends MovingRectangle { protected _bounceWall() { // Should be enough for Wall this.dir.y = this.dir.y * -1; } - protected _bouncePlayer(collider: Racket) { - this._bouncePlayerAlgo(collider); + protected _bounceRacket(racket: Racket) { + this._bounceRacketAlgo(racket); } - protected _bouncePlayerAlgo(collider: Racket) { // WIP - // Bounce for Racket need to be more complexe than this + protected _bounceRacketAlgo(racket: Racket) { this.speed += this.baseSpeed/20; - this.dir.x = this.dir.x * -1; + + 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.10; + 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) + const normalizationFactor = Math.abs(y) + Math.abs(x); + this.dir.assign(x/normalizationFactor, y/normalizationFactor); + */ } } diff --git a/src/shared_js/constants.ts b/src/shared_js/constants.ts index f014e9cd..c540d1a3 100644 --- a/src/shared_js/constants.ts +++ b/src/shared_js/constants.ts @@ -7,12 +7,12 @@ 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/50); -export const ph = pw*5; +export const pw = Math.floor(w/60); +export const ph = pw*6; export const ballSize = pw; export const wallSize = Math.floor(w/100); export const playerSpeed = Math.floor(w/1.5); // pixel per second -export const ballSpeed = Math.floor(w/1.5); // pixel per second +export const ballSpeed = Math.floor(w/2); // pixel per second export const matchStartDelay = 3000; // millisecond export const newRoundDelay = 1500; // millisecond