42_ft_transcendence/games/objects/Game.py

145 lines
4.4 KiB
Python

from transcendence.abstract.AbstractRoom import AbstractRoom
from transcendence.abstract.AbstractRoomMember import AbstractRoomMember
from channels.generic.websocket import WebsocketConsumer
from .Ball import Ball
from .Player import Player
from .Spectator import Spectator
from .Wall import Wall
import math
from .. import config
from ..models import GameModel
class Game(AbstractRoom):
def __init__(self, game_id):
super().__init__(None)
self.ball: Ball = Ball()
game_model: GameModel = GameModel.objects.get(pk = game_id)
self.players_id: list[int] = game_model.get_players_id()
self.started = False
radius: float = min(config.MAP_SIZE_X, config.MAP_SIZE_Y) / 2 - 10
self.nb_sides = len(self.players_id) * 2
self.polygon: list[tuple[float, float]] = []
for i in range(self.nb_sides):
angle: float = (i * 2 * math.pi / self.nb_sides) + (math.pi * 3 / 4)
x: float = config.MAP_CENTER_X + radius * math.cos(angle)
y: float = config.MAP_CENTER_Y + radius * math.sin(angle)
self.polygon.append((x, y))
self.players: list[Player] = []
self.spectators: list[Spectator] = []
self.walls: list[Wall] = []
for i in range(1, self.nb_sides, 2):
self.walls.append(Wall(*self.polygon[i], *self.polygon[(i + 1) % self.nb_sides]))
self.game_id: int = game_id
def broadcast(self, detail: str, data: dict = {}, excludeds: list[Spectator | Player] = []):
members: list[Player | Spectator] = self.players + self.spectators
for excluded in excludeds:
members.remove(excluded)
for member in members:
member.send(detail, data)
def get_player_by_user_id(self, user_id: int) -> Player:
for player in self.players:
player: Player
if (player.user_id == user_id):
return player
return None
def _send_game_data(self, member: AbstractRoomMember):
member.send("init_game", self.to_dict())
def append(self, member: AbstractRoomMember):
super().append(member)
member.send("init_game", self.to_dict())
def _player_join(self, user_id: int, socket: WebsocketConsumer):
#check if member is a player
if (user_id not in self.players_id):
return None
# check if player is already connected
player = self.get_player_by_user_id(user_id)
if (player is not None):
player.disconnect(1001)
index: int = self.players_id.index(user_id) * 2
player = Player(user_id, socket, *self.polygon[index], *self.polygon[(index + 1) % self.nb_sides])
self.players.append(player)
player.accept()
self.broadcast("player_join", player.to_dict(), [player])
return player
def _player_leave(self, player: Player):
# TODO send data to all players
self.players.remove(player)
def _spectator_join(self, user_id: int, socket: WebsocketConsumer):
spectator: Spectator = Spectator(user_id, socket)
self.spectators.append(spectator)
spectator.accept()
return spectator
def _spectator_leave(self, spectator: Spectator):
self.spectators.remove(spectator)
def join(self, user_id: int, socket: WebsocketConsumer) -> Spectator | Player:
if (user_id in self.players_id):
member: Player = self._player_join(user_id, socket)
print("yo")
else:
member: Spectator = self._spectator_join(user_id, socket)
self._send_game_data(member)
return member
def start(self):
self.started = True
def remove(self, member: AbstractRoomMember):
if (isinstance(member, Player)):
self._player_leave(member)
elif (isinstance(member, Spectator)):
self._spectator_leave(member)
def to_dict(self):
data: dict = {"ball": self.ball.to_dict(),
"players": [player.to_dict() for player in self.players],
"walls": [wall.to_dict() for wall in self.walls],
}
print(self.players )
return data