game: add: close game when nobody in

This commit is contained in:
starnakin 2024-02-21 19:04:25 +01:00
parent 0e5ff11e83
commit c6b0539894
4 changed files with 59 additions and 14 deletions

View File

@ -16,6 +16,11 @@ class GameModel(models.Model):
def start(self):
self.started = True
def finish(self, winner_id):
self.winner_id = winner_id
self.finished = True
self.save()
def get_players_id(self):
return [game_player.player_id for game_player in GameMembersModel.objects.filter(game_id = self.pk)]

View File

@ -22,15 +22,22 @@ from ..routine import routine
import threading
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .GameManager import GameManager
class Game(AbstractRoom):
def __init__(self, game_id):
def __init__(self, game_id: int, game_manager):
super().__init__(None)
self.game_manager: GameManager = game_manager
self.ball: Ball = Ball()
self.model: GameModel = GameModel.objects.get(pk = game_id)
self.started = False
self.stopped: bool = False
radius: float = min(config.MAP_SIZE_X, config.MAP_SIZE_Y) / 2 - 10
@ -105,6 +112,12 @@ class Game(AbstractRoom):
return False
return True
def nobody_is_here(self):
for player in self.players:
if player.is_connected():
return False
return len(self.spectators) == 0
def _player_join(self, user_id: int, socket: WebsocketConsumer):
player = self.get_player_by_user_id(user_id)
@ -127,7 +140,14 @@ class Game(AbstractRoom):
def _update_player(self, player: Player):
self._updated_players.append(player)
def finish(self, winner: Player):
self.model.finish(winner.user_id)
def _player_leave(self, player: Player):
if (self.nobody_is_here()):
if (self.model.started):
self.finish(player)
return
self._update_player(player)
def _spectator_join(self, user_id: int, socket: WebsocketConsumer):
@ -149,9 +169,8 @@ class Game(AbstractRoom):
return member
def start(self):
if (self.started == True):
if (self.model.started == True):
return
self.started = True
self.model.start()
def leave(self, member: AbstractRoomMember):
@ -159,6 +178,10 @@ class Game(AbstractRoom):
self._player_leave(member)
elif (isinstance(member, Spectator)):
self._spectator_leave(member)
if (self.nobody_is_here()):
self.stopped = True
self.thread.join(10)
self.game_manager.remove(self)
def to_dict(self):

View File

@ -1,12 +1,15 @@
from ..models import GameModel
from .Game import Game
from ..models import GameModel
class GameManager():
def __init__(self) -> None:
self._game_list: list[Game] = []
def remove(self, game: Game):
self._game_list.remove(game)
def get(self, game_id: int) -> Game:
if (not GameModel.objects.filter(pk = game_id, finished = False).exists()):
@ -17,7 +20,7 @@ class GameManager():
if (game.game_id == game_id):
return game
game: Game = Game(game_id)
game: Game = Game(game_id, self)
self._game_list.append(game)

View File

@ -253,7 +253,7 @@ async def update_ball(game: Game, impact_data: dict) -> None:
await SyncToAsync(game.broadcast)("update_ball", game.ball.to_dict())
async def render(game: Game):
async def render_ball(game: Game):
while True:
@ -262,16 +262,30 @@ async def render(game: Game):
impact_data: dict = get_impact_data(segments, game.ball)
await update_ball(game, impact_data)
def routine(game: Game):
asyncio.run(render(game))
async def render_players(game: Game):
while True:
for player in game._updated_players:
game.broadcast("update_paddle", player.to_dict(), [player])
game._updated_players.clear()
sleep(1 / config.SERVER_TPS)
await asyncio.sleep(1 / config.SERVER_TPS)
async def render(game: Game):
routine_ball = asyncio.create_task(render_ball(game))
routine_players = asyncio.create_task(render_players(game))
while(True):
if (game.stopped):
routine_ball.cancel()
routine_players.cancel()
return
await asyncio.sleep(0.3)
def routine(game: Game):
asyncio.run(render(game))