Skip to content

Commit

Permalink
Merge pull request #190 from tdameros/pong-game-points
Browse files Browse the repository at this point in the history
Pong game points
  • Loading branch information
V-Fries authored Feb 8, 2024
2 parents aeb390f + 071de85 commit 3605db1
Show file tree
Hide file tree
Showing 18 changed files with 243 additions and 96 deletions.
21 changes: 19 additions & 2 deletions front/src/threejs/Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,14 @@
>> 'move_speed': float
>> }
>> },
>> ... (Should have 2 players)
>> ... (Should have at least 2 players)
>> ],
>> 'ball': {
>> 'position': {'x': float, 'y': float, 'z': float},
>> 'movement': {'x': float, 'y': float, 'z': float},
>> 'radius': float
>> 'ball_is_waiting': bool,
>> 'ball_start_time': Optional[float] (Seconds since the Epoch),
>> }
>> }
>> ]
Expand Down Expand Up @@ -101,6 +103,21 @@
>
>> Updates the position and direction of the player at index player_index
- ### `update_ball`:
>> Argument:
>> ```
>> {
>> 'match_index': int,
>> 'ball_movement': {'x': float, 'y': float, 'z': float}
>> 'ball_start_time': float (Seconds since the Epoch),
>> }
>> ```
>
>> For the ball at `match[match_index]`:
>> Sets the ball position to `[0., 0., current_position.z]`.
>> Sets the ball movement to `'ball_movement'`
>> Stops the ball movement till `ball_start_time`
- ### `update_ball`:
>> Argument:
>> ```
Expand All @@ -111,4 +128,4 @@
>> }
>> ```
>
>> Updates the position and movement of the ball in the match at index match_index
>> Updates the position and movement of the ball in the match at index match_index
30 changes: 21 additions & 9 deletions front/src/threejs/Engine/sockets/_GameSocketIO.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,33 @@ export class _GameSocketIO {

this.#socketIO.on('scene', (data) => {
console.log('game scene received');
// this.#engine.stopAnimationLoop();
this.#engine.scene = new Scene(data['scene']['matches'],
data['player_location']);
this.#engine.scene = new Scene(
data['scene']['matches'],
data['player_location'],
);
this.#engine.startListeningForKeyHooks();
});

this.#socketIO.on('update_player', (data) => {
console.log('update_player received');
const playerLocation = data['player_location'];
this.#engine.scene
.setPlayerPaddleDirection(playerLocation,
data['direction']);
this.#engine.scene
.setPlayerPaddlePosition(playerLocation,
data['position']);
this.#engine.scene.setPlayerPaddleDirection(
playerLocation,
data['direction'],
);
this.#engine.scene.setPlayerPaddlePosition(
playerLocation,
data['position'],
);
});

this.#socketIO.on('prepare_ball_for_match', (data) => {
console.log('prepare_ball_for_match received');
const matchIndex = data['match_index'];
this.#engine.scene.matches[matchIndex].prepare_ball_for_match(
data['ball_start_time'],
data['ball_movement'],
);
});

this.#socketIO.on('update_ball', (data) => {
Expand Down
5 changes: 5 additions & 0 deletions front/src/threejs/Scene/Ball.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export class Ball {
this.#movement = jsonToVector3(ballJson['movement']);
}

prepareForMatch(ballMovementJson) {
this.#threeJSGroup.position.set(0., 0., this.#threeJSGroup.position.z);
this.#movement.set(ballMovementJson['x'], ballMovementJson['y'], ballMovementJson['z']);
}

