diff --git a/space_dodge/classes/button.py b/space_dodge/classes/button.py index f830057..1555312 100644 --- a/space_dodge/classes/button.py +++ b/space_dodge/classes/button.py @@ -1,15 +1,39 @@ import pygame as p +from space_dodge.file_handling.constants_and_file_loading import WINDOW + class Button: def __init__(self, image, x, y): - self.image = image + self._image = image self.x = x self.y = y + self.pos = (x, y) self.width = image.get_width() self.height = image.get_height() + self.image_hover = p.transform.scale(self._image, (self.width + 3, self.height + 3)) self.rect = p.Rect(x, y, self.width, self.height) + @property + def image(self): + mouse_pos = p.mouse.get_pos() + if self.rect.collidepoint(mouse_pos): + return self.image_hover + else: + return self._image + + def update_rect(self, x): self.rect = p.Rect(x, self.y, self.width, self.height) + self.x = x return self.rect + + def clicked(self): + mouse_pos = p.mouse.get_pos() + if self.rect.collidepoint(mouse_pos) and p.mouse.get_pressed()[0]: + return True + else: + return False + + def draw(self): + WINDOW.blit(self.image, self.pos) diff --git a/space_dodge/classes/player.py b/space_dodge/classes/player.py index 2b5fb75..cb8afe0 100644 --- a/space_dodge/classes/player.py +++ b/space_dodge/classes/player.py @@ -1,21 +1,36 @@ from space_dodge.file_handling.constants_and_file_loading import HEIGHT, PLAYER_HEIGHT, PLAYER_WIDTH, PLAYER_VELOCITY, \ - playerL, playerR + playerL, playerR, WIDTH class Player: def __init__(self): - self.x = 0 + self._x = 0 self.y = HEIGHT - PLAYER_HEIGHT self.width = PLAYER_WIDTH self.height = PLAYER_HEIGHT self.velocity = PLAYER_VELOCITY self.left_image = playerL self.right_image = playerR - self.image = playerL + self._image = playerL + self.direction = 0 # The direction the player is facing( written in binary ) 0 = left, 1 = right - def direction(self, direction): - if direction == 0: - self.image = self.left_image + @property + def image(self): + if self.direction == 0: + self._image = self.left_image else: - self.image = self.right_image - return self.image + self._image = self.right_image + return self._image + + @property + def x(self): + return self._x + + @x.setter + def x(self, value): + if value - self.velocity >= 0 and value + self.velocity + self.width <= WIDTH: + self._x = value + + @property + def pos(self): + return self._x, self.y diff --git a/space_dodge/classes/slider.py b/space_dodge/classes/slider.py deleted file mode 100644 index 9d9b617..0000000 --- a/space_dodge/classes/slider.py +++ /dev/null @@ -1,41 +0,0 @@ -import pygame - - -class Slider: - def __init__(self, pos: list, size: tuple, initial_val: float, min: int, max: int, title): - self.pos = pos - self.size = size - - self.slider_left_pos = self.pos[0] - (size[0] // 2) - self.slider_right_pos = self.pos[0] + (size[0] // 2) - self.slider_top_pos = self.pos[1] - (size[1] // 2) - - self.min = min - self.max = max - - # Calculate the initial position of the button based on the initial value percentage - self.initial_val = initial_val - self.button_x = int((self.slider_left_pos + self.initial_val * 100)) - - self.container_rect = pygame.Rect(self.slider_left_pos, self.slider_top_pos, size[0], size[1]) - self.button_rect = pygame.Rect(self.button_x - 5, self.slider_top_pos, 10, size[1]) - - self.title = title - self.pos[0] = self.title.get_width() + self.pos[0] - - def move_slider(self, mouse_pos): - self.button_rect.x = mouse_pos[0] - 5 - - def render(self, window): - pygame.draw.rect(window, (255, 255, 255), self.container_rect) - pygame.draw.rect(window, (0, 0, 0), self.button_rect) - window.blit(self.title, - (self.slider_left_pos - self.title.get_width() - 10, self.pos[1] - self.title.get_height() / 2)) - window.blit(pygame.font.SysFont("comicsans", 20).render(str(int(self.get_value())), 1, (255, 255, 255)), - (self.slider_right_pos + 10, self.pos[1] - 10)) - - def get_value(self): - val_range = self.slider_right_pos - self.slider_left_pos - 1 - button_val = self.button_rect.x - self.slider_left_pos - - return (button_val / val_range) * (self.max - self.min) + self.min + 5 diff --git a/space_dodge/drawing/draw.py b/space_dodge/drawing/draw.py index 10500b3..492b66d 100644 --- a/space_dodge/drawing/draw.py +++ b/space_dodge/drawing/draw.py @@ -3,17 +3,15 @@ from space_dodge.classes.animation import Animation from space_dodge.file_handling.constants_and_file_loading import ( WINDOW, WIDTH, HEIGHT, FONT, BULLET_HEIGHT, - threeLives, twoLives, oneLife, background, bullet_texture, bullet_explosion_frames, - pauseButtonImage, muteImage, unmuteImage -) + threeLives, twoLives, oneLife, game_background, bullet_texture, bullet_explosion_frames) # Create a mask for the bullet bullet_mask = pygame.mask.from_surface(bullet_texture) -def draw(player, bullets, direction, highscore, highscoreBreak, mute, lives, timeText, scoreText, explosions, dt, - settingsButton): - WINDOW.blit(background, (0, 0)) +def draw(player, bullets, highscore, highscoreBreak, mute, lives, timeText, scoreText, explosions, dt, + muteSymbol, unmuteSymbol, settingsButton, pauseButton): + WINDOW.blit(game_background, (0, 0)) # Draw settings icon WINDOW.blit(settingsButton.image, (settingsButton.x, settingsButton.y)) @@ -36,19 +34,20 @@ def draw(player, bullets, direction, highscore, highscoreBreak, mute, lives, tim WINDOW.blit(timeText, (10, 10)) WINDOW.blit(scoreText, (WIDTH - 270, 10)) WINDOW.blit(FONT.render("Your high score", 1, "white"), (250, 10)) - WINDOW.blit(pauseButtonImage, (scoreText.get_width() + 745, 19)) - WINDOW.blit(muteImage if mute else unmuteImage, (timeText.get_width() + 10, 10)) + WINDOW.blit(pauseButton.image, (scoreText.get_width() + 745, 19)) + WINDOW.blit(muteSymbol.image if mute else unmuteSymbol.image, (timeText.get_width() + 10, 10)) highScoreText = FONT.render(f" is {highscore}" if highscoreBreak else f" was {highscore}", 1, "white") WINDOW.blit(highScoreText, (500, 10)) # Draw player - WINDOW.blit(player.direction(direction), (player.x, player.y)) + WINDOW.blit(player.image, player.pos) # Draw lives - lives_images = {3: threeLives, 2: twoLives, 1: oneLife} + lives_images = {3: threeLives, + 2: twoLives, 1: oneLife} if lives in lives_images: WINDOW.blit(lives_images[lives], (780, 50)) else: - WINDOW.blit(background, (0, 0)) + WINDOW.blit(game_background, (0, 0)) pygame.display.update() diff --git a/space_dodge/drawing/title_screen/draw_title_screen.py b/space_dodge/drawing/title_screen/draw_title_screen.py index deafe37..96de274 100644 --- a/space_dodge/drawing/title_screen/draw_title_screen.py +++ b/space_dodge/drawing/title_screen/draw_title_screen.py @@ -1,9 +1,11 @@ import pygame +from space_dodge.classes.button import Button from space_dodge.drawing.tutorial_and_information.keybindings import keybindings_screen +from space_dodge.drawing.tutorial_and_information.settings import settings_menu from space_dodge.drawing.tutorial_and_information.welcome import welcome_screen from space_dodge.file_handling.constants_and_file_loading import ( - WINDOW, WIDTH, HEIGHT, start_button_image, muteImage, unmuteImage, title_screen_image + WINDOW, start_button_image, muteImage, unmuteImage, title_screen_background, settingsIcon, WIDTH, HEIGHT ) from space_dodge.file_handling.utility import ref @@ -11,11 +13,6 @@ pygame.init() pygame.mixer.init() -# Define Rect objects -start_button_rect = start_button_image.get_rect(center=(WIDTH / 2, HEIGHT / 2)) -muteSymbol_rect = muteImage.get_rect(x=50, y=200, width=80, height=60) -unmuteSymbol_rect = unmuteImage.get_rect(x=50, y=200, width=80, height=60) - # Draw the title screen def draw_title(): @@ -26,22 +23,34 @@ def draw_title(): mute = False start = False + # Define Button objects + muteSymbol = Button(muteImage, 50, 200) + unmuteSymbol = Button(unmuteImage, 50, 200) + startButton = Button(start_button_image, 350, 300) + settingsButton = Button(settingsIcon, WIDTH - settingsIcon.get_width() - 10, + HEIGHT - settingsIcon.get_height()) + while not start: - WINDOW.blit(title_screen_image, (0, 0)) - WINDOW.blit(start_button_image, start_button_rect.topleft) - WINDOW.blit(muteImage if mute else unmuteImage, (50, 200)) + WINDOW.blit(title_screen_background, (0, 0)) + WINDOW.blit(startButton.image, startButton.pos) + if mute: + WINDOW.blit(muteSymbol.image, muteSymbol.pos) + else: + WINDOW.blit(unmuteSymbol.image, unmuteSymbol.pos) + WINDOW.blit(settingsButton.image, settingsButton.pos) for event in pygame.event.get(): if event.type == pygame.QUIT: return False, 0.0 elif event.type == pygame.MOUSEBUTTONDOWN: - mouse_x, mouse_y = pygame.mouse.get_pos() - if start_button_rect.collidepoint(mouse_x, mouse_y): + if startButton.clicked(): start = True pygame.mixer.music.stop() - elif muteSymbol_rect.collidepoint(mouse_x, mouse_y) or unmuteSymbol_rect.collidepoint(mouse_x, mouse_y): + elif muteSymbol.clicked() or unmuteSymbol.clicked(): mute = not mute pygame.mixer.music.unpause() if not mute else pygame.mixer.music.pause() + elif settingsButton.clicked(): + settings_menu(mute, music_path="sounds/background_music/title_screen/title_screen_music.mp3") pygame.display.update() diff --git a/space_dodge/drawing/tutorial_and_information/keybindings.py b/space_dodge/drawing/tutorial_and_information/keybindings.py index 0aae740..5dc09a6 100644 --- a/space_dodge/drawing/tutorial_and_information/keybindings.py +++ b/space_dodge/drawing/tutorial_and_information/keybindings.py @@ -1,10 +1,9 @@ import time import pygame -from pygame.mixer_music import pause # Importing the crucial variables from the constants file -from space_dodge.file_handling.constants_and_file_loading import WINDOW, WIDTH, HEIGHT, welcome_screen_image, FONT, \ +from space_dodge.file_handling.constants_and_file_loading import WINDOW, WIDTH, HEIGHT, welcome_screen_background, FONT, \ FONT_SMALL keybindText1 = FONT.render("Press M to mute/unmute or just click the symbol.", 1, "orange") @@ -15,7 +14,7 @@ def keybindings_screen(pausedTimes): - WINDOW.blit(welcome_screen_image, (0, 0)) + WINDOW.blit(welcome_screen_background, (0, 0)) keybindText1Place = WIDTH / 2 - keybindText1.get_width() / 2, 300 WINDOW.blit(keybindText1, keybindText1Place) WINDOW.blit(keybindText2, (WIDTH / 2 - keybindText2.get_width() / 2, diff --git a/space_dodge/drawing/tutorial_and_information/settings.py b/space_dodge/drawing/tutorial_and_information/settings.py index 7d94678..5992c05 100644 --- a/space_dodge/drawing/tutorial_and_information/settings.py +++ b/space_dodge/drawing/tutorial_and_information/settings.py @@ -16,7 +16,7 @@ @pause_time -def settings_menu(mute): +def settings_menu(mute, music_path=None): pygame.mixer.music.load(ref("sounds/background_music/pause_screen/pause_music.mp3")) pygame.mixer.music.play(-1) slider = Slider(WINDOW, 350, 400, 100, 30, min=0, max=100, initial=pygame.mixer.music.get_volume() * 100) @@ -45,7 +45,7 @@ def settings_menu(mute): elif keys[pygame.K_ESCAPE]: pygame.mixer.music.stop() pygame.mixer.music.unload() - pygame.mixer.music.load(ref("sounds/background_music/background_music.mp3")) + pygame.mixer.music.load(ref("sounds/background_music/background_music.mp3" if music_path is None else music_path)) pygame.mixer.music.play(-1) return True diff --git a/space_dodge/drawing/tutorial_and_information/welcome.py b/space_dodge/drawing/tutorial_and_information/welcome.py index dbb03bb..d750aeb 100644 --- a/space_dodge/drawing/tutorial_and_information/welcome.py +++ b/space_dodge/drawing/tutorial_and_information/welcome.py @@ -1,12 +1,12 @@ import pygame # Importing the crucial variables from the constants file -from space_dodge.file_handling.constants_and_file_loading import WINDOW, WIDTH, HEIGHT, welcome_screen_image, FONT, \ +from space_dodge.file_handling.constants_and_file_loading import WINDOW, WIDTH, HEIGHT, welcome_screen_background, FONT, \ FONT_SMALL def welcome_screen(): - WINDOW.blit(welcome_screen_image, (0, 0)) + WINDOW.blit(welcome_screen_background, (0, 0)) welcomeText1 = FONT.render("Welcome to Space Dodge!", 1, "orange") welcomeText2 = FONT.render("Use A & D keys to move left & right!", 1, "orange") welcomeText3 = FONT.render("Try not to hit the bullets!", 1, "orange") diff --git a/space_dodge/file_handling/constants_and_file_loading.py b/space_dodge/file_handling/constants_and_file_loading.py index 89060fa..7bf87e0 100644 --- a/space_dodge/file_handling/constants_and_file_loading.py +++ b/space_dodge/file_handling/constants_and_file_loading.py @@ -143,9 +143,9 @@ def update_loading_bar(assets_num=1): draw_except("Lives") try: - background = t.scale(i.load(ref("assets/space_background.jpg")), (WIDTH, HEIGHT)) - title_screen_image = t.scale(i.load(ref("assets/title_screen.jpg")), (WIDTH, HEIGHT)) - welcome_screen_image = t.scale(i.load(ref("assets/welcome_screen.png")), (WIDTH, HEIGHT)) + game_background = t.scale(i.load(ref("assets/space_background.jpg")), (WIDTH, HEIGHT)) + title_screen_background = t.scale(i.load(ref("assets/title_screen.jpg")), (WIDTH, HEIGHT)) + welcome_screen_background = t.scale(i.load(ref("assets/welcome_screen.png")), (WIDTH, HEIGHT)) pause_background = t.scale(i.load(ref("assets/pause_background.png")), (WIDTH, HEIGHT)) update_loading_bar(4) except FileNotFoundError: diff --git a/space_dodge/main.py b/space_dodge/main.py index 29f4286..fc7f154 100644 --- a/space_dodge/main.py +++ b/space_dodge/main.py @@ -4,11 +4,12 @@ import pygame # Import all constant variables -from file_handling.constants_and_file_loading import (FONT, - FONT_MEDIUM, FONT_BIG, WIDTH, HEIGHT, WINDOW, settingsIcon) +from space_dodge.file_handling.constants_and_file_loading import (FONT, + FONT_MEDIUM, FONT_BIG, WIDTH, HEIGHT, WINDOW, + settingsIcon) # Import all the files( images, sounds, etc. ) -from file_handling.constants_and_file_loading import (muteImage, unmuteImage, pauseButtonImage, background, - sadSound, GameOverSound, highscoreSound) +from space_dodge.file_handling.constants_and_file_loading import (muteImage, unmuteImage, pauseButtonImage, game_background, + sadSound, GameOverSound, highscoreSound) # Import the classes' modules from space_dodge.classes.bullet import Bullet from space_dodge.classes.button import Button @@ -28,13 +29,11 @@ def main(): - running = True # Keeps the while loop running highscoreBreak = False # Tells if the current score is bigger than the highscore mute = False # Is the game muted or not lives = 3 # Self-explanatory highscoreSoundPlayed = False # Has the highscore sound been played? pausedTimes = [] # The total pause time - highscore_file_not_found = False # Is the highscore file not found? last_time = time.time() explosions = [] # The list of explosions player = Player() # Create the player object @@ -53,12 +52,8 @@ def main(): bullets = [] # The list of bullets - direction = 0 # The direction the player is facing( written in binary ) 0 = left, 1 = right - # Load the high score from file highscore = load_highscore(ref("file_handling/highscore.pickle")) - if highscore == 0: - highscore_file_not_found = True # Draw the title screen running, startTime = draw_title() @@ -100,7 +95,7 @@ def main(): bulletCount += clock.tick(60) # The mask for the player - player_mask = pygame.mask.from_surface(player.direction(direction)) + player_mask = pygame.mask.from_surface(player.image) # Event handling for event in pygame.event.get(): @@ -116,36 +111,33 @@ def main(): if keys[pygame.K_a] or keys[pygame.K_d]: pass break - if keys[pygame.K_m]: + if keys[pygame.K_m] or muteButton.clicked() or unmuteButton.clicked(): mute = not mute if keys[pygame.K_k] or keys[pygame.K_i]: running, pausedTime = keybindings_screen(pausedTimes) pausedTimes.append(pausedTime) - if ((muteButton.rect.collidepoint(pygame.mouse.get_pos()) or unmuteButton.rect.collidepoint( - pygame.mouse.get_pos())) - and pygame.mouse.get_pressed()[0]): - mute = not mute - if (pauseButton.rect.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]) or ( + if (pauseButton.clicked() or keys[pygame.K_p]): running, pausedTime = pause_menu(score, elapsedTime, highscore, highscoreBreak, mute) pausedTimes.append(pausedTime) - if settingsButton.rect.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]: + if settingsButton.clicked(): running, pausedTime = settings_menu(mute) pausedTimes.append(pausedTime) score += 1 - if score > highscore: - highscore = score - highscoreBreak = True - if not highscoreSoundPlayed and not highscore_file_not_found: - highscoreBrokenText = FONT.render(f"You broke your previous highscore of {score - 1}!", 1, - "green") - WINDOW.blit(highscoreBrokenText, ( - WIDTH / 2 - highscoreBrokenText.get_width() / 2, HEIGHT / 2 - highscoreBrokenText.get_height() / 2)) - pygame.display.update() - pygame.mixer.Sound.play(highscoreSound) - highscoreSoundPlayed = True - pygame.time.delay(1000) + if highscore != 1 and not highscore != score: + if score > highscore: + highscore = score + highscoreBreak = True + if not highscoreSoundPlayed: + highscoreBrokenText = FONT.render(f"You broke your previous highscore of {score - 1}!", 1, + "green") + WINDOW.blit(highscoreBrokenText, ( + WIDTH / 2 - highscoreBrokenText.get_width() / 2, HEIGHT / 2 - highscoreBrokenText.get_height() / 2)) + pygame.display.update() + pygame.mixer.Sound.play(highscoreSound) + highscoreSoundPlayed = True + pygame.time.delay(1000) if bulletCount > bulletAddIncrement: for _ in range(3): @@ -155,11 +147,11 @@ def main(): bulletAddIncrement = max(400, bulletAddIncrement - 50) bulletCount = 0 - if keys[pygame.K_a] and player.x - player.velocity >= 0: - direction = 0 + if keys[pygame.K_a]: + player.direction = 0 player.x -= player.velocity - if keys[pygame.K_d] and player.x + player.velocity + player.width <= WIDTH: - direction = 1 + if keys[pygame.K_d]: + player.direction = 1 player.x += player.velocity for bullet in bullets[:]: @@ -173,18 +165,18 @@ def main(): bullets.clear() lives -= 1 if lives > 0: - WINDOW.blit(background, (0, 0)) + WINDOW.blit(game_background, (0, 0)) WINDOW.blit(lostLivesText if lives > 1 else lostLifeText, (50, HEIGHT / 2 - lostLivesText.get_height())) pygame.display.update() pygame.time.delay(1000) else: - WINDOW.blit(background, (0, 0)) + WINDOW.blit(game_background, (0, 0)) pygame.display.update() if highscore >= score: save_object(highscore) pygame.mixer.music.fadeout(1000) - WINDOW.blit(background, (0, 0)) + WINDOW.blit(game_background, (0, 0)) loseText = FONT_BIG.render("GAME OVER!", 1, "red") highscoreText = FONT_MEDIUM.render(f"Your score was {score}.", 1, "white") timeText = FONT_MEDIUM.render(f"You played for {round(elapsedTime)} seconds.", 1, "white") @@ -207,8 +199,8 @@ def main(): save_object(highscore) if score >= highscore else None continue - draw(player, bullets, direction, highscore, highscoreBreak, mute, lives, timeText, scoreText, explosions, dt, - settingsButton) + draw(player, bullets, highscore, highscoreBreak, mute, lives, timeText, scoreText, explosions, dt, + muteButton, unmuteButton, settingsButton, pauseButton) pygame.quit()