From 2475b0c407a0eb57bab30523bfcf218288ec9177 Mon Sep 17 00:00:00 2001 From: V-Fries Date: Wed, 7 Feb 2024 08:29:30 +0100 Subject: [PATCH 1/3] Typing, and very light refactoring --- pong_server/dev_deprecated_redirection_server.sh | 7 ++++--- pong_server/dev_game_creator.sh | 2 +- pong_server/src/game_server/Game.py | 7 ++++--- pong_server/src/game_server/Scene/Player/_Board.py | 2 +- .../src/game_server/update_player_movement_and_position.py | 3 ++- pong_server/src/shared_code/emit.py | 4 +++- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/pong_server/dev_deprecated_redirection_server.sh b/pong_server/dev_deprecated_redirection_server.sh index 2e31b550..fb7fb2dc 100755 --- a/pong_server/dev_deprecated_redirection_server.sh +++ b/pong_server/dev_deprecated_redirection_server.sh @@ -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 diff --git a/pong_server/dev_game_creator.sh b/pong_server/dev_game_creator.sh index cfbb20b4..7e5e4fd9 100755 --- a/pong_server/dev_game_creator.sh +++ b/pong_server/dev_game_creator.sh @@ -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) diff --git a/pong_server/src/game_server/Game.py b/pong_server/src/game_server/Game.py index d960a284..1b02cd9e 100644 --- a/pong_server/src/game_server/Game.py +++ b/pong_server/src/game_server/Game.py @@ -2,6 +2,7 @@ from typing import Optional import numpy +import socketio import rooms as rooms from Scene.PlayerFinder.PlayerFinder import PlayerFinder @@ -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: @@ -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, diff --git a/pong_server/src/game_server/Scene/Player/_Board.py b/pong_server/src/game_server/Scene/Player/_Board.py index ee6d0c88..09540dd9 100644 --- a/pong_server/src/game_server/Scene/Player/_Board.py +++ b/pong_server/src/game_server/Scene/Player/_Board.py @@ -15,5 +15,5 @@ def to_json() -> dict: 'size': vector_to_dict(settings.BOARD_SIZE) } - def update_position(self, time_delta: float): + def update(self, time_delta: float): pass diff --git a/pong_server/src/game_server/update_player_movement_and_position.py b/pong_server/src/game_server/update_player_movement_and_position.py index 16b8f4f9..844eb936 100644 --- a/pong_server/src/game_server/update_player_movement_and_position.py +++ b/pong_server/src/game_server/update_player_movement_and_position.py @@ -1,4 +1,5 @@ import numpy +import socketio from Game import Game from Scene.PlayerFinder.PlayerLocation import PlayerLocation @@ -33,7 +34,7 @@ def get_fixed_player_position(game: Game, return None -async def update_player_direction_and_position(sio, +async def update_player_direction_and_position(sio: socketio.AsyncServer, sid: str, game: Game, client_player_position_list: list[float], diff --git a/pong_server/src/shared_code/emit.py b/pong_server/src/shared_code/emit.py index a4d97b6d..b1c7476d 100644 --- a/pong_server/src/shared_code/emit.py +++ b/pong_server/src/shared_code/emit.py @@ -1,7 +1,9 @@ import logging +import socketio -async def emit(sio, + +async def emit(sio: socketio.AsyncServer, event: str, room: str, message: any, From e4fe3ad8684409362e9dc4a3a39301aa6fb6141a Mon Sep 17 00:00:00 2001 From: V-Fries Date: Wed, 7 Feb 2024 08:30:25 +0100 Subject: [PATCH 2/3] Fixed game server not cleaning up correctly --- pong_server/src/game_server/main.py | 37 +++++++++++++++++++---------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/pong_server/src/game_server/main.py b/pong_server/src/game_server/main.py index 5583d6e8..ae6fdd31 100644 --- a/pong_server/src/game_server/main.py +++ b/pong_server/src/game_server/main.py @@ -17,11 +17,13 @@ from update_player_movement_and_position import \ update_player_direction_and_position -sio = socketio.AsyncServer(cors_allowed_origins='*') -app = web.Application() +sio: socketio.AsyncServer = socketio.AsyncServer(cors_allowed_origins='*') +app: web.Application = web.Application() sio.attach(app) -should_exit = False -exit_code = 0 +runner = web.AppRunner(app) + +should_exit: bool = False +exit_code: int = 0 game: Game | None = None @@ -100,13 +102,15 @@ async def background_task(): try: await wait_for_all_players_to_join() + await game.get_scene().start_game(sio) + await game_loop() except Exception as e: try: # Attempt graceful exit print(f'Error: in background_task: {e}') """ Do not use logging! This should always be printed as the game - creator will read it """ + creator may read it """ logging.critical(f'Error in background_task: {e}') global exit_code global should_exit @@ -130,7 +134,6 @@ async def start_background_task(app): async def start_server(): - runner = web.AppRunner(app) await runner.setup() start_port = int(os.getenv('PONG_GAME_SERVERS_MIN_PORT')) @@ -139,7 +142,7 @@ async def start_server(): for port in range(start_port, end_port + 1): try: - server = web.TCPSite(runner, '0.0.0.0', port) + server = web.TCPSite(runner, '0.0.0.0', port=port) await server.start() return port except OSError: @@ -151,6 +154,7 @@ async def start_server(): async def main(): try: setup_logging(f'Game Server {os.getpid()}: ') + logging.getLogger('aiohttp').setLevel(logging.WARNING) logging.debug(f'Starting Game Server({os.getpid()})') global game @@ -159,8 +163,8 @@ async def main(): port = await start_server() uri = f'http://localhost:{port}' # TODO should be 42.shiftcode.fr in prod print(f'uri: {uri}') - """ Do not use logging! This should always be printed as the redirection - server will read it """ + """ Do not use logging! This should always be printed as the game + creator will read it """ sys.stdout.flush() except Exception as e: print(f'Error: {str(e)}') @@ -174,9 +178,18 @@ async def main(): while True: await sio.sleep(5) - if should_exit: # set to True by background_task - exit(exit_code) + if should_exit: # set to True by background_task() + logging.debug('Cleaning up before exiting') + loop = asyncio.get_running_loop() + tasks = [task for task in asyncio.all_tasks() + if task is not asyncio.current_task()] + for task in tasks: + task.cancel() + await runner.cleanup() + loop.stop() + logging.info(f'Exiting with code {exit_code}') + return exit_code if __name__ == '__main__': - asyncio.run(main()) + exit(asyncio.run(main())) From 071de85ffc13d11b732a0f8316fe9f7d87fcdd2f Mon Sep 17 00:00:00 2001 From: V-Fries Date: Wed, 7 Feb 2024 08:39:04 +0100 Subject: [PATCH 3/3] Game points are now stored and the ball now stays immobile for a few seconds before moving --- front/src/threejs/Documentation.md | 21 ++++- .../threejs/Engine/sockets/_GameSocketIO.js | 30 +++++-- front/src/threejs/Scene/Ball.js | 5 ++ front/src/threejs/Scene/Match.js | 26 ++++-- front/src/threejs/Scene/Scene.js | 3 +- pong_server/src/game_server/Scene/Ball.py | 86 +++++++++++-------- pong_server/src/game_server/Scene/Match.py | 76 +++++++++++++--- .../src/game_server/Scene/Player/Paddle.py | 2 +- .../src/game_server/Scene/Player/Player.py | 6 +- pong_server/src/game_server/Scene/Scene.py | 19 ++-- pong_server/src/game_server/settings.py | 3 + 11 files changed, 203 insertions(+), 74 deletions(-) diff --git a/front/src/threejs/Documentation.md b/front/src/threejs/Documentation.md index 64d69fc4..f8bd81b7 100644 --- a/front/src/threejs/Documentation.md +++ b/front/src/threejs/Documentation.md @@ -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), >> } >> } >> ] @@ -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: >> ``` @@ -111,4 +128,4 @@ >> } >> ``` > - >> Updates the position and movement of the ball in the match at index match_index \ No newline at end of file + >> Updates the position and movement of the ball in the match at index match_index diff --git a/front/src/threejs/Engine/sockets/_GameSocketIO.js b/front/src/threejs/Engine/sockets/_GameSocketIO.js index 5fa6d9ff..332594eb 100644 --- a/front/src/threejs/Engine/sockets/_GameSocketIO.js +++ b/front/src/threejs/Engine/sockets/_GameSocketIO.js @@ -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) => { diff --git a/front/src/threejs/Scene/Ball.js b/front/src/threejs/Scene/Ball.js index 21927c06..d4ad0bca 100644 --- a/front/src/threejs/Scene/Ball.js +++ b/front/src/threejs/Scene/Ball.js @@ -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; diff --git a/front/src/threejs/Scene/Match.js b/front/src/threejs/Scene/Match.js index d541b263..e9ba23c8 100644 --- a/front/src/threejs/Scene/Match.js +++ b/front/src/threejs/Scene/Match.js @@ -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])); @@ -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) { diff --git a/front/src/threejs/Scene/Scene.js b/front/src/threejs/Scene/Scene.js index e9681991..23d692e8 100644 --- a/front/src/threejs/Scene/Scene.js +++ b/front/src/threejs/Scene/Scene.js @@ -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); } } diff --git a/pong_server/src/game_server/Scene/Ball.py b/pong_server/src/game_server/Scene/Ball.py index f1d5ea7f..6db1417c 100644 --- a/pong_server/src/game_server/Scene/Ball.py +++ b/pong_server/src/game_server/Scene/Ball.py @@ -3,6 +3,7 @@ from typing import Optional import numpy +import socketio import rooms import settings @@ -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 { @@ -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 @@ -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: @@ -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( @@ -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 @@ -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 diff --git a/pong_server/src/game_server/Scene/Match.py b/pong_server/src/game_server/Scene/Match.py index 2e2e173b..696b605f 100644 --- a/pong_server/src/game_server/Scene/Match.py +++ b/pong_server/src/game_server/Scene/Match.py @@ -1,34 +1,90 @@ +import time +from typing import Optional + import numpy +import socketio +import rooms +import settings from Scene.Ball import Ball from Scene.Player.Player import Player +from shared_code.emit import emit from vector_to_dict import vector_to_dict class Match(object): - def __init__(self, position: numpy.ndarray): + def __init__(self, position: numpy.ndarray, match_index: int): + self.MATCH_INDEX = match_index self._position = position.copy() self._players: list[Player] = [Player(is_player_on_the_right=False), Player(is_player_on_the_right=True)] + self._points: list[int] = [0, 0] + self._ball: Ball = Ball() + self._ball_is_waiting: bool = True + self._ball_start_time: Optional[float] = None def to_json(self) -> dict: + if self._ball_start_time is None: + ball_start_time = None + else: + ball_start_time = self._ball_start_time + return { 'position': vector_to_dict(self._position), 'players': [player.to_json() for player in self._players], - 'ball': self._ball.to_json() + 'ball': self._ball.to_json(), + 'ball_is_waiting': self._ball_is_waiting, + 'ball_start_time': ball_start_time, } - async def update_positions(self, sio, time_delta: float, match_index: int): - self._players[0].update_position(time_delta) - self._players[1].update_position(time_delta) - await self._ball.update_position(sio, - time_delta, - self._players[0].get_paddle(), - self._players[1].get_paddle(), - match_index) + def get_index(self) -> int: + return self.MATCH_INDEX + + async def start_game(self, sio: socketio.AsyncServer): + await self.prepare_ball_for_match(sio) + + async def update(self, sio: socketio.AsyncServer, time_delta: float, current_time: float): + self._players[0].update(time_delta) + self._players[1].update(time_delta) + + if self._ball_is_waiting and current_time >= self._ball_start_time: + self._ball_is_waiting = False + if not self._ball_is_waiting: + await self._ball.update(sio, + time_delta, + self._players[0].get_paddle(), + self._players[1].get_paddle(), + self) + + async def player_marked_point(self, sio: socketio.AsyncServer, player_index: int): + self._points[player_index] += 1 + + if self._points[player_index] >= settings.POINTS_TO_WIN: + await self._finish_match(sio, player_index) + return + + await self.prepare_ball_for_match(sio) + + # TODO send point update to tournament / matchmaking + + async def _finish_match(self, sio: socketio.AsyncServer, winner_index: int): + await self.prepare_ball_for_match(sio) # TODO delete this once this + # function is implemented + + # TODO send match finish to tournament / matchmaking + + async def prepare_ball_for_match(self, sio: socketio.AsyncServer): + self._ball.prepare_for_match() + self._ball_is_waiting = True + self._ball_start_time = time.time() + settings.BALL_WAITING_TIME_SEC + await emit(sio, 'prepare_ball_for_match', rooms.ALL_PLAYERS, { + 'match_index': self.MATCH_INDEX, + 'ball_start_time': self._ball_start_time, + 'ball_movement': vector_to_dict(self._ball.get_movement()), + }) def get_player(self, index: int) -> Player: return self._players[index] diff --git a/pong_server/src/game_server/Scene/Player/Paddle.py b/pong_server/src/game_server/Scene/Player/Paddle.py index 45698a47..63fc2570 100644 --- a/pong_server/src/game_server/Scene/Player/Paddle.py +++ b/pong_server/src/game_server/Scene/Player/Paddle.py @@ -24,7 +24,7 @@ def to_json(self) -> dict: 'move_speed': settings.PADDLE_MOVE_SPEED } - def update_position(self, time_delta: float): + def update(self, time_delta: float): self._position += self._movement * time_delta if self._position[1] <= settings.PADDLE_BOUNDING_BOX.get_y_min(): diff --git a/pong_server/src/game_server/Scene/Player/Player.py b/pong_server/src/game_server/Scene/Player/Player.py index 5e230c69..87b860f0 100644 --- a/pong_server/src/game_server/Scene/Player/Player.py +++ b/pong_server/src/game_server/Scene/Player/Player.py @@ -28,9 +28,9 @@ def to_json(self) -> dict: 'paddle': self._paddle.to_json() } - def update_position(self, time_delta: float): - self._paddle.update_position(time_delta) - self._board.update_position(time_delta) + def update(self, time_delta: float): + self._paddle.update(time_delta) + self._board.update(time_delta) def set_paddle_direction(self, direction: str): self._paddle.set_direction(direction) diff --git a/pong_server/src/game_server/Scene/Scene.py b/pong_server/src/game_server/Scene/Scene.py index 99dcaebf..c191e8a5 100644 --- a/pong_server/src/game_server/Scene/Scene.py +++ b/pong_server/src/game_server/Scene/Scene.py @@ -1,4 +1,7 @@ +import time + import numpy +import socketio import settings from Scene.Match import Match @@ -13,9 +16,8 @@ def __init__(self, nb_of_players: int): match_x_position: float = 0. for i in range(int(nb_of_players / 2)): - self._matches.append(Match(numpy.array([match_x_position, - 0., - 0.]))) + match_position = numpy.array([match_x_position, 0., 0.]) + self._matches.append(Match(match_position, i)) match_x_position += settings.BOARD_SIZE[0] * 2. + settings.BOARD_SIZE[0] / 2. def to_json(self): @@ -23,9 +25,14 @@ def to_json(self): "matches": [match.to_json() for match in self._matches] } - async def update(self, sio, time_delta: float): - for i in range(len(self._matches)): - await self._matches[i].update_positions(sio, time_delta, i) + async def start_game(self, sio: socketio.AsyncServer): + for match in self._matches: + await match.start_game(sio) + + async def update(self, sio: socketio.AsyncServer, time_delta: float): + current_time = time.time() + for match in self._matches: + await match.update(sio, time_delta, current_time) def get_match(self, index: int): return self._matches[index] diff --git a/pong_server/src/game_server/settings.py b/pong_server/src/game_server/settings.py index 9a08e58a..8089a919 100644 --- a/pong_server/src/game_server/settings.py +++ b/pong_server/src/game_server/settings.py @@ -11,8 +11,11 @@ BALL_RADIUS: float = 1. BALL_ACCELERATION: float = 1.1 BALL_BOUNDING_BOX: BallBoundingBox = BallBoundingBox() +BALL_WAITING_TIME_SEC: float = 2. PADDLE_SIZE: numpy.ndarray = numpy.array([1., 5., 1.]) PADDLE_MOVE_SPEED: float = 9. PADDLE_X_POSITION: float = BOARD_SIZE[0] * 0.5 - BALL_RADIUS * 1.5 - PADDLE_SIZE[0] * 0.5 PADDLE_BOUNDING_BOX: PaddleBoundingBox = PaddleBoundingBox() + +POINTS_TO_WIN: int = 5