updateFrame(timeDelta, matchBoundingBox, leftPaddle, rightPaddle) {
if (this.#movement.x === 0.) return;

Expand Down
26 changes: 21 additions & 5 deletions front/src/threejs/Scene/Match.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ export class Match {
#ball;
#ballBoundingBox;
#paddleBoundingBox;
#ballIsWaiting;
#ballStartTime;

constructor(matchJson) {
this.#ball = new Ball(matchJson['ball']);
this.#ballIsWaiting = matchJson['ball_is_waiting'];
this.#ballStartTime = matchJson['ball_start_time'];

const playersJson = matchJson['players'];
this.#players.push(new Player(playersJson[0]));
Expand All @@ -31,13 +35,25 @@ export class Match {
this.#paddleBoundingBox = new PaddleBoundingBox(playersJson[0]);
}

updateFrame(timeDelta) {
updateFrame(timeDelta, currentTime) {
this.#players[0].updateFrame(timeDelta, this.#paddleBoundingBox);
this.#players[1].updateFrame(timeDelta, this.#paddleBoundingBox);
this.#ball.updateFrame(timeDelta,
this.#ballBoundingBox,
this.#players[0].paddle,
this.#players[1].paddle);

if (this.#ballIsWaiting && currentTime >= this.#ballStartTime) {
this.#ballIsWaiting = false;
}
if (this.#ballIsWaiting === false) {
this.#ball.updateFrame(timeDelta,
this.#ballBoundingBox,
this.#players[0].paddle,
this.#players[1].paddle);
}
}

prepare_ball_for_match(ballStartTime, ballMovementJson) {
this.#ballIsWaiting = true;
this.#ballStartTime = ballStartTime * 1000;
this.#ball.prepareForMatch(ballMovementJson);
}

setBallMovement(movementJson) {
Expand Down
3 changes: 2 additions & 1 deletion front/src/threejs/Scene/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ export class Scene {
}

updateFrame(timeDelta) {
const currentTime = Date.now();
for (const match of this.#matches) {
match.updateFrame(timeDelta);
match.updateFrame(timeDelta, currentTime);
}
}

Expand Down
7 changes: 4 additions & 3 deletions pong_server/dev_deprecated_redirection_server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ function quit() {
}

while true; do
kill -9 $(pgrep '[P]ython')
kill -9 `pgrep '[P]ython'`
sleep 1
clear
`sed 's/^/export /' ../.env`
export PONG_GAME_SERVERS_MIN_PORT=60200
export PONG_GAME_SERVERS_MAX_PORT=60210
python -m unittest discover test
(
cd src/redirection_server_deprecated &&
find . -name '*.py' |
( find . -name '*.py' && find ../game_server -name '*.py' ) |
entr -z -d python3 main.py
)
done
2 changes: 1 addition & 1 deletion pong_server/dev_game_creator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export GAME_SERVER_PATH=~/git/transcendence/pong_server/src/game_server/


(cd src/game_creator/ && python3 manage.py test) || exit $?
kill -9 $(pgrep '[P]ython')
kill -9 `pgrep '[P]ython'`

(cd src/game_creator/ && python3 manage.py runserver)
7 changes: 4 additions & 3 deletions pong_server/src/game_server/Game.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Optional

import numpy
import socketio

import rooms as rooms
from Scene.PlayerFinder.PlayerFinder import PlayerFinder
Expand Down Expand Up @@ -44,12 +45,12 @@ def is_user_part_of_game(self, user_id: int) -> bool:
def get_sid_from_user_id(self, user_id: int) -> str | None:
return self._player_sid_map.get(user_id)

async def add_user(self, user_id: int, sid: str, sio):
async def add_user(self, user_id: int, sid: str, sio: socketio.AsyncServer):
self._player_sid_map[user_id] = sid
self._player_finder.add_player(user_id, sid)
await sio.enter_room(sid, rooms.ALL_PLAYERS)

async def remove_user(self, sid: str, sio):
async def remove_user(self, sid: str, sio: socketio.AsyncServer):
try:
user_id: int | None = self._user_id_map.pop(sid)
if user_id is not None:
Expand All @@ -69,7 +70,7 @@ def get_player_location(self, sid: str) -> PlayerLocation | None:
return self._player_finder.get_player_location_from_sid(sid)

async def set_player_movement_and_position(self,
sio,
sio: socketio.AsyncServer,
player_location: PlayerLocation,
direction: str,
player_position: numpy.ndarray,
Expand Down
86 changes: 49 additions & 37 deletions pong_server/src/game_server/Scene/Ball.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Optional

import numpy
import socketio

import rooms
import settings
Expand All @@ -12,18 +13,22 @@
from vector_to_dict import vector_to_dict


class Match(object):
def get_index(self) -> int:
pass

async def player_marked_point(self, sio: socketio.AsyncServer, player_index: int):
pass


class Ball(object):
def __init__(self):
self._position: numpy.ndarray = numpy.array([0.,
0.,
settings.BALL_RADIUS / 2.])

x = -5.5 if random.randint(0, 1) == 0 else 5.5
y = -2.8 if random.randint(0, 1) == 0 else 2.8
self._movement: numpy.ndarray = numpy.array([x, y, 0.])
self._original_movement = self._movement.copy()
# TODO delete self._original_movement (it is required for now, but won't
# be once the game is finished)
self._movement: numpy.ndarray = numpy.array([0., 0., 0.])
self._set_random_movement()

def to_json(self) -> dict:
return {
Expand All @@ -33,12 +38,35 @@ def to_json(self) -> dict:
'acceleration': settings.BALL_ACCELERATION
}

async def update_position(self,
sio,
time_delta: float,
left_paddle: Paddle,
right_paddle: Paddle,
match_index: int):
def prepare_for_match(self):
self._position[0] = 0.
self._position[1] = 0.
self._set_random_movement()

def _set_random_movement(self):
min_x = 4.5
max_x = 6.5
if random.randint(0, 1) == 0:
self._movement[0] = random.uniform(-max_x, -min_x)
else:
self._movement[0] = random.uniform(min_x, max_x)

min_y = 1.8
max_y = 3.
if random.randint(0, 1) == 0:
self._movement[1] = random.uniform(-max_y, -min_y)
else:
self._movement[1] = random.uniform(min_y, max_y)

def get_movement(self) -> numpy.ndarray:
return self._movement

async def update(self,
sio: socketio.AsyncServer,
time_delta: float,
left_paddle: Paddle,
right_paddle: Paddle,
match: Match):
if self._movement[0] == 0.:
return

Expand All @@ -55,7 +83,7 @@ async def update_position(self,
travel,
left_paddle if self._movement[0] < 0. else right_paddle,
time_delta,
match_index
match
)

if should_fix_position:
Expand All @@ -64,15 +92,15 @@ async def update_position(self,
await emit(sio, 'update_ball', rooms.ALL_PLAYERS,
{'position': vector_to_dict(self._position),
'movement': vector_to_dict(self._movement),
'match_index': match_index,
'match_index': match.get_index(),
'debug': 'update_position'})

async def _handle_collisions(self,
sio,
sio: socketio.AsyncServer,
travel: Segment2,
paddle: Paddle,
time_delta: float,
match_index: int) -> (bool, bool):
match: Match) -> (bool, bool):
""" Returns (should_emit_update_ball: bool, should_fix_position: bool) """

(collision_detected, should_emit_update_ball) = await self._handle_paddle_collision(
Expand All @@ -81,8 +109,8 @@ async def _handle_collisions(self,
if collision_detected:
return should_emit_update_ball, True

if await self._handle_match_point(sio, match_index):
return True, False
if await self._handle_match_point(sio, match):
return False, False

self._handle_board_collision()
return False, True
Expand Down Expand Up @@ -122,28 +150,12 @@ async def _handle_paddle_collision(self,
return True, True
return True, False

async def _handle_match_point(self, sio, match_index: int):
async def _handle_match_point(self, sio: socketio.AsyncServer, match: Match) -> bool:
if self._position[0] <= settings.BALL_BOUNDING_BOX.get_x_min():
self._position[0] = 0.
self._position[1] = 0.
self._movement = self._original_movement.copy()
await emit(sio, 'update_ball', rooms.ALL_PLAYERS,
{'position': vector_to_dict(self._position),
'movement': vector_to_dict(self._movement),
'match_index': match_index})
# TODO Should send a match_update instead (not implemented yet)
# TODO should mark a point for left player
await match.player_marked_point(sio, 1)
return True
elif self._position[0] >= settings.BALL_BOUNDING_BOX.get_x_max():
self._position[0] = 0.
self._position[1] = 0.
self._movement = self._original_movement.copy()
await emit(sio, 'update_ball', rooms.ALL_PLAYERS,
{'position': vector_to_dict(self._position),
'movement': vector_to_dict(self._movement),
'match_index': match_index})
# TODO Should send a match_update instead (not implemented yet)
# TODO should mark a point for right player
await match.player_marked_point(sio, 0)
return True
return False

Expand Down
Loading

0 comments on commit 3605db1

Please sign in to comment.