diff --git a/components/button.py b/components/button.py index 44866f7..3c765ed 100644 --- a/components/button.py +++ b/components/button.py @@ -1,34 +1,34 @@ -import pygame - -#button class -class Button(): - def __init__(self, x, y, image, image2, scale): - width = image.get_width() - height = image.get_height() - self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale))) - self.image2 = pygame.transform.scale(image2, (int(width * scale), int(height * scale))) - self.rect = self.image.get_rect() - self.rect.topleft = (x, y) - self.clicked = False - - def draw_and_clicked(self, surface): - """ write button and return action""" - press_up_or_down = True - action = False - #get mouse position - pos = pygame.mouse.get_pos() - image = self.image - #check mouseover and clicked conditions - if self.rect.collidepoint(pos) : - image = self.image2 - if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False: - self.clicked = True - action = True - - if pygame.mouse.get_pressed()[0] == 0: - self.clicked = False - - #draw button on screen - surface.blit(image, (self.rect.x, self.rect.y)) - +import pygame + +#button class +class Button(): + def __init__(self, x, y, image, image2, scale): + width = image.get_width() + height = image.get_height() + self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale))) + self.image2 = pygame.transform.scale(image2, (int(width * scale), int(height * scale))) + self.rect = self.image.get_rect() + self.rect.topleft = (x, y) + self.clicked = False + + def draw_and_clicked(self, surface): + """ write button and return action""" + press_up_or_down = True + action = False + #get mouse position + pos = pygame.mouse.get_pos() + image = self.image + #check mouseover and clicked conditions + if self.rect.collidepoint(pos) : + image = self.image2 + if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False: + self.clicked = True + action = True + + if pygame.mouse.get_pressed()[0] == 0: + self.clicked = False + + #draw button on screen + surface.blit(image, (self.rect.x, self.rect.y)) + return action \ No newline at end of file diff --git a/events/ball_release_event_listener.py b/events/ball_release_event_listener.py index 315d15e..0e8d39f 100644 --- a/events/ball_release_event_listener.py +++ b/events/ball_release_event_listener.py @@ -1,75 +1,78 @@ -from events.event_listener import EventListener -from utils.stoppable_thread import StoppableThread -from utils.vector import Vector -from math import (atan, cos, sin) -from time import time -import pygame - -class BallReleaseEventListener(EventListener): - def __init__(self) -> None: - super().__init__() - - def run(self, event, game): - # retrieve the ball. - ball = game.get_window().get_element("ball") - # retrieve the placeholder ball. - placeholder_ball = game.get_window().get_element("placeholder_ball") - # check if the ball is at the same position - if abs(ball.get_x() - ball.get_initial_x()) < 15 and abs(ball.get_y() - ball.get_initial_y()) < 15 or ball.is_released(): - return - ball.set_released(True) - # disable ball. - placeholder_ball.set_visible(False) - # clear dots. - for i in range(20): - game.get_window().remove_element(("dot_",str(i))) - # launch new thread. - self.__t = StoppableThread(target=self.__move_ball, args=(game,)) - # register the thread in order to be able to kill it. - game.register_thread(self.__t) - # start the thread execution. - self.__t.start() - def __move_ball(self, game): - """ - Makes the ball move. - """ - # retrieve the ball. - ball = game.get_window().get_element("ball") - # define a delta time. - delta_time = 0.01 - # get the width and the height of the window. - w, h = pygame.display.get_surface().get_size() - # get the with and the height of the ball. - bw, bh = ball.get_surface().get_size() - # define the x and y values. - x, y = ball.get_x(), ball.get_y() - # define gravitation. - g = 9.81 - vx, vy = 0.1 * (ball.get_initial_x() - ball.get_x()), 0.1 * (ball.get_initial_y() - ball.get_y()) - # define our vector - v = Vector(vx, vy) - # define our reference time. - tr = time() - # update x and y position. - - while True: - if self.__t.stopped(): - break - ts = time() - tr - if ts >= delta_time: - v.set_y(v.get_y() + g * delta_time) - # update the ball's current coordinates. - x += v.get_x() * delta_time * 60 - y += v.get_y() * delta_time * 60 - # display the ball. - ball.set_x(x) - ball.set_y(y) - if y + bh >= h: - # calculate alpha. - alpha = atan(v.get_y() / v.get_x()) - # re-calculate alpha. - alpha = -alpha - # update vector. - v.set_x(v.normalize() * cos(alpha) * 0.8) - v.set_y(v.normalize() * sin(alpha) * 0.8) - tr += delta_time \ No newline at end of file +from events.event_listener import EventListener +from utils.stoppable_thread import StoppableThread +from utils.vector import Vector +from math import (atan, cos, sin) +from time import time +import pygame + + +class BallReleaseEventListener(EventListener): + def __init__(self) -> None: + super().__init__() + + def run(self, event, game): + # retrieve the ball. + ball = game.get_window().get_element("ball") + # retrieve the placeholder ball. + placeholder_ball = game.get_window().get_element("placeholder_ball") + # check if the ball is at the same position + if abs(ball.get_x() - ball.get_initial_x()) < 15 and abs(ball.get_y() - ball.get_initial_y()) < 15 or ball.is_released(): + return + ball.set_released(True) + # disable ball. + placeholder_ball.set_visible(False) + # clear dots. + for i in range(20): + game.get_window().remove_element(("dot_",str(i))) + # launch new thread. + self.__t = StoppableThread(target=self.__move_ball, args=(game,)) + # register the thread in order to be able to kill it. + game.register_thread(self.__t) + # start the thread execution. + self.__t.start() + + def __move_ball(self, game): + """ + Makes the ball move. + """ + # retrieve the ball. + ball = game.get_window().get_element("ball") + # define a delta time. + delta_time = 0.01 + # get the width and the height of the window. + w, h = pygame.display.get_surface().get_size() + # get the with and the height of the ball. + bw, bh = ball.get_surface().get_size() + # define the x and y values. + x, y = ball.get_x(), ball.get_y() + # define gravitation. + g = 9.81 + vx, vy = 0.1 * (ball.get_initial_x() - ball.get_x() + ), 0.1 * (ball.get_initial_y() - ball.get_y()) + # define our vector + v = Vector(vx, vy) + # define our reference time. + tr = time() + # update x and y position. + + while True: + if self.__t.stopped(): + break + ts = time() - tr + if ts >= delta_time: + v.set_y(v.get_y() + g * delta_time) + # update the ball's current coordinates. + x += v.get_x() * delta_time * 60 + y += v.get_y() * delta_time * 60 + # display the ball. + ball.set_x(x) + ball.set_y(y) + if y + bh >= h: + # calculate alpha. + alpha = atan(v.get_y() / v.get_x()) + # re-calculate alpha. + alpha = -alpha + # update vector. + v.set_x(v.normalize() * cos(alpha) * 0.8) + v.set_y(v.normalize() * sin(alpha) * 0.8) + tr += delta_time diff --git a/events/drag_event_listener.py b/events/drag_event_listener.py index a173c80..3d4b8f9 100644 --- a/events/drag_event_listener.py +++ b/events/drag_event_listener.py @@ -1,36 +1,37 @@ -from events.event_listener import EventListener -from element import Element -import pygame - - -class DragEventListener(EventListener): - def __init__(self) -> None: - super().__init__() - self.__white_dot = pygame.image.load("img/white_dot.png") - self.__white_dot = pygame.transform.scale(self.__white_dot, (20, 20)) - - def run(self, event, game): - # pre-register the dots. - for i in range(0, 20): - game.get_window().register_element(("dot_",str(i)), Element(self.__white_dot, 0, 0, False, False)) - # retrieve the ball. - ball = game.get_window().get_element("ball") - if pygame.mouse.get_pressed()[0] == True and not ball.is_released(): - # update x and y position. - ball.set_x(pygame.mouse.get_pos()[0] - 30) - ball.set_y(pygame.mouse.get_pos()[1] - 30) - # get the initial x and y value. - ix, iy = ball.get_initial_x(), ball.get_initial_y() - vx, vy = 1.1 * (ix - ball.get_x()), 1.1 * (iy - ball.get_y()) - for t in range(20): - # get the inital vector values. - x = (ball.get_x() + 30 + vx * t) - y = (9.81 * t**2 + vy * t + ball.get_y() + 30) - if t != 0: - # retrieve the dot. - dot = game.get_window().get_element(("dot_",str(t))) - # update x and y coordinates. - dot.set_x(x) - dot.set_y(y) - # set the dot visible. - dot.set_visible(True) \ No newline at end of file +from events.event_listener import EventListener +from element import Element +import pygame + + +class DragEventListener(EventListener): + def __init__(self) -> None: + super().__init__() + self.__white_dot = pygame.image.load("img/white_dot.png") + self.__white_dot = pygame.transform.scale(self.__white_dot, (20, 20)) + + def run(self, event, game): + # pre-register the dots. + for i in range(0, 20): + game.get_window().register_element(("dot_",str(i)), Element(self.__white_dot, 0, 0, False, False)) + # retrieve the ball. + ball = game.get_window().get_element("ball") + if pygame.mouse.get_pressed()[0] == True and not ball.is_released(): + # update x and y position. + ball.set_x(pygame.mouse.get_pos()[0] - 30) + ball.set_y(pygame.mouse.get_pos()[1] - 30) + # get the initial x and y value. + ix, iy = ball.get_initial_x(), ball.get_initial_y() + vx, vy = 1.1 * (ix - ball.get_x()), 1.1 * (iy - ball.get_y()) + for t in range(20): + # get the inital vector values. + x = (ball.get_x() + 30 + vx * t) + y = (9.81 * t**2 + vy * t + ball.get_y() + 30) + if t != 0: + # retrieve the dot. + dot = game.get_window().get_element(("dot_",str(t))) + # update x and y coordinates. + dot.set_x(x) + dot.set_y(y) + # set the dot visible. + dot.set_visible(True) + # get the initial x and y value. \ No newline at end of file diff --git a/game.py b/game.py index 5bbdcb4..d21bdca 100644 --- a/game.py +++ b/game.py @@ -10,8 +10,9 @@ from events.drag_event_listener import DragEventListener from events.ball_release_event_listener import BallReleaseEventListener + class Game(): - def __init__(self, screen:pygame.Surface, img_location:str, img_name: str, sound_location:str) -> None: + def __init__(self, screen: pygame.Surface, img_location: str, img_name: str, sound_location: str) -> None: # get the actual display screen. self.__screen = screen # set up playing players. @@ -37,22 +38,28 @@ def __init__(self, screen:pygame.Surface, img_location:str, img_name: str, sound # get the actual ball. ball = pygame.image.load(img_location + img_name+".png") # get the placeholder ball. - placeholder_ball = pygame.image.load(img_location + img_name+"-placeholder.png") + placeholder_ball = pygame.image.load( + img_location + img_name+"-placeholder.png") # register the field without public. self.get_window().register_element("field", Element(field2, 0, 0)) # register the ball. self.get_window().register_element("ball", Ball(ball, 170, 450)) # register the placeholder ball. - self.get_window().register_element("placeholder_ball", Element(placeholder_ball, 170, 450)) + self.get_window().register_element("placeholder_ball", + Element(placeholder_ball, 170, 450)) # listen to events. - self.listen(pygame.MOUSEMOTION, DragEventListener()) - self.listen(pygame.MOUSEBUTTONUP, BallReleaseEventListener()) + self.listen(pygame.MOUSEMOTION, + DragEventListener()) + self.listen(pygame.MOUSEBUTTONUP, + BallReleaseEventListener()) + def get_window(self) -> Window: """ :return: the game's window. """ return self.__window - def register_player(self, player_name:str) -> None: + + def register_player(self, player_name: str) -> None: """ Register a player by its name. :param: str player_name: the player's name. @@ -63,6 +70,7 @@ def register_player(self, player_name:str) -> None: player.setup() # register the player. self.__players.append(player) + def register_thread(self, thread) -> None: """ Register the given thread into a list. @@ -105,7 +113,8 @@ def setup(self): #cursor init self.__screen.blit(self.cursor,(x,y)) pygame.display.update() - def listen(self, event_type:int, event_listener:EventListener) -> None: + + def listen(self, event_type: int, event_listener: EventListener) -> None: """ Takes in parameter an event to call and an event type to listen to. Bind in pair the event type and the event to call. @@ -113,8 +122,10 @@ def listen(self, event_type:int, event_listener:EventListener) -> None: :param EventListener event_listener: the event listener that will be called. """ self.__events.append([event_type, event_listener]) + def end(self): pass + def get_screen(self): """ Return game's screen.