Commit 3b42f6e6 authored by Boris OUYA's avatar Boris OUYA
Browse files

Merge branch 'comm' into 'main'

Comm

See merge request !23
parents b9430c43 cf9c7636
......@@ -36,15 +36,24 @@ class AbstractBall(pg.sprite.Sprite, ABC):
@abstractmethod
def _init_paddles(self,data):
"""
Initialise les raquêtes
"""
...
def getSpeed(self) -> float:
return self.speed
def launch(self) -> None:
self.launched = True
def choose_ball_orientation(self, dep : str):
"""Déplace l'orientation de la balle dans le sens spécifée par dep: up -> vers la droite de la
verticale vers le haut; down -> vers la gauche de la verticale vers le haut;
"""
current_angle = math.radians(
self.orientation.angle_to(pg.Vector2(1, 0)))
......@@ -70,18 +79,21 @@ class AbstractBall(pg.sprite.Sprite, ABC):
def move(self,ignore=False):
self.rect.x = round(self.rect.x + self.speed * self.orientation.x)
self.rect.y = round(self.rect.y + self.speed * self.orientation.y)
return self.collision(self.tiles)
def reflect(self, normal_vector):
"""Réfléchit le vecteur orientation selon la normale spécifiée"""
if normal_vector.magnitude() != 0:
self.orientation = self.orientation.reflect(normal_vector)
def get_orientation(self): return self.orientation.x,self.orientation.y
def collision_mur(self):
"""Gère la collision avec les murs"""
normal_vector = pg.math.Vector2()
collision = False
if self.rect.top < 3: # haut
......@@ -106,6 +118,8 @@ class AbstractBall(pg.sprite.Sprite, ABC):
def _reflect_on_paddle(self,paddle):
"""Gère la collision sur la barre spécifiée"""
self.rect.left -= round(self.orientation.x * self.speed)
self.rect.top -= round(self.orientation.y * self.speed)
......@@ -127,6 +141,7 @@ class AbstractBall(pg.sprite.Sprite, ABC):
@abstractmethod
def collision_barre(self):
"""vérifie et gère la collion avec une barre"""
...
def get_pos(self):
......@@ -134,6 +149,7 @@ class AbstractBall(pg.sprite.Sprite, ABC):
def collision_tile(self, tiles):
"""Gère la collision avec les tuiles"""
hits = pg.sprite.spritecollide(self, tiles,False)
collision = False
......@@ -201,6 +217,7 @@ class AbstractBall(pg.sprite.Sprite, ABC):
return (collision, hit)
def up_speed(self):
"""Augmente la vitesse et borne l'angle de la direction"""
self.speed = min(self.speed + 0.01, self.max_speed)
if abs(self.orientation.y) < math.sin(math.pi/16):
self.orientation.y = -math.sin(math.pi/16) if self.orientation.y < 0 else math.sin(math.pi/16)
......@@ -210,7 +227,8 @@ class AbstractBall(pg.sprite.Sprite, ABC):
return self.rect.y > DISPLAY_HEIGHT
def collision(self, tiles):
"""Gère toutes les collisions et renvoie un tuple
(la coliision a eu lieu?, la tuile touchée éventuellement"""
data_coll_barre = self.collision_barre()
if data_coll_barre[0]:
return True,data_coll_barre[1]
......@@ -222,6 +240,7 @@ class AbstractBall(pg.sprite.Sprite, ABC):
return coll_tile[0] or coll_mur, coll_tile[1]
def main_menu_init(self):
"""Initialisation pour l'écran de début"""
self.launched = True
self.orientation.x = 1
self.orientation.y = -1
......@@ -232,7 +251,7 @@ class AbstractBall(pg.sprite.Sprite, ABC):
def main_menu_collision(self, collision):
"""Collision pour l'écran de début"""
normal_vector = pg.math.Vector2()
if self.rect.top < 3: # haut
......@@ -277,6 +296,7 @@ class AbstractBall(pg.sprite.Sprite, ABC):
def main_menu(self):
"""Gère la balle dans l'écran de menu"""
collision = False
for _ in range(4):
self.rect.x += self.orientation.x
......@@ -286,6 +306,7 @@ class AbstractBall(pg.sprite.Sprite, ABC):
def draw(self):
self.screen.blit(self.img, pg.Rect(
self.rect.x, self.rect.y, self.width, self.height))
......
......@@ -63,6 +63,7 @@ class AbstractGamePhase(ABC):
@abstractmethod
def _init_entities(self,player_perk=None):
"""Initialise les entités de la classe"""
...
def getStatus(self):
......@@ -79,10 +80,12 @@ class AbstractGamePhase(ABC):
@classmethod
@abstractmethod
def constructFromTiles(cls, game, tiles,player_perk=None):
"""Retourne la scène de jeu construite à partir des tuile en paramètre"""
...
@classmethod
def getReprFromFile(cls,screen,filename):
"""Retourne les tuiles représentées dans filename"""
repr_tile = []
with open(filename, "rb") as f:
repr_tile = pickle.load(f)
......@@ -105,16 +108,20 @@ class AbstractGamePhase(ABC):
@classmethod
def loadSceneFrom(cls, game,screen, filename,player_perk=None):
"""Charge la scène de jeu à partir du fichier représentatif
des tuiles"""
tiles = cls.getReprFromFile(screen,filename)
return cls.constructFromTiles(game,tiles,player_perk)
@abstractmethod
def _process_horizontal_movement(self, key_state):
"""Gère les mouvements horizontaux des joueurs"""
...
def _prelaunch_on_space_pressed(self):
"""Action quand la barre espace est pressé pendant la phase de lancement"""
self._has_started = True
for barre in self._barres:
barre.inplay = True
......@@ -124,6 +131,7 @@ class AbstractGamePhase(ABC):
def _process_pre_launch_ball_orientation(self, key_state):
"""S'occupe de la réponse à la barre espace pendant la phase de lancement"""
if key_state["space"][0] == True:
self._prelaunch_on_space_pressed()
......@@ -141,6 +149,7 @@ class AbstractGamePhase(ABC):
@abstractmethod
def _manage_ball_hit(self,hit):
"""S'occupe des actions quand une tuile est touchée"""
...
......@@ -161,6 +170,7 @@ class AbstractGamePhase(ABC):
self.spawnParticlesAt(ball.get_pos(),color)
def _process_ball_logic_in_game(self):
for ball in self._balls:
collision_happened, hit = ball.move()
......
......@@ -35,10 +35,12 @@ class AbstractLevelLoader(State,ABC):
@abstractmethod
def _init_perks(self):
"""initialise les avantages du joueur"""
...
@abstractmethod
def _load_next_game_scene(self):
"""charge la scène de jeu suivante"""
...
def loadNextScene(self,shop=False) -> Union[GamePhase, None]:
......@@ -59,6 +61,7 @@ class AbstractLevelLoader(State,ABC):
def _update_keystate(self,keystate):
"""Altère le dictionnaire des clés"""
pass
def _manage_ongoing_scene(self, key_state: Dict[str, KeyData]) -> None:
......@@ -104,6 +107,7 @@ class AbstractLevelLoader(State,ABC):
@abstractmethod
def _isGamePhase(self,scene):
"""Vérifie si la scène du jeu actuelle est une scène de jeu"""
...
def update(self, key_state: Dict[str, KeyData]) -> None:
......
......@@ -25,68 +25,3 @@ class Balle(AbstractBall):
def _init_paddles(self,data):
self.barre = data
def main_menu_init(self):
self.launched = True
self.orientation.x = 1
self.orientation.y = -1
while 162 < self.rect.x < 177 + 251 and 45 < self.rect.y < 59 + 294:
self.rect.x = random.randint(0, 605)
self.rect.y = random.randint(0, 420)
def main_menu_collision(self, collision):
normal_vector = pg.math.Vector2()
if self.rect.top < 3: # haut
normal_vector = pg.math.Vector2(0, -1)
self.rect.top = 3
collision = True
if self.rect.left < 3: # gauche
normal_vector = pg.math.Vector2(1, 0)
self.rect.left = 3
collision = True
if self.rect.right > self.display_width - 3: # droite
normal_vector = pg.math.Vector2(-1, 0)
self.rect.right = self.display_width - 3
collision = True
if self.rect.top > DISPLAY_HEIGHT - 14:
normal_vector = pg.math.Vector2(0, 1)
self.rect.top = DISPLAY_HEIGHT - 14
collision = True
if self.rect.x == 163 and 45 < self.rect.y < 59 + 294:
normal_vector = pg.math.Vector2(-1, 0)
collision = True
if self.rect.x == 177 + 251 and 45 < self.rect.y < 59 + 294:
normal_vector = pg.math.Vector2(1, 0)
collision = True
if self.rect.y == 45 and 162 < self.rect.x < 177 + 251:
normal_vector = pg.math.Vector2(0, -1)
collision = True
if self.rect.y == 59 + 294 and 162 < self.rect.x < 177 + 251:
normal_vector = pg.math.Vector2(0, 1)
collision = True
self.reflect(normal_vector)
return collision
def main_menu(self):
collision = False
for _ in range(4):
self.rect.x += self.orientation.x
self.rect.y += self.orientation.y
collision = self.main_menu_collision(collision)
return collision
\ No newline at end of file
......@@ -68,6 +68,7 @@ class Barre(pg.sprite.Sprite):
self.delay_shoot = 600
def _manage_speed(self):
"""Change la vitesse selon la direction actuelle de la barre"""
if self.dir == "left":
self.vitesse -= self.freinage if self.vitesse > 0 else self.acceleration
if (self.vitesse < -1 * self.vitesseMax):
......@@ -139,6 +140,7 @@ class Barre(pg.sprite.Sprite):
def receiveSignal(self,signal):
"""Reçoit le type d'un item et réagit en conséquence """
if signal == 1:
self.shooting = False
if self.sprites == self.short_sprites:
......
......@@ -83,6 +83,9 @@ class Game:
height: int
) -> pygame.surface.Surface:
"""Renvoi l'image sous forme d'une surface avec la hauteur et la
largeur spécifiée"""
img_file = os.path.join("assets", image_filename)
img = pygame.image.load(img_file).convert().convert_alpha()
img = pygame.transform.scale(img, (width, height))
......@@ -92,6 +95,13 @@ class Game:
def _processMultipleKeyDown(self,event : pygame.event.Event) -> None:
"""
Rempli le dictionnaire des inputs avec les actions de l'utilisateur.
Supporte plusieurs inputs à la fois.
"""
if event.type != pygame.KEYDOWN:
return
keys = pygame.key.get_pressed()
......@@ -123,34 +133,11 @@ class Game:
self._key_states["z"] = (True, None)
"""def _processKeyDown(self,event : pygame.event.Event):
if event.type != pygame.KEYDOWN:
return
if event.unicode.isalnum():
self._key_states["characters"] = (True, event.unicode)
if event.key == pygame.K_RIGHT:
self._key_states["right"] = (True, None)
if event.key == pygame.K_LEFT:
self._key_states["left"] = (True, None)
if event.key == pygame.K_UP:
self._key_states["up"] = (True, None)
if event.key == pygame.K_DOWN:
self._key_states["down"] = (True, None)
if event.key == pygame.K_SPACE:
self._key_states["space"] = (True, None)
if event.key == pygame.K_BACKSPACE:
self._key_states["backspace"] = (True, None)
if event.key == pygame.K_ESCAPE:
self._key_states["escape"] = (True, None)
if event.key == pygame.K_q:
self._key_states["q"] = (True, None)
if event.key == pygame.K_d:
self._key_states["d"] = (True, None)
def _processMouseEvent(self , event : pygame.event.Event) -> None:
"""
def _processMouseEvent(self , event : pygame.event.Event) -> None:
Gère les inputs de type clic de souris
"""
if event.type == pygame.MOUSEBUTTONDOWN:
mouseStates = pygame.mouse.get_pressed(num_buttons=3)
......@@ -202,6 +189,11 @@ class Game:
show_rect: bool = False, rot: bool = False
) -> None:
"""
Ecrit le texte spécifié à la position spécifiée dans la
bonne couleur. si show_rect est mis à vrai, le rectangle englobant
est montré. Si rot est vrai, le texte est écrit dans l'axe des y.
"""
rect = pygame.Rect(position[0], position[1],
MIN_TEXT_RECT, TEXT_HEIGHT)
text_surface = self.font.render(text, True, color)
......@@ -220,21 +212,38 @@ class Game:
self._key_states[key] = (False, None)
def popStateStack(self) -> None:
"""
Retire l'état en sommet de la pile
"""
self._states_stack.pop()
def stack(self, state) -> None:
"""
ajoute un état au sommet de la pile
"""
self._states_stack.append(state)
def blitOnScreen(self, surface: pygame.Surface, rect: pygame.Rect) -> None:
"""
Affiche une surface à l'écran à la position spécifiée par rect
"""
self._screen.blit(surface, rect)
def get_column(self, x: int) -> int:
"""
Retourne la colonne correspondante à l'abcisse spécifiée
"""
return x // (TILE_WIDTH + GAP)
def get_row(self, y: int) -> int:
"""
Retourne la ligne correspondante à l'ordonnée spécifiée
"""
return y // (TILE_HEIGHT + GAP)
def get_coords(self, pos: Position) -> Position:
"""Retourne la colonne et la ligne de la position spécifiée"""
return self.get_column(pos[0]), self.get_row(pos[1])
......
......@@ -122,6 +122,7 @@ class GameIATrain(GameIA):
del hit
def return_closest_item_info(self):
"""Retourne un coefficient selon les informations de l'item le plus proche"""
if len(self._items) == 0:
return 0
......
......@@ -32,6 +32,7 @@ class GameLauncherTrain(GameIA):
def _initialize(self, net, screen=None, tiles=None, lives=3, rendering=False, decr=0,allow_items=False):
super()._initialize(net, screen, tiles, lives, rendering, decr)
self._balls[0].launched = False
self.gaming_net = GAME_NET
......
......@@ -22,6 +22,7 @@ class GamePhase(AbstractGamePhase):
def _init_entities(self,player_perk=None):
barre = Barre(self, self.display_width//2 -
60, self.display_height - 40)
......
......@@ -74,5 +74,5 @@ class GamePhaseIA(AbstractGamePhase):
self._barres[0].rect.w // 2 - self._balls[0].rect.w // 2
def return_scaled_inputs(self):
"""Retourne les inputs du réseau de neuronnes"""
return self.inputGen.return_scaled_inputs()
\ No newline at end of file
......@@ -37,6 +37,9 @@ class InputGenerator:
def return_closest_item_info(self):
"""
Retourne un coefficient pour l'item le plus proche
"""
if len(self._items) == 0:
return 0
......@@ -68,6 +71,8 @@ class InputGenerator:
return score
def getClosestBall(self):
"""Retourne la balle la plus prohce du joueur"""
closest = self._balls[0]
min_distance = (closest.rect.x - self._barres[0].rect.x) ** 2 + (closest.rect.y - self._barres[0].rect.y) ** 2
......@@ -81,6 +86,7 @@ class InputGenerator:
return closest
def return_scaled_inputs(self):
""" Retourne les inputs"""
ball = self.getClosestBall()
......
......@@ -155,6 +155,8 @@ class LevelGestionState(State):
self.bouton9.render()
def _render_selection(self) -> None:
"""Affiche la sélection à l'écran"""
for i in range(9):
color = (0, 0, 0)
mouse_pos = pygame.mouse.get_pos()
......
......@@ -89,6 +89,9 @@ class LevelSelectionToEditState(State):
return pygame.time.get_ticks() - self._last_click > self._delay
def _selections(self, pos: Position):
"""Gère les clics de la souris"""
if self._return_button.rect.collidepoint(*pos):
self.game.popStateStack()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment