diff --git a/GUI.py b/GUI.py deleted file mode 100644 index bdddc13..0000000 --- a/GUI.py +++ /dev/null @@ -1,48 +0,0 @@ -import sys -import pygame -import components.button as button - -# init pygame. -pygame.init() -# load game icon. -icon = pygame.image.load("./img/Logo.png") -# set game icon. -pygame.display.set_icon(icon) -# set game name. -pygame.display.set_caption("ʙᴀsᴋᴇᴛ ɢᴏ !") -# define window's size. -window = pygame.display.set_mode((1024, 640)) -fond = pygame.image.load('./img/bg.png') -window.blit(fond, (0, 0)) -# load button images -start_img = pygame.image.load('./img/start_btn.png').convert_alpha() -exit_img = pygame.image.load('./img/exit_btn.png').convert_alpha() -start_img_hov = pygame.image.load('./img/start_btn_hover.png').convert_alpha() -exit_img_hov = pygame.image.load('./img/exit_btn_hover.png').convert_alpha() -# create button instances -start_button = button.Button(397, 390, start_img, 0.8) -start2_button = button.Button(397, 390, start_img_hov, 0.8) -exit_button = button.Button(412, 500, exit_img, 0.8) -exit2_button = button.Button(412, 500, exit_img_hov, 0.8) - -# create a new instance of the Game. -clock = pygame.time.Clock() -is_running = True - -while is_running: - if start_button.draw(window): - import main - if exit_button.draw(window): - pygame.quit() - sys.exit() - MOUSE_POS = pygame.mouse.get_pos() - if 397 <= MOUSE_POS[0] < 622 and 390 <= MOUSE_POS[1] < 490: - start2_button.draw(window) - if 412 <= MOUSE_POS[0] < 607 and 500 <= MOUSE_POS[1] < 600: - exit2_button.draw(window) - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - sys.exit() - pygame.display.update() - clock.tick(60) diff --git a/README.md b/README.md index 5c1660a..4e86b34 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ -## Basket Go ! +# BASKET GO! -Basket Go ! est un jeu tournant sous pygame dont le but est de mettre la balle dans le panier afin de gagner des points. +Basket Go ! est un jeu tournant sous la bibliothèque **Pygame**, comme son nom l'indique l'univers de ce jeu vidéo est tourner vers le basketball, comportant **trois catégories :** +(Solo / 1vs1 'tour par tour' / Niveaux) Dont le but est de s'amusez en se challengeant à **marquez le plus de panier possible** dans un **temps imparti (45sec)**, le jeu étant composée d'une **boutique** et de sa propre **monnaie (Go ticket)** vous la gagnerait à chaque fin de partie selon le score obtenue. +A vous de Jouez ! +## Aspect Graphique +[Charte Graphique](https://user-images.githubusercontent.com/97946104/206729155-c77702b8-d29a-4dad-ace3-678474b561ec.png) +... +... + +## Hierarchie code +```mermaid +graph LR +A[main.py] --> B((button)) +A --> C((game)) +``` diff --git a/components/button.py b/components/button.py index 8c40f0f..3c765ed 100644 --- a/components/button.py +++ b/components/button.py @@ -1,30 +1,34 @@ -import pygame - -#button class -class Button(): - def __init__(self, x, y, image, scale): - width = image.get_width() - height = image.get_height() - self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale))) - self.rect = self.image.get_rect() - self.rect.topleft = (x, y) - self.clicked = False - - def draw(self, surface): - action = False - #get mouse position - pos = pygame.mouse.get_pos() - - #check mouseover and clicked conditions - if self.rect.collidepoint(pos): - 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(self.image, (self.rect.x, self.rect.y)) - - return action \ No newline at end of file +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 0a9474c..0e8d39f 100644 --- a/events/ball_release_event_listener.py +++ b/events/ball_release_event_listener.py @@ -1,77 +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 +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 a9366f7..3d4b8f9 100644 --- a/events/drag_event_listener.py +++ b/events/drag_event_listener.py @@ -1,37 +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) +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 2f20cbe..d21bdca 100644 --- a/game.py +++ b/game.py @@ -23,17 +23,25 @@ def __init__(self, screen: pygame.Surface, img_location: str, img_name: str, sou self.__window = Window() # game threads. self.__threads = [] + self.clock = pygame.time.Clock() + self.fps = 150 # get the actual basket ball field. - field = pygame.image.load( - img_location + "terrain_basket_sans_public.png") + field = pygame.image.load(img_location + "terrain_basket_public.png") field = pygame.transform.scale(field, (1024, 640)) + field2 = pygame.image.load("img/terrain_basket_public_2.png") + field2 = pygame.transform.scale(field2, (1024, 640)) + self.field = field + self.field2 = field2 + #get the cursor + cursor_init = pygame.image.load("img/cursor.png").convert_alpha() + self.cursor = cursor_init # 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") # register the field without public. - self.get_window().register_element("field", Element(field, 0, 0)) + 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. @@ -68,13 +76,21 @@ def register_thread(self, thread) -> None: Register the given thread into a list. """ self.__threads.append(thread) - + def display_fps(self): + """Show the program's FPS in the window handle.""" + caption = "{} - FPS: {:.2f}".format("ʙᴀsᴋᴇᴛ ɢᴏ !", self.clock.get_fps()) + pygame.display.set_caption(caption) def setup(self): """ Setup the ressources (background image, audio, etc.) and listen to all the events built in the game. """ while True: + x,y = pygame.mouse.get_pos() + x -= self.cursor.get_width()/2 + y -= self.cursor.get_height()/2 + self.clock.tick(self.fps) + self.display_fps() # loop through each elements. for element in self.__window.get_elements(): # retrive the object. @@ -94,6 +110,8 @@ def setup(self): if event_pair[0] == event.type: # run the event. event_pair[1].run(event, self) + #cursor init + self.__screen.blit(self.cursor,(x,y)) pygame.display.update() def listen(self, event_type: int, event_listener: EventListener) -> None: @@ -113,3 +131,4 @@ def get_screen(self): Return game's screen. """ return self.__screen + \ No newline at end of file diff --git a/img/cursor.png b/img/cursor.png new file mode 100644 index 0000000..4d53cd9 Binary files /dev/null and b/img/cursor.png differ diff --git a/img/exit_btn.png b/img/exit_btn.png index 1b68175..2dee998 100644 Binary files a/img/exit_btn.png and b/img/exit_btn.png differ diff --git a/img/exit_btn_hover.png b/img/exit_btn_hover.png index dfaf568..0ddd3ed 100644 Binary files a/img/exit_btn_hover.png and b/img/exit_btn_hover.png differ diff --git a/img/start_btn.png b/img/start_btn.png index 3b2e262..278ce68 100644 Binary files a/img/start_btn.png and b/img/start_btn.png differ diff --git a/img/start_btn_hover.png b/img/start_btn_hover.png index 7e644c1..4612af7 100644 Binary files a/img/start_btn_hover.png and b/img/start_btn_hover.png differ diff --git a/img/terrain_basket_public.png b/img/terrain_basket_public.png new file mode 100644 index 0000000..cf877e1 Binary files /dev/null and b/img/terrain_basket_public.png differ diff --git a/img/terrain_basket_public_2.png b/img/terrain_basket_public_2.png new file mode 100644 index 0000000..6889140 Binary files /dev/null and b/img/terrain_basket_public_2.png differ diff --git a/img/terrain_basket_sans_public.png b/img/terrain_basket_sans_public.png deleted file mode 100644 index 3381c50..0000000 Binary files a/img/terrain_basket_sans_public.png and /dev/null differ diff --git a/main.py b/main.py index 0f9129f..7fd9d66 100644 --- a/main.py +++ b/main.py @@ -1,22 +1,90 @@ import pygame import random +import components.button as button +import sys from game import Game # init pygame. pygame.init() # load game icon. -icon = pygame.image.load("img/Logo.png") +icon = pygame.image.load("./img/Logo.png") # set game icon. pygame.display.set_icon(icon) # set game name. pygame.display.set_caption("ʙᴀsᴋᴇᴛ ɢᴏ !") # define window's size. -screen = pygame.display.set_mode((1024,640)) -image = ["flame","mountains","pink","basket-ball","smile","military"] -i = random.randint(0,5) -# create a new instance of the Game. -game = Game(screen, "img/",image[i], None) -# register dummy player. -game.register_player("Yanis") -# setup the game. -game.setup() \ No newline at end of file +window = pygame.display.set_mode((1024,640)) +fond = pygame.image.load('./img/bg.png') +pygame.mouse.set_pos((fond.get_width()/2,fond.get_height()/2)) + +#load button images +start_img = pygame.image.load('./img/start_btn.png') +exit_img = pygame.image.load('./img/exit_btn.png') +start_img_hov = pygame.image.load('./img/start_btn_hover.png') +exit_img_hov = pygame.image.load('./img/exit_btn_hover.png') +#create button instances +start_button = button.Button(397, 390, start_img, start_img_hov, 1) +exit_button = button.Button(412, 500, exit_img, exit_img_hov, 1) + +clock = pygame.time.Clock() +is_running = True +press = False +press2 = False + +#set cursor +cursor = "img/cursor.png" +cursor_init = pygame.image.load(cursor).convert_alpha() +pygame.mouse.set_visible(False) + +while is_running: + MOUSE_POS = pygame.mouse.get_pos() + x,y = pygame.mouse.get_pos() + x -= cursor_init.get_width()/2 + y -= cursor_init.get_height()/2 + #blit background + window.blit(fond,(0,0)) + #if start_button was clicked or selected and press enter + if start_button.draw_and_clicked(window) or press == True : + image = ["flame","mountains","pink","basket-ball","smile","military"] + i = random.randint(0,5) + # create a new instance of the Game. + game = Game(window, "img/",image[i], None) + # register dummy player. + game.register_player("Yanis") + # setup the game. + game.setup() + #if exit_button was clicked or selected and press enter + if exit_button.draw_and_clicked(window) or press2 == True: + pygame.quit() + sys.exit() + window.blit(cursor_init,(x,y)) + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_RETURN: + if start_button.rect.collidepoint(MOUSE_POS) : + press = True + else : + press = False + if exit_button.rect.collidepoint(MOUSE_POS) : + press2 = True + else : + press2 = False + #if K_UP is pressed moov cursor on button start + if event.scancode == 82 : + if MOUSE_POS != (513,438) : + pygame.mouse.set_pos((513,438)) + else : + pygame.mouse.set_pos((513,547)) + #if K_DOWN is pressed moov cursor on button exit + if event.scancode == 81 : + if MOUSE_POS != (513,547) : + pygame.mouse.set_pos((513,547)) + else : + pygame.mouse.set_pos((513,438)) + + pygame.display.update() + clock.tick(60) + \ No newline at end of file