from __future__ import annotations import pygame import random import math from typing import Tuple, TYPE_CHECKING from entity import Entity from screen import Screen if TYPE_CHECKING: from player import Player class Ball(Entity): def __init__(self, screen_manager: Screen, player:Player, bot:Player): self.player: Player = player self.bot: Player = bot self.size = 30 color_ball = (255, 200, 200, 255) image:pygame.Surface = pygame.Surface((self.size, self.size), pygame.SRCALPHA) pygame.draw.circle(image, color_ball, (round(self.size / 2), round(self.size / 2)), self.size / 2) origin: Tuple[int, int] = (round(screen_manager.get_screen().get_size()[0] / 2) - round(self.size / 2), round(screen_manager.get_screen().get_size()[1] / 2) - round(self.size / 2)) super().__init__("Ball", origin, image, screen_manager) self.speed: int = 25 self.friction.x = 1 # le vrai speed est la différence entre friction.x et speed self.velocity.max = 10 ** 2 # Mettre au carré pour économiser des calcules plus tard (sur la normalisation du mouvement) self.velocity.min = 2 self.collide: bool = False def draw(self): self.screen.blit(self.image, (self.pos.x, self.pos.y)) def speed_up(self): self.velocity.x = self.velocity.x + .75 if (self.velocity.x > 0) else self.velocity.x - .75 self.velocity.y = self.velocity.y + .75 if (self.velocity.y > 0) else self.velocity.y - .75 def move(self, deltatime: float): if (self.velocity.x == 0 and self.velocity.y == 0): # si la balle est a l'arret lui donner un mouvement aléatoire self.velocity.x = random.randint(1, int(self.velocity.min)) self.velocity.y = random.randint(1, int(self.velocity.min)) norm: float = self.velocity.x ** 2 + self.velocity.y ** 2 # norme du vecteur mouvement scale: float = 1 if (norm > self.velocity.max): scale = math.sqrt(self.velocity.max / norm) elif(norm < self.velocity.min): scale = math.sqrt(self.velocity.min / norm) self.velocity.x *= scale self.velocity.y *= scale if (self.pos.x < 0 or (self.pos.x + round(self.size / 2)) > self.screen.get_size()[0]): self.velocity.x = -self.velocity.x # Collision avec le mur # collision avec le joueur if ((self.pos.y + self.size / 2) >= self.player.pos.y - self.player.size[1] and self.pos.y <= self.player.pos.y): if (self.pos.x + self.size >= self.player.pos.x and self.pos.x - self.size <= self.player.pos.x + self.player.size[0]): self.velocity.y = -self.velocity.y if not self.collide: self.speed_up() self.collide = True # collision avec le bot elif (self.pos.y - round(self.size / 2) <= self.bot.pos.y and self.pos.y >= self.bot.pos.y + self.bot.size[1]): if (self.pos.x + self.size >= self.bot.pos.x and self.pos.x - self.size <= self.bot.pos.x + self.bot.size[0]): self.velocity.y = -self.velocity.y if not self.collide: self.speed_up() self.collide = True else: self.collide = False self.pos.x += round(self.velocity.x) self.pos.y += round(self.velocity.y) def as_winner(self) -> int: if (self.pos.y < 0): return 0 # Joueur a gagner if (self.pos.y > self.screen.get_size()[1]): return 1 # Bot a gagner return -1