game: online: recoded but collision not work

This commit is contained in:
2024-05-14 03:28:05 +02:00
parent 18bc8a0028
commit 7a0ff15cec
16 changed files with 518 additions and 653 deletions

View File

@ -3,11 +3,6 @@ from __future__ import annotations
from channels.generic.websocket import WebsocketConsumer
from .ASpectator import ASpectator
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from games.objects.AGame import AGame
class APlayer(ASpectator):
def is_connected(self) -> bool:

View File

@ -16,11 +16,12 @@ class Ball:
self.speed: float
self.reset()
self.speed = 0
def reset(self) -> None:
self.size = config.BALL_SIZE
self.position = Position(Point(config.BALL_SPAWN_POS_X + self.size / 2, config.BALL_SPAWN_POS_Y + self.size / 2), time.time())
self.angle = math.pi * 0.3
self.angle = math.pi * 1
self.speed = config.BALL_SPEED_START
def to_dict(self) -> dict:

View File

@ -1,184 +1,191 @@
from transcendence.abstract.AbstractRoom import AbstractRoom
from transcendence.abstract.AbstractRoomMember import AbstractRoomMember
from channels.generic.websocket import WebsocketConsumer
from ..AGame import AGame
from .Ball import Ball
from .PongPlayer import PongPlayer
from .PongSpectator import PongSpectator
from .Wall import Wall
from .Point import Point
from .Segment import Segment
import math
from .Point import Point
from .Ball import Ball
from ... import config
from channels.generic.websocket import WebsocketConsumer
from django.contrib.auth.models import User
from ...routine import routine
import threading
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from profiles.models import ProfileModel
class PongGame(AGame):
def __init__(self, game_id: int, game_manager):
super().__init__("pong", game_id, game_manager)
self.ball: Ball = Ball()
self.stopped: bool = False
radius: float = min(config.MAP_SIZE_X, config.MAP_SIZE_Y) / 2 - 10
players: list[ProfileModel] = self.model.get_players()
nb_sides = 4
polygon: list[Point] = []
for i in range(nb_sides):
angle: float = (i * 2 * math.pi / nb_sides) + (math.pi * 3 / nb_sides)
x: float = round(config.MAP_CENTER_X + radius * math.cos(angle))
y: float = round(config.MAP_CENTER_Y + radius * math.sin(angle))
polygon.append(Point(x, y))
segments: list[Segment] = []
for i in range(nb_sides):
segments.append(Segment(polygon[i], polygon[(i + 1) % nb_sides]))
self.walls: list[Wall]
self.players: list[PongPlayer]
self.walls: list[Wall]
players: list[User] = self.model.get_players()
nb_players: int = len(players)
if (nb_players == 2):
self.players = [PongPlayer(self, players[0], None, segments[0]), PongPlayer(self, players[1], None, segments[2])]
self.walls = [Wall(segments[1].start, segments[1].stop), Wall(segments[3].start, segments[3].stop)]
corners = [Point(50, config.MAP_CENTER_Y - config.MAP_SIZE_Y / 4),
Point(config.MAP_SIZE_X - 50, config.MAP_CENTER_Y - config.MAP_SIZE_Y / 4),
Point(config.MAP_SIZE_X - 50, config.MAP_CENTER_Y + config.MAP_SIZE_Y / 4),
Point(50, config.MAP_CENTER_Y + config.MAP_SIZE_Y / 4)
]
self.players = [PongPlayer(self, players[0], None, Segment(corners[1].copy(), corners[2].copy())),
PongPlayer(self, players[1], None, Segment(corners[0].copy(), corners[3].copy()))]
self.walls = [Wall(corners[0], corners[1]),
Wall(corners[2], corners[3])]
else:
corners: list[Point] = [Point(50, 50),
Point(config.MAP_SIZE_X - 50, 50),
Point(config.MAP_SIZE_X - 50, config.MAP_CENTER_Y - 50),
Point(50, config.MAP_SIZE_Y - 50)]
self.players = []
self.walls = []
for i in range(4):
if (i < nb_players):
self.players.append(PongPlayer(self, players[i], None, segments[i]))
if i < nb_players:
self.players.append(PongPlayer(self, players[i], None, Segment(corners[i], corners[(i + 1) % 4])))
else:
self.walls.append(Wall(segments[i]))
self.walls.append(Segment(corners[i], corners[(i + 1) % 4]))
self.spectators: list[PongSpectator]
self.ball: Ball = Ball()
def goal(self, goal_defenser: PongPlayer) -> None:
self._updated_players: list[PongPlayer] = []
timestamp: int = goal_defenser.add_goal()
self.broadcast("goal", {"player_id": goal_defenser.user.pk,
"timestamp": timestamp})
if len(goal_defenser.score) >= config.GAME_MAX_SCORE:
self.eliminate(goal_defenser)
player_list = self.get_valid_players()
if len(player_list) == 1:
self.finish(player_list[0])
return
self.ball.reset()
self.broadcast("update_ball", self.ball.to_dict())
self.game_id: int = game_id
def get_valid_players(self) -> list[PongPlayer]:
return [player for player in self.players if player.is_connected and not player.is_eliminated]
def finish(self, winner: PongPlayer) -> bool:
self.broadcast("finish", {'winner_id': winner.user.pk})
self.model.finish(winner.user)
self.stopped = True
def start(self):
# Set to true to stop the thread routine
self.stopped: bool = False
self.model.start()
self.broadcast("start")
self.thread = threading.Thread(target = routine, args=(self,))
self.ball.reset()
self.broadcast("update_ball", self.ball.to_dict())
self.thread = threading.Thread(target=routine, args=(self,))
self.thread.start()
def goal(self, goal_taker: PongPlayer):
def eliminate(self, eliminated: PongPlayer):
timestamp = goal_taker.add_goal()
self.broadcast("eliminated", {"eliminated_id": eliminated.user.pk})
self.broadcast("goal", {"player_id": goal_taker.user_id,
"timestamp": timestamp})
if (len(goal_taker.score) >= config.GAME_MAX_SCORE):
connected_players: list[PongPlayer] = self.get_players_connected()
if (len(connected_players) == 2):
self.finish(connected_players[not connected_players.index(goal_taker)])
else:
goal_taker.eliminate()
def _send_game_data(self, member: PongSpectator | PongPlayer):
member.send("init_game", self.to_dict())
def _everbody_is_here(self):
return len(self.players) == len(self.get_players_connected())
def _nobody_is_here(self):
return len(self.get_players_connected()) == 0
def _player_join(self, user_id: int, socket: WebsocketConsumer):
eliminated.eliminate()
def _player_join(self, user: User, socket: WebsocketConsumer) -> PongPlayer | None:
if (self.model.started):
return None
player = self.get_player_by_user_id(user_id)
player = self.get_player_by_user_id(user.pk)
if (player is None):
return None
# check if player is already connected
if (player.is_connected()):
player.disconnect(1001)
player.socket = socket
if (self._everbody_is_here()):
self.update_player(player)
if len(self.players) == len(self.get_players_connected()):
self.start()
self.update_player(player)
return player
def update_player(self, player: PongPlayer):
self._updated_players.append(player)
def finish(self, winner: PongPlayer):
self.broadcast("finish", {"winner": winner.to_dict()})
self.model.finish(winner.user_id)
def _player_leave(self, player: PongPlayer):
def _spectator_join(self, user: User, socket: WebsocketConsumer) -> PongSpectator:
connected_players: list[PongPlayer] = self.get_players_connected()
if (self.model.started):
if (len(connected_players) == 1):
print([player.username for player in connected_players])
last_player: PongPlayer = connected_players[0]
self.finish(last_player)
return
self.update_player(player)
def _spectator_join(self, user_id: int, socket: WebsocketConsumer):
spectator: PongSpectator = PongSpectator(user_id, socket, self)
spectator: PongSpectator = PongSpectator(user, socket, self)
self.spectators.append(spectator)
return spectator
def _spectator_leave(self, spectator: PongSpectator):
self.spectators.remove(spectator)
def join(self, user_id: int, socket: WebsocketConsumer) -> PongSpectator | PongPlayer:
member: PongPlayer = self._player_join(user_id, socket)
if (member is None):
member: PongSpectator = self._spectator_join(user_id, socket)
self._send_game_data(member)
return member
def start(self):
if (self.model.started == True):
return
self.model.start()
def join(self, user: User, socket: WebsocketConsumer) -> PongSpectator | PongPlayer:
member: PongPlayer | PongSpectator
member = self._player_join(user, socket)
if member is None:
member = self._spectator_join(user, socket)
self._send_game_data(member)
return member
def _player_leave(self, player: PongPlayer):
if self.model.started:
self.eliminate(player)
players: list[PongPlayer] = self.get_valid_players()
if len(players) == 1:
self.finish(players[0])
def _spectator_leave(self, spectator: PongSpectator):
self.spectators.remove(spectator)
def leave(self, member: PongSpectator | PongPlayer):
def leave(self, member: AbstractRoomMember):
if (isinstance(member, PongPlayer)):
self._player_leave(member)
elif (isinstance(member, PongSpectator)):
self._spectator_leave(member)
if (self._nobody_is_here()):
self.stopped = True
self.thread.join(10)
self.game_manager.remove(self)
if self.model.started:
if len(self.get_players_connected()) + len(self.spectators) == 0:
self.stopped = True
if hasattr(self, 'thread'):
self.thread.join(10)
self.game_manager.remove(self)
def to_dict(self):
def _send_game_data(self, member: PongSpectator | PongPlayer):
member.send("init_game", self.to_dict())
def update_player(self, player: PongPlayer):
self.broadcast("update_player", player.to_dict(), [player])
def to_dict(self):
data: dict = {"ball": self.ball.to_dict(),
"players": [player.to_dict() for player in self.players],

View File

@ -27,14 +27,14 @@ class PongPlayer(APlayer):
self.rail: Segment = rail
self.is_eliminated: bool = False
self.game: PongGame
def eliminate(self):
self.disconnect(1000)
self.is_eliminated = True
self.game.update_player(self)
def receive(self, data: dict):
detail: str = data.get("detail")
@ -108,7 +108,7 @@ class PongPlayer(APlayer):
def add_goal(self):
timestamp = self.game.model.add_goal(self.user_id)
timestamp = self.game.model.add_goal(self.user)
self.score.append(timestamp)
@ -122,6 +122,8 @@ class PongPlayer(APlayer):
"position": self.position.to_dict(),
"score": self.score,
"isEliminated": self.is_eliminated,
"rail": self.rail.to_dict(),
"isConnected": self.is_connected(),

View File

@ -2,7 +2,7 @@ from __future__ import annotations
from channels.generic.websocket import WebsocketConsumer
from transcendence.abstract.AbstractRoomMember import AbstractRoomMember
from django.contrib.auth.models import User
from typing import TYPE_CHECKING
@ -15,8 +15,8 @@ from .Ball import Ball
class PongSpectator(ASpectator):
def __init__(self, user_id: int, socket: WebsocketConsumer, game: PongGame):
super().__init__(user_id, socket, game)
def __init__(self, user: User, socket: WebsocketConsumer, game: PongGame):
super().__init__(user, socket, game)
self.game: PongGame = game
def send_paddle(self, player: PongPlayer):

View File

@ -5,7 +5,7 @@ class Position:
def __init__(self, location: int | Point = 0, time: int = 0) -> None:
self.time: float = time
self.location: float = location
self.location: float | Point = location
def copy(self):
try: