diff --git a/Street Fighter/README.md b/Street Fighter/README.md new file mode 100644 index 0000000..e2ed81c --- /dev/null +++ b/Street Fighter/README.md @@ -0,0 +1,146 @@ +# Shadow Fight + +**Shadow Fight** is an engaging two-player fighting game built with Python and Pygame. This project features exciting gameplay mechanics, unique characters, and dynamic animations, making it a perfect choice for retro game enthusiasts and developers interested in Python-based game development. + + + +## Features +- **Two Distinct Fighters**: + - **Warrior**: A melee combatant with powerful sword attacks. + - **Wizard**: A magic wielder with spell-based attacks. +- **Gameplay Mechanics**: + - Health bars for each fighter. + - Smooth animations for idle, run, jump, attack, hit, and death actions. + - Scoring system to track player victories. +- **Dynamic Background**: + - Blurred background effects during the main menu for a cinematic feel. +- **Sound Effects and Music**: + - Immersive soundtracks and attack effects. +- **Responsive UI**: + - Main menu with start, score, and exit options. + - Victory screen for the winning fighter. +- **Custom Controls** for two players. + + + +## 📋 Table of Contents +- [Features](#features) +- [Requirements](#requirements) +- [Installation](#installation) +- [Gameplay Instructions](#gameplay-instructions) +- [Screenshots](#screenshots) +- [Demo](#demo) +- [License](#license) +- [Credits](#credits) +- [Contributing](#contributing) +- [Contact](#contact) + + + +## Requirements +- Python 3.7 or higher +- Required Python libraries: + - `pygame` + - `numpy` + - `opencv-python` + + + +## Installation + +Follow these steps to install and run the game: + +1. **Clone the Repository**: + ```bash + git clone https://github.com/AadityaPanda/Shadow-Fight.git + cd Shadow-Fight + ``` + +2. **Install Dependencies**: + ```bash + pip install -r requirements.txt + ``` + +3. **Run the Game**: + ```bash + python src/main.py + ``` + + + +## Gameplay Instructions + +### Player Controls: +- **Player 1**: + - Move: `A` (Left), `D` (Right) + - Jump: `W` + - Attack: `R` (Attack 1), `T` (Attack 2) + +- **Player 2**: + - Move: Left Arrow (`←`), Right Arrow (`→`) + - Jump: Up Arrow (`↑`) + - Attack: `M` (Attack 1), `N` (Attack 2) + +**Objective**: Reduce your opponent's health to zero to win the round. Victory is celebrated with a dynamic win screen! + + + +## Screenshots +![Screenshot (2)](https://github.com/user-attachments/assets/82b289ab-5da7-4331-a1b4-dd264ee77707) +![Screenshot (3)](https://github.com/user-attachments/assets/c72256a3-c637-4b2f-8605-57a7c39093de) +![Screenshot (4)](https://github.com/user-attachments/assets/1e747407-7887-4bc3-87c1-751b6d27eb5c) + + + +## Demo + + +https://github.com/user-attachments/assets/fe990e99-b59e-4ef3-9d2a-80ba7a7e7601 + + + + + +## License + +This project is licensed under the [MIT License](LICENSE). Feel free to use, modify, and distribute it in your projects. + + + +## Credits + +- **Developer**: Aaditya Panda +- **Assets**: + - Background music and sound effects: [Free Music Archive](https://freemusicarchive.org/) + - Fonts: [Turok Font](https://www.fontspace.com/turok-font) + - Sprites: Custom-designed and modified from open-source assets. + + + +## Contributing + +Contributions are welcome! Here's how you can help: +1. Fork the repository. +2. Create a new branch: + ```bash + git checkout -b feature/YourFeatureName + ``` +3. Commit your changes: + ```bash + git commit -m "Add YourFeatureName" + ``` +4. Push to the branch: + ```bash + git push origin feature/YourFeatureName + ``` +5. Open a pull request. + +Check the [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines. + + + +## Contact + +- **Developer**: Aaditya Panda +- **Email**: [aadityapanda23@gmail.com](mailto:aadityapanda23@gmail.com) +- **GitHub**: [AadityaPanda](https://github.com/AadityaPanda) diff --git a/Street Fighter/assets/audio/magic.wav b/Street Fighter/assets/audio/magic.wav new file mode 100644 index 0000000..1e55ba4 Binary files /dev/null and b/Street Fighter/assets/audio/magic.wav differ diff --git a/Street Fighter/assets/audio/music.mp3 b/Street Fighter/assets/audio/music.mp3 new file mode 100644 index 0000000..7b90d41 Binary files /dev/null and b/Street Fighter/assets/audio/music.mp3 differ diff --git a/Street Fighter/assets/audio/sword.wav b/Street Fighter/assets/audio/sword.wav new file mode 100644 index 0000000..960457f Binary files /dev/null and b/Street Fighter/assets/audio/sword.wav differ diff --git a/Street Fighter/assets/fonts/turok.ttf b/Street Fighter/assets/fonts/turok.ttf new file mode 100644 index 0000000..374aa56 Binary files /dev/null and b/Street Fighter/assets/fonts/turok.ttf differ diff --git a/Street Fighter/assets/icon/sficon.ico b/Street Fighter/assets/icon/sficon.ico new file mode 100644 index 0000000..462d779 Binary files /dev/null and b/Street Fighter/assets/icon/sficon.ico differ diff --git a/Street Fighter/assets/images/bg.jpg b/Street Fighter/assets/images/bg.jpg new file mode 100644 index 0000000..26ea8d2 Binary files /dev/null and b/Street Fighter/assets/images/bg.jpg differ diff --git a/Street Fighter/assets/images/bg1.jpg b/Street Fighter/assets/images/bg1.jpg new file mode 100644 index 0000000..dd6726d Binary files /dev/null and b/Street Fighter/assets/images/bg1.jpg differ diff --git a/Street Fighter/assets/images/bg2.jpg b/Street Fighter/assets/images/bg2.jpg new file mode 100644 index 0000000..bcf0238 Binary files /dev/null and b/Street Fighter/assets/images/bg2.jpg differ diff --git a/Street Fighter/assets/images/victory.png b/Street Fighter/assets/images/victory.png new file mode 100644 index 0000000..e0c0635 Binary files /dev/null and b/Street Fighter/assets/images/victory.png differ diff --git a/Street Fighter/assets/images/warrior.png b/Street Fighter/assets/images/warrior.png new file mode 100644 index 0000000..7861832 Binary files /dev/null and b/Street Fighter/assets/images/warrior.png differ diff --git a/Street Fighter/assets/images/wizard.png b/Street Fighter/assets/images/wizard.png new file mode 100644 index 0000000..02af53b Binary files /dev/null and b/Street Fighter/assets/images/wizard.png differ diff --git a/Street Fighter/src/fighter.py b/Street Fighter/src/fighter.py new file mode 100644 index 0000000..1583599 --- /dev/null +++ b/Street Fighter/src/fighter.py @@ -0,0 +1,191 @@ +import pygame + +class Fighter: + def __init__(self, player, x, y, flip, data, sprite_sheet, animation_steps, sound): + self.player = player + self.size = data[0] + self.image_scale = data[1] + self.offset = data[2] + self.flip = flip + self.animation_list = self.load_images(sprite_sheet, animation_steps) + self.action = 0 # 0:idle #1:run #2:jump #3:attack1 #4: attack2 #5:hit #6:death + self.frame_index = 0 + self.image = self.animation_list[self.action][self.frame_index] + self.update_time = pygame.time.get_ticks() + self.rect = pygame.Rect((x, y, 80, 180)) + self.vel_y = 0 + self.running = False + self.jump = False + self.attacking = False + self.attack_type = 0 + self.attack_cooldown = 0 + self.attack_sound = sound + self.hit = False + self.health = 100 + self.alive = True + + def load_images(self, sprite_sheet, animation_steps): + # extract images from spritesheet + animation_list = [] + for y, animation in enumerate(animation_steps): + temp_img_list = [] + for x in range(animation): + temp_img = sprite_sheet.subsurface(x * self.size, y * self.size, self.size, self.size) + temp_img_list.append( + pygame.transform.scale(temp_img, (self.size * self.image_scale, self.size * self.image_scale))) + animation_list.append(temp_img_list) + return animation_list + + def move(self, screen_width, screen_height, target, round_over): + SPEED = 10 + GRAVITY = 2 + dx = 0 + dy = 0 + self.running = False + self.attack_type = 0 + + # get keypresses + key = pygame.key.get_pressed() + + # can only perform other actions if not currently attacking + if self.attacking == False and self.alive == True and round_over == False: + # check player 1 controls + if self.player == 1: + # movement + if key[pygame.K_a]: + dx = -SPEED + self.running = True + if key[pygame.K_d]: + dx = SPEED + self.running = True + # jump + if key[pygame.K_w] and self.jump == False: + self.vel_y = -30 + self.jump = True + # attack + if key[pygame.K_r] or key[pygame.K_t]: + self.attack(target) + # determine which attack type was used + if key[pygame.K_r]: + self.attack_type = 1 + if key[pygame.K_t]: + self.attack_type = 2 + + # check player 2 controls + if self.player == 2: + # movement + if key[pygame.K_LEFT]: + dx = -SPEED + self.running = True + if key[pygame.K_RIGHT]: + dx = SPEED + self.running = True + # jump + if key[pygame.K_UP] and self.jump == False: + self.vel_y = -30 + self.jump = True + # attack + if key[pygame.K_m] or key[pygame.K_n]: + self.attack(target) + # determine which attack type was used + if key[pygame.K_m]: + self.attack_type = 1 + if key[pygame.K_n]: + self.attack_type = 2 + + # apply gravity + self.vel_y += GRAVITY + dy += self.vel_y + + # ensure player stays on screen + if self.rect.left + dx < 0: + dx = -self.rect.left + if self.rect.right + dx > screen_width: + dx = screen_width - self.rect.right + if self.rect.bottom + dy > screen_height - 110: + self.vel_y = 0 + self.jump = False + dy = screen_height - 110 - self.rect.bottom + + # ensure players face each other + if target.rect.centerx > self.rect.centerx: + self.flip = False + else: + self.flip = True + + # apply attack cooldown + if self.attack_cooldown > 0: + self.attack_cooldown -= 1 + + # update player position + self.rect.x += dx + self.rect.y += dy + + # handle animation updates + def update(self): + # check what action the player is performing + if self.health <= 0: + self.health = 0 + self.alive = False + self.update_action(6) # 6:death + elif self.hit: + self.update_action(5) # 5:hit + elif self.attacking: + if self.attack_type == 1: + self.update_action(3) # 3:attack1 + elif self.attack_type == 2: + self.update_action(4) # 4:attack2 + elif self.jump: + self.update_action(2) # 2:jump + elif self.running: + self.update_action(1) # 1:run + else: + self.update_action(0) # 0:idle + + animation_cooldown = 50 + # update image + self.image = self.animation_list[self.action][self.frame_index] + # check if enough time has passed since the last update + if pygame.time.get_ticks() - self.update_time > animation_cooldown: + self.frame_index += 1 + self.update_time = pygame.time.get_ticks() + # check if the animation has finished + if self.frame_index >= len(self.animation_list[self.action]): + # if the player is dead then end the animation + if not self.alive: + self.frame_index = len(self.animation_list[self.action]) - 1 + else: + self.frame_index = 0 + # check if an attack was executed + if self.action == 3 or self.action == 4: + self.attacking = False + self.attack_cooldown = 20 + # check if damage was taken + if self.action == 5: + self.hit = False + # if the player was in the middle of an attack, then the attack is stopped + self.attacking = False + self.attack_cooldown = 20 + + def attack(self, target): + if self.attack_cooldown == 0: + # execute attack + self.attacking = True + self.attack_sound.play() + attacking_rect = pygame.Rect(self.rect.centerx - (2 * self.rect.width * self.flip), self.rect.y, + 2 * self.rect.width, self.rect.height) + if attacking_rect.colliderect(target.rect): + target.health -= 10 + target.hit = True + + def update_action(self, new_action): + # check if the new action is different to the previous one + if new_action != self.action: + self.action = new_action + # update the animation settings + self.frame_index = 0 + self.update_time = pygame.time.get_ticks() + + def draw(self, surface): + img = pygame.transform.flip(self.image, self.flip, False) + surface.blit(img, (self.rect.x - (self.offset[0] * self.image_scale), self.rect.y - (self.offset[1] * self.image_scale))) diff --git a/Street Fighter/src/main.py b/Street Fighter/src/main.py new file mode 100644 index 0000000..905efbf --- /dev/null +++ b/Street Fighter/src/main.py @@ -0,0 +1,338 @@ +import math +import os +import sys +import cv2 +import numpy as np +import pygame +from pygame import mixer +from fighter import Fighter + +def resource_path(relative_path): + base_path = os.path.abspath(".") # Works whether running as a script or from the bundled executable + return os.path.join(base_path, relative_path) + +mixer.init() +pygame.init() +cached_blurred_bg = None + +# Constants +info = pygame.display.Info() +SCREEN_WIDTH = info.current_w +SCREEN_HEIGHT = info.current_h +FPS = 60 +ROUND_OVER_COOLDOWN = 3000 + +# Colors +RED = (255, 0, 0) +YELLOW = (255, 255, 0) +WHITE = (255, 255, 255) +BLACK = (0, 0, 0) +BLUE = (0, 0, 255) +GREEN = (0, 255, 0) + +# Initialize Game Window +screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.NOFRAME) +pygame.display.set_caption("Street Fighter") +clock = pygame.time.Clock() + +# Load Assets +bg_image = cv2.imread(resource_path("assets/images/bg1.jpg")) +victory_img = pygame.image.load(resource_path("assets/images/victory.png")).convert_alpha() +warrior_victory_img = pygame.image.load(resource_path("assets/images/warrior.png")).convert_alpha() +wizard_victory_img = pygame.image.load(resource_path("assets/images/wizard.png")).convert_alpha() + +# Fonts +menu_font = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), 50) +menu_font_title = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), 100) +count_font = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), 80) +score_font = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), 30) + +# Music and Sounds +pygame.mixer.music.load(resource_path("assets/audio/music.mp3")) +pygame.mixer.music.set_volume(0.5) +pygame.mixer.music.play(-1, 0.0, 5000) +sword_fx = pygame.mixer.Sound(resource_path("assets/audio/sword.wav")) +sword_fx.set_volume(0.5) +magic_fx = pygame.mixer.Sound(resource_path("assets/audio/magic.wav")) +magic_fx.set_volume(0.75) + +# Load Fighter Spritesheets +warrior_sheet = pygame.image.load(resource_path("assets/images/warrior.png")).convert_alpha() +wizard_sheet = pygame.image.load(resource_path("assets/images/wizard.png")).convert_alpha() + +# Define Animation Steps +WARRIOR_ANIMATION_STEPS = [10, 8, 1, 7, 7, 3, 7] +WIZARD_ANIMATION_STEPS = [8, 8, 1, 8, 8, 3, 7] + +# Fighter Data +WARRIOR_SIZE = 162 +WARRIOR_SCALE = 4 +WARRIOR_OFFSET = [72, 46] +WARRIOR_DATA = [WARRIOR_SIZE, WARRIOR_SCALE, WARRIOR_OFFSET] +WIZARD_SIZE = 250 +WIZARD_SCALE = 3 +WIZARD_OFFSET = [112, 97] +WIZARD_DATA = [WIZARD_SIZE, WIZARD_SCALE, WIZARD_OFFSET] + +# Game Variables +score = [0, 0] # Player Scores: [P1, P2] + + +def draw_text(text, font, color, x, y): + img = font.render(text, True, color) + screen.blit(img, (x, y)) + + +def blur_bg(image): + global cached_blurred_bg + if cached_blurred_bg is None: + image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + blurred_image = cv2.GaussianBlur(image_bgr, (15, 15), 0) + cached_blurred_bg = cv2.cvtColor(blurred_image, cv2.COLOR_BGR2RGB) + return cached_blurred_bg + + +def draw_bg(image, is_game_started=False): + if not is_game_started: + blurred_bg = blur_bg(image) + blurred_bg = pygame.surfarray.make_surface(np.transpose(blurred_bg, (1, 0, 2))) + blurred_bg = pygame.transform.scale(blurred_bg, (SCREEN_WIDTH, SCREEN_HEIGHT)) + screen.blit(blurred_bg, (0, 0)) + else: + image = pygame.surfarray.make_surface(np.transpose(image, (1, 0, 2))) + image = pygame.transform.scale(image, (SCREEN_WIDTH, SCREEN_HEIGHT)) + screen.blit(image, (0, 0)) + + +def draw_button(text, font, text_col, button_col, x, y, width, height): + pygame.draw.rect(screen, button_col, (x, y, width, height)) + pygame.draw.rect(screen, WHITE, (x, y, width, height), 2) + text_img = font.render(text, True, text_col) + text_rect = text_img.get_rect(center=(x + width // 2, y + height // 2)) + screen.blit(text_img, text_rect) + return pygame.Rect(x, y, width, height) + + +def victory_screen(winner_img): + start_time = pygame.time.get_ticks() + while pygame.time.get_ticks() - start_time < ROUND_OVER_COOLDOWN or pygame.key.get_pressed()[pygame.K_SPACE]: + + resized_victory_img = pygame.transform.scale(victory_img, (victory_img.get_width() * 2, victory_img.get_height() * 2)) + screen.blit(resized_victory_img, (SCREEN_WIDTH // 2 - resized_victory_img.get_width() // 2, + SCREEN_HEIGHT // 2 - resized_victory_img.get_height() // 2 - 50)) + + screen.blit(winner_img, (SCREEN_WIDTH // 2 - winner_img.get_width() // 2, + SCREEN_HEIGHT // 2 - winner_img.get_height() // 2 + 100)) + + pygame.display.update() + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + + +def draw_gradient_text(text, font, x, y, colors): + offset = 2 + for i, color in enumerate(colors): + img = font.render(text, True, color) + screen.blit(img, (x + i * offset, y + i * offset)) + # Draw final, centered text + img = font.render(text, True, colors[-1]) + screen.blit(img, (x, y)) + + +def main_menu(): + animation_start_time = pygame.time.get_ticks() + + while True: + draw_bg(bg_image, is_game_started=False) + + elapsed_time = (pygame.time.get_ticks() - animation_start_time) / 1000 + scale_factor = 1 + 0.03 * math.sin(elapsed_time * math.pi) # Reduced oscillation for smoother effect + scaled_font = pygame.font.Font("assets/fonts/turok.ttf", int(100 * scale_factor)) + + title_text = "STREET FIGHTER" + colors = [BLUE, GREEN, YELLOW] + shadow_color = BLACK + title_x = SCREEN_WIDTH // 2 - scaled_font.size(title_text)[0] // 2 + title_y = SCREEN_HEIGHT // 6 + + shadow_offset = 5 + draw_text(title_text, scaled_font, shadow_color, title_x + shadow_offset, title_y + shadow_offset) + draw_gradient_text(title_text, scaled_font, title_x, title_y, colors) + + button_width = SCREEN_WIDTH // 4 + button_height = SCREEN_HEIGHT // 15 + button_spacing = SCREEN_HEIGHT // 20 + + start_button_y = SCREEN_HEIGHT // 2 - (button_height + button_spacing) * 1.5 + 50 + scores_button_y = SCREEN_HEIGHT // 2 - (button_height + button_spacing) * 0.5 + 50 + exit_button_y = SCREEN_HEIGHT // 2 + (button_height + button_spacing) * 0.5 + 50 + + start_button = draw_button("START GAME", menu_font, BLACK, GREEN, SCREEN_WIDTH // 2 - button_width // 2, + start_button_y, button_width, button_height) + scores_button = draw_button("SCORES", menu_font, BLACK, GREEN, SCREEN_WIDTH // 2 - button_width // 2, + scores_button_y, button_width, button_height) + exit_button = draw_button("EXIT", menu_font, BLACK, GREEN, SCREEN_WIDTH // 2 - button_width // 2, + exit_button_y, button_width, button_height) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + if event.type == pygame.MOUSEBUTTONDOWN: + if start_button.collidepoint(event.pos): + return "START" + if scores_button.collidepoint(event.pos): + return "SCORES" + if exit_button.collidepoint(event.pos): + pygame.quit() + sys.exit() + + pygame.display.update() + clock.tick(FPS) + + +def scores_screen(): + while True: + draw_bg(bg_image) + + scores_title = "SCORES" + draw_text(scores_title, menu_font_title, RED, SCREEN_WIDTH // 2 - menu_font_title.size(scores_title)[0] // 2, 50) + + score_font_large = pygame.font.Font("assets/fonts/turok.ttf", 60) # Increased size for scores + p1_text = f"WARRIOR: {score[0]}" + p2_text = f"WIZARD: {score[1]}" + shadow_offset = 5 + + p1_text_x = SCREEN_WIDTH // 2 - score_font_large.size(p1_text)[0] // 2 + p1_text_y = SCREEN_HEIGHT // 2 - 50 + draw_text(p1_text, score_font_large, BLACK, p1_text_x + shadow_offset, p1_text_y + shadow_offset) # Shadow + draw_gradient_text(p1_text, score_font_large, p1_text_x, p1_text_y, [BLUE, GREEN]) # Gradient + + p2_text_x = SCREEN_WIDTH // 2 - score_font_large.size(p2_text)[0] // 2 + p2_text_y = SCREEN_HEIGHT // 2 + 50 + draw_text(p2_text, score_font_large, BLACK, p2_text_x + shadow_offset, p2_text_y + shadow_offset) # Shadow + draw_gradient_text(p2_text, score_font_large, p2_text_x, p2_text_y, [RED, YELLOW]) # Gradient + + return_button = draw_button("RETURN TO MAIN MENU", menu_font, BLACK, GREEN, SCREEN_WIDTH // 2 - 220, 700, 500, 50) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + if event.type == pygame.MOUSEBUTTONDOWN: + if return_button.collidepoint(event.pos): + return + + pygame.display.update() + clock.tick(FPS) + + +def reset_game(): + global fighter_1, fighter_2 + fighter_1 = Fighter(1, SCREEN_WIDTH // 4, SCREEN_HEIGHT // 2, False, WARRIOR_DATA, warrior_sheet, + WARRIOR_ANIMATION_STEPS, sword_fx) + fighter_2 = Fighter(2, 3 * SCREEN_WIDTH // 4, SCREEN_HEIGHT // 2, True, WIZARD_DATA, wizard_sheet, + WIZARD_ANIMATION_STEPS, magic_fx) + + +def draw_health_bar(health, is_left, y): + bar_width = 400 + bar_height = 40 + padding = 20 + + if is_left: + x = padding + else: + x = SCREEN_WIDTH - bar_width - padding + + pygame.draw.rect(screen, BLACK, (x, y, bar_width, bar_height)) + if health > 0: + pygame.draw.rect(screen, RED, (x, y, health * 4, bar_height)) + pygame.draw.rect(screen, WHITE, (x, y, bar_width, bar_height), 4) + + +def countdown(): + countdown_font = pygame.font.Font(resource_path("assets/fonts/turok.ttf"), SCREEN_HEIGHT // 10) + countdown_texts = ["3", "2", "1", "FIGHT!"] + + for text in countdown_texts: + draw_bg(bg_image, is_game_started=True) + text_img = countdown_font.render(text, True, RED) + text_width, text_height = text_img.get_size() + x_pos = (SCREEN_WIDTH - text_width) // 2 + y_pos = (SCREEN_HEIGHT - text_height) // 2 + screen.blit(text_img, (x_pos, y_pos)) + pygame.display.update() + pygame.time.delay(1000) + + +def game_loop(): + global score + reset_game() + round_over = False + winner_img = None + game_started = True + + countdown() + + while True: + draw_bg(bg_image, is_game_started=game_started) + + warrior_text = f"WARRIOR HEALTH: {fighter_1.health}" + wizard_text = f"WIZARD HEALTH: {fighter_2.health}" + + warrior_text_width = score_font.size(warrior_text)[0] + wizard_text_width = score_font.size(wizard_text)[0] + + draw_text(warrior_text, score_font, RED, 20, 20) + draw_text(wizard_text, score_font, RED, SCREEN_WIDTH - wizard_text_width - 20, 20) + + draw_health_bar(fighter_1.health, True, 50) + draw_health_bar(fighter_2.health, False, 50) + + exit_button = draw_button("MAIN MENU", menu_font, BLACK, YELLOW, SCREEN_WIDTH // 2 - 150, 20, 300, 50) + + if not round_over: + fighter_1.move(SCREEN_WIDTH, SCREEN_HEIGHT, fighter_2, round_over) + fighter_2.move(SCREEN_WIDTH, SCREEN_HEIGHT, fighter_1, round_over) + + fighter_1.update() + fighter_2.update() + + if not fighter_1.alive: + score[1] += 1 + round_over = True + winner_img = wizard_victory_img + elif not fighter_2.alive: + score[0] += 1 + round_over = True + winner_img = warrior_victory_img + else: + victory_screen(winner_img) + return + + fighter_1.draw(screen) + fighter_2.draw(screen) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + if event.type == pygame.MOUSEBUTTONDOWN: + if exit_button.collidepoint(event.pos): + return + + pygame.display.update() + clock.tick(FPS) + + +while True: + menu_selection = main_menu() + + if menu_selection == "START": + game_loop() + elif menu_selection == "SCORES": + scores_screen()