diff --git a/Act_Of_Rejection.ttf b/Act_Of_Rejection.ttf new file mode 100644 index 0000000..76f570d Binary files /dev/null and b/Act_Of_Rejection.ttf differ diff --git a/PressStart2P-Regular.ttf b/PressStart2P-Regular.ttf new file mode 100644 index 0000000..39adf42 Binary files /dev/null and b/PressStart2P-Regular.ttf differ diff --git a/assets/font.ttf b/assets/font.ttf deleted file mode 100644 index e69de29..0000000 diff --git a/assets/music.mp3 b/assets/music.mp3 deleted file mode 100644 index e69de29..0000000 diff --git a/assets/shoot.wav b/assets/shoot.wav deleted file mode 100644 index e69de29..0000000 diff --git a/backgrounds/beach.jpg b/backgrounds/beach.jpg new file mode 100644 index 0000000..7f97183 Binary files /dev/null and b/backgrounds/beach.jpg differ diff --git a/backgrounds/evening_street.jpg b/backgrounds/evening_street.jpg new file mode 100644 index 0000000..af16b94 Binary files /dev/null and b/backgrounds/evening_street.jpg differ diff --git a/backgrounds/market.jpg b/backgrounds/market.jpg new file mode 100644 index 0000000..8923f57 Binary files /dev/null and b/backgrounds/market.jpg differ diff --git a/backgrounds/restaurant.jpg b/backgrounds/restaurant.jpg new file mode 100644 index 0000000..ec8b8fb Binary files /dev/null and b/backgrounds/restaurant.jpg differ diff --git a/backgrounds/sakura_street.jpg b/backgrounds/sakura_street.jpg new file mode 100644 index 0000000..2cae230 Binary files /dev/null and b/backgrounds/sakura_street.jpg differ diff --git a/backgrounds/ship.jpg b/backgrounds/ship.jpg new file mode 100644 index 0000000..f99c900 Binary files /dev/null and b/backgrounds/ship.jpg differ diff --git a/backgrounds/street_markets.jpg b/backgrounds/street_markets.jpg new file mode 100644 index 0000000..8cdd33a Binary files /dev/null and b/backgrounds/street_markets.jpg differ diff --git a/boom.png b/boom.png new file mode 100644 index 0000000..d856c42 Binary files /dev/null and b/boom.png differ diff --git a/boss/boss1.png b/boss/boss1.png new file mode 100644 index 0000000..737d746 Binary files /dev/null and b/boss/boss1.png differ diff --git a/boss/boss2.png b/boss/boss2.png new file mode 100644 index 0000000..17429e9 Binary files /dev/null and b/boss/boss2.png differ diff --git a/boss/boss3.png b/boss/boss3.png new file mode 100644 index 0000000..181cd9e Binary files /dev/null and b/boss/boss3.png differ diff --git a/characters/fifth5_char.png b/characters/fifth5_char.png new file mode 100644 index 0000000..836dc46 Binary files /dev/null and b/characters/fifth5_char.png differ diff --git a/characters/first1_char.png b/characters/first1_char.png new file mode 100644 index 0000000..cfdda01 Binary files /dev/null and b/characters/first1_char.png differ diff --git a/characters/forth4_char.png b/characters/forth4_char.png new file mode 100644 index 0000000..51a1c3e Binary files /dev/null and b/characters/forth4_char.png differ diff --git a/characters/second2_char.png b/characters/second2_char.png new file mode 100644 index 0000000..9781059 Binary files /dev/null and b/characters/second2_char.png differ diff --git a/characters/sixth6_char.png b/characters/sixth6_char.png new file mode 100644 index 0000000..f4ae68f Binary files /dev/null and b/characters/sixth6_char.png differ diff --git a/characters/third3_char.png b/characters/third3_char.png new file mode 100644 index 0000000..52290e9 Binary files /dev/null and b/characters/third3_char.png differ diff --git a/custom_cursor.png b/custom_cursor.png new file mode 100644 index 0000000..45efba9 Binary files /dev/null and b/custom_cursor.png differ diff --git a/freesound_community-pixel-sound-effect-3-82880.mp3 b/freesound_community-pixel-sound-effect-3-82880.mp3 new file mode 100644 index 0000000..bf1ed66 Binary files /dev/null and b/freesound_community-pixel-sound-effect-3-82880.mp3 differ diff --git a/game.py b/game.py index 857760a..7c26379 100644 --- a/game.py +++ b/game.py @@ -1,56 +1,263 @@ import pygame import random +import sys +import os +import math -# --- Inicializācija --- +# Inicializējam pygame pygame.init() -# Ekrāna iestatījumi +# --- AUDIO SISTĒMAS LABOJUMS --- +# Mēģinam ieslēgt skaņu, ja neizdodas - turpinām bez tās. +mixer_initialized = False +try: + pygame.mixer.init() + mixer_initialized = True +except pygame.error: + print("Brīdinājums: Neizdevās inicializēt audio sistēmu. Spēle tiks palaista bez skaņas.") +# ------------------------------ + WIDTH, HEIGHT = 1024, 576 SCREEN = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Pixel Kombat: Ultimate") + +# --- CUSTOM CURSOR IESTATĪJUMI (SĀKUMS) --- +# Paslēpjam noklusējuma sistēmas kursoru +pygame.mouse.set_visible(False) +# --- CUSTOM CURSOR IESTATĪJUMI (BEIGAS) --- CLOCK = pygame.time.Clock() -# --- Krāsas (PIEVIENOTS RED UN BLUE) --- +# --- KRĀSAS --- WHITE = (255, 255, 255) BLACK = (0, 0, 0) -RED = (255, 0, 0) # <--- Šis trūka -BLUE = (0, 0, 255) # <--- Papildus +RED = (255, 0, 0) +BLUE = (0, 0, 255) GRAY = (50, 50, 50) DARK_GRAY = (20, 20, 20) YELLOW = (255, 215, 0) -BROWN = (139, 69, 19) GREEN = (50, 200, 50) CYAN = (0, 255, 255) PURPLE = (160, 32, 240) - -# Pieejamās raksturu krāsas (saraksts) -COLORS = [ - (235, 64, 52), # Red - (52, 119, 235), # Blue - (52, 235, 86), # Green - (255, 215, 0), # Gold - (160, 32, 240), # Purple - (255, 105, 180) # Pink -] +ORANGE = (255, 165, 0) +LIGHT_BLUE = (100, 149, 237) # --- Fonti --- +def get_font(name, size): + if os.path.exists(name): + try: + return pygame.font.Font(name, size) + except: + return pygame.font.SysFont('arial', size) + else: + return pygame.font.SysFont('arial', size) + +FONT_BIG = get_font("Act_Of_Rejection.ttf", 80) +FONT_MED = get_font("PressStart2P-Regular.ttf", 36) +FONT_SMALL = get_font("PressStart2P-Regular.ttf", 20) +FONT_TINY = get_font("PressStart2P-Regular.ttf", 14) + +# --- Globālie mainīgie --- +STATE = "MENU" +SELECTED_BG = "BEACH" +GAME_MODE = "PVP" + +# --- Mūzika --- +MUSIC_FILE = "lofiewme-pixel-fantasia-355123.mp3" +sound_on = True + +# Mūzikas ielāde (tikai ja audio sistēma darbojas) +if mixer_initialized: + if os.path.exists(MUSIC_FILE): + try: + pygame.mixer.music.load(MUSIC_FILE) + pygame.mixer.music.set_volume(0.5) + pygame.mixer.music.play(-1) + except Exception as e: + print(f"Kļūda ielādējot mūziku: {e}") + else: + print(f"Mūzikas fails '{MUSIC_FILE}' nav atrasts.") +else: + print("Mūzika netiks atskaņota (audio nav pieejams).") + +# --- Sitiena skaņa --- +HIT_SOUND_FILE = "freesound_community-pixel-sound-effect-3-82880.mp3" +hit_sound = None + +# Skaņas ielāde (tikai ja audio sistēma darbojas) +if mixer_initialized: + if os.path.exists(HIT_SOUND_FILE): + try: + hit_sound = pygame.mixer.Sound(HIT_SOUND_FILE) + hit_sound.set_volume(0.7) + except Exception as e: + print(f"Kļūda ielādējot sitiena skaņu: {e}") + else: + print(f"Skaņas fails '{HIT_SOUND_FILE}' nav atrasts.") + +# --- High score --- +HIGHSCORE_FILE = "highscores.txt" +def save_highscore(winner_name): + try: + with open(HIGHSCORE_FILE, "a") as f: + f.write(f"{winner_name}\n") + except Exception as e: + print(f"Neizdevās saglabāt rezultātu: {e}") + +def load_highscores(): + scores = [] + if os.path.exists(HIGHSCORE_FILE): + try: + with open(HIGHSCORE_FILE, "r") as f: + lines = f.readlines() + scores = [line.strip() for line in lines[-5:]] + except: + pass + return scores + +# --- Tēlu un fona datu bāzes --- +FALLBACK_COLORS = [ + (235, 64, 52), (52, 119, 235), (52, 235, 86), (255, 215, 0), (160, 32, 240), (255, 105, 180) +] + +CHARACTER_FILES = [ + "characters/first1_char.png", "characters/second2_char.png", "characters/third3_char.png", + "characters/forth4_char.png", "characters/fifth5_char.png", "characters/sixth6_char.png" +] + +BOSS_FILES = ["boss/boss1.png", "boss/boss2.png", "boss/boss3.png"] + +P1_CHAR_INDEX = 0 +P2_CHAR_INDEX = 1 + +BG_FILES = { + "BEACH": "backgrounds/beach.jpg", "EVENINGSTREET": "backgrounds/evening_street.jpg", + "MARKET": "backgrounds/market.jpg", "RESTAURANT": "backgrounds/restaurant.jpg", + "SAKURASTREET": "backgrounds/sakura_street.jpg", "SHIP": "backgrounds/ship.jpg", + "STREETMARKETS": "backgrounds/street_markets.jpg" +} + +# --- Safe character(nav svarīgi) --- +def create_placeholder_image(color, size=(80, 160), text="", is_boss=False): + surf = pygame.Surface(size) + surf.fill(color) + if text: + font = pygame.font.SysFont('arial', 20) + txt = font.render(text, True, WHITE) + surf.blit(txt, (size[0]//2 - txt.get_width()//2, size[1]//2 - txt.get_height()//2)) + return surf + +# --- Tēlu ielade --- +def load_character_images(): + chars_data = [] + SPRITE_SIZE = (80, 150) + ICON_SIZE = (100, 100) + for i, filename in enumerate(CHARACTER_FILES): + color = FALLBACK_COLORS[i % len(FALLBACK_COLORS)] + try: + if os.path.exists(filename): + img = pygame.image.load(filename).convert_alpha() + game_img = pygame.transform.scale(img, SPRITE_SIZE) + icon_img = pygame.transform.scale(img, ICON_SIZE) + else: + raise FileNotFoundError +# --- Ja ne atrod attēlu --- + except: + game_img = create_placeholder_image(color, SPRITE_SIZE, f"T{i+1}") + icon_surf = pygame.Surface(ICON_SIZE) + icon_surf.fill(color) + pygame.draw.rect(icon_surf, WHITE, (0,0,ICON_SIZE[0], ICON_SIZE[1]), 2) + font = pygame.font.SysFont('arial', 24) + txt = font.render(f"Char {i+1}", True, WHITE) + icon_surf.blit(txt, (ICON_SIZE[0]//2 - txt.get_width()//2, ICON_SIZE[1]//2 - txt.get_height()//2)) + icon_img = icon_surf + chars_data.append({'game_img': game_img, 'icon': icon_img, 'color': color}) + return chars_data + +# --- Bossu ielade --- +def load_boss_images(): + bosses = [] + BOSS_SIZE = (160, 300) + boss_colors = [(100, 0, 0), (0, 100, 0), (0, 0, 100)] + + for i, filename in enumerate(BOSS_FILES): + try: + if os.path.exists(filename): + img = pygame.image.load(filename).convert_alpha() + img = pygame.transform.scale(img, BOSS_SIZE) + bosses.append(img) + else: + raise FileNotFoundError + except: + img = create_placeholder_image(boss_colors[i % len(boss_colors)], BOSS_SIZE, f"BOSS", is_boss=True) + bosses.append(img) + return bosses + +# --- Ja fons un logu bildes nav atrastas --- +def load_image_safe(filename, fallback_color, size=None): + try: + if os.path.exists(filename): + img = pygame.image.load(filename) + if size: + img = pygame.transform.scale(img, size) + else: + img = pygame.transform.scale(img, (WIDTH, HEIGHT)) + return img + else: + raise FileNotFoundError + except: + surf = pygame.Surface(size if size else (WIDTH, HEIGHT)) + surf.fill(fallback_color) + return surf + +# --- Attēlu ielade --- +CHARACTERS = load_character_images() +BOSS_IMAGES = load_boss_images() + +# --- Menu bildes --- +MENU_PIC_WIDTH = 250 +menupic1 = load_image_safe("menupic1.png", FALLBACK_COLORS[1], (MENU_PIC_WIDTH, HEIGHT)) +menupic2 = load_image_safe("menupic2.png", FALLBACK_COLORS[0], (MENU_PIC_WIDTH, HEIGHT)) + +# --- Fonu attēli --- +bg_images = {} +cols = {"BEACH": (194, 178, 128), "EVENINGSTREET": (30, 30, 50), "MARKET": (100, 80, 60), + "RESTAURANT": (150, 100, 50), "SAKURASTREET": (255, 183, 197), "SHIP": (0, 105, 148), + "STREETMARKETS": (90, 90, 90)} +for key, path in BG_FILES.items(): + bg_images[key] = load_image_safe(path, cols.get(key, GRAY)) + +# --- Boom attēla ielade --- try: - FONT_BIG = pygame.font.Font(None, 74) - FONT_MED = pygame.font.Font(None, 50) - FONT_SMALL = pygame.font.Font(None, 32) + if os.path.exists("boom.png"): + BOOM_IMG_ORIGINAL = pygame.image.load("boom.png").convert_alpha() + BOOM_IMG = pygame.transform.scale(BOOM_IMG_ORIGINAL, (80, 80)) + BOOM_IMG_LARGE = pygame.transform.scale(BOOM_IMG_ORIGINAL, (160, 160)) + else: + BOOM_IMG = pygame.Surface((80, 80)); BOOM_IMG.fill(YELLOW) + BOOM_IMG_LARGE = pygame.Surface((160, 160)); BOOM_IMG_LARGE.fill(ORANGE) except: - FONT_BIG = pygame.font.SysFont("Arial", 74) - FONT_MED = pygame.font.SysFont("Arial", 50) - FONT_SMALL = pygame.font.SysFont("Arial", 32) + BOOM_IMG = pygame.Surface((80, 80)); BOOM_IMG.fill(YELLOW) + BOOM_IMG_LARGE = pygame.Surface((160, 160)); BOOM_IMG_LARGE.fill(ORANGE) -# --- Globālie mainīgie (Spēles stāvokļi) --- -STATE = "MENU" # MENU, CHAR_SELECT, BG_SELECT, DIALOGUE, GAME, GAMEOVER -SELECTED_BG = "CITY" -P1_COLOR = COLORS[0] # Noklusējums -P2_COLOR = COLORS[1] # Noklusējums +# --- Custom cursor ielade --- +CURSOR_IMG = None +CURSOR_FILE = "custom_cursor.png" +if os.path.exists(CURSOR_FILE): + try: + CURSOR_IMG = pygame.image.load(CURSOR_FILE).convert_alpha() + CURSOR_IMG = pygame.transform.scale(CURSOR_IMG, (32, 32)) + print("Kursors veiksmīgi ielādēts.") + except Exception as e: + print(f"Kļūda ielādējot kursoru: {e}") +else: + print(f"Kursora fails '{CURSOR_FILE}' nav atrasts.") + CURSOR_IMG = pygame.Surface((20, 20), pygame.SRCALPHA) + pygame.draw.circle(CURSOR_IMG, WHITE, (10, 10), 10) + pygame.draw.circle(CURSOR_IMG, BLACK, (10, 10), 10, 2) -# --- UI Klases --- +# ---- UI Klases ---- +# --- Visas pogas(to visparīgums un pārbaude) class Button: def __init__(self, x, y, w, h, text, color, hover_color, action_code): self.rect = pygame.Rect(x, y, w, h) @@ -61,12 +268,9 @@ class Button: def draw(self, surface): mouse_pos = pygame.mouse.get_pos() - color = self.hover_color if self.rect.collidepoint(mouse_pos) else self.color - - pygame.draw.rect(surface, color, self.rect) - pygame.draw.rect(surface, WHITE, self.rect, 2) # Apmale - - text_surf = FONT_SMALL.render(self.text, True, WHITE) + is_hovered = self.rect.collidepoint(mouse_pos) + current_color = self.hover_color if is_hovered else self.color + text_surf = FONT_SMALL.render(self.text, True, current_color) surface.blit(text_surf, (self.rect.centerx - text_surf.get_width()//2, self.rect.centery - text_surf.get_height()//2)) def is_clicked(self, event): @@ -75,20 +279,39 @@ class Button: return True return False -# --- Klase Spēlētājam --- +# ---Consolēs zīmejums --- +def draw_key_visual(surface, x, y, w, h, key_text, action_text, color): + pygame.draw.rect(surface, color, (x, y, w, h), 2) + pygame.draw.rect(surface, DARK_GRAY, (x+4, y+4, w-8, h-8)) + + txt_surf = FONT_SMALL.render(key_text, True, WHITE) + surface.blit(txt_surf, (x + w//2 - txt_surf.get_width()//2, y + 10)) + + desc_surf = FONT_TINY.render(action_text, True, GRAY) + surface.blit(desc_surf, (x + w//2 - desc_surf.get_width()//2, y + h + 5)) + +# ---Cīnītājs --- class Fighter(pygame.sprite.Sprite): - def __init__(self, x, y, color, facing_right, controls): + def __init__(self, x, y, char_data, facing_right, controls): super().__init__() - self.original_color = color - self.color = color - - self.rect = pygame.Rect(x, y, 50, 100) + # - Ka izskatas - + self.char_data = char_data + self.image = char_data['game_img'] + self.color_accent = char_data['color'] + self.start_x = x + self.start_y = y + self.facing_right_start = facing_right + # - Fizika - + self.rect = self.image.get_rect() + self.rect.center = (x, y) + self.rect.bottom = HEIGHT - 50 + # - Fizikas un Kustības - self.vel_y = 0 self.speed = 7 - self.jump_power = -18 + self.jump_power = -20 self.gravity = 0.8 self.on_ground = False - + # - Stāvokļa un cīnas - self.facing_right = facing_right self.controls = controls self.attacking = False @@ -96,8 +319,19 @@ class Fighter(pygame.sprite.Sprite): self.attack_box = pygame.Rect(0, 0, 0, 0) self.health = 100 self.hit_timer = 0 - + # - Sagatavot nākamajai kārtai - + def reset_round(self): + self.health = 100 + self.vel_y = 0 + self.rect.center = (self.start_x, self.start_y) + self.rect.bottom = HEIGHT - 50 + self.facing_right = self.facing_right_start + self.attacking = False + self.attack_cooldown = 0 + self.hit_timer = 0 + # - tēla pārvietošana - def move(self, keys): + # - Horizontāla kustība - dx = 0 if keys[self.controls['left']]: dx = -self.speed @@ -105,15 +339,16 @@ class Fighter(pygame.sprite.Sprite): if keys[self.controls['right']]: dx = self.speed self.facing_right = True - + # - robežas - self.rect.x += dx if self.rect.left < 0: self.rect.left = 0 if self.rect.right > WIDTH: self.rect.right = WIDTH + # - Lekšana - if keys[self.controls['jump']] and self.on_ground: self.vel_y = self.jump_power self.on_ground = False - + # - Gravitācija - self.vel_y += self.gravity self.rect.y += self.vel_y @@ -121,43 +356,26 @@ class Fighter(pygame.sprite.Sprite): self.rect.bottom = HEIGHT - 50 self.vel_y = 0 self.on_ground = True - + # - Uzbrukuma uzsākšana - def attack(self): if self.attack_cooldown == 0: self.attacking = True self.attack_cooldown = 20 if self.facing_right: - self.attack_box = pygame.Rect(self.rect.right, self.rect.y + 20, 60, 50) + self.attack_box = pygame.Rect(self.rect.right, self.rect.y + 40, 80, 80) else: - self.attack_box = pygame.Rect(self.rect.left - 60, self.rect.y + 20, 60, 50) - + self.attack_box = pygame.Rect(self.rect.left - 80, self.rect.y + 40, 80, 80) + # - Taimeris - def update(self): if self.attack_cooldown > 0: self.attack_cooldown -= 1 else: self.attacking = False - - if self.hit_timer > 0: - self.hit_timer -= 1 - self.color = WHITE - else: - self.color = self.original_color - + if self.hit_timer > 0: self.hit_timer -= 1 + # - Tēla darbība uz ekranā - def draw(self, surface): - pygame.draw.rect(surface, self.color, self.rect) - pygame.draw.rect(surface, BLACK, self.rect, 2) - - head_rect = pygame.Rect(self.rect.x + 10, self.rect.y - 20, 30, 20) - pygame.draw.rect(surface, self.color, head_rect) - pygame.draw.rect(surface, BLACK, head_rect, 2) - - eye_color = BLACK - if self.facing_right: - pygame.draw.rect(surface, eye_color, (self.rect.x + 30, self.rect.y - 15, 5, 5)) - else: - pygame.draw.rect(surface, eye_color, (self.rect.x + 15, self.rect.y - 15, 5, 5)) - + img_to_draw = pygame.transform.flip(self.image, not self.facing_right, False) + surface.blit(img_to_draw, self.rect) if self.attacking: - pygame.draw.rect(surface, YELLOW, self.attack_box) - pygame.draw.rect(surface, WHITE, self.attack_box, 2) + surface.blit(BOOM_IMG, self.attack_box) def take_damage(self, amount): self.health -= amount @@ -166,150 +384,238 @@ class Fighter(pygame.sprite.Sprite): if self.rect.centerx < WIDTH // 2: self.rect.x -= 20 else: self.rect.x += 20 -# --- Fona Zīmēšanas Funkcijas --- +# --- Boss --- +class Boss(pygame.sprite.Sprite): + def __init__(self, image): + super().__init__() + self.image = image + self.rect = self.image.get_rect() + self.rect.center = (WIDTH // 2, HEIGHT // 2) + self.rect.bottom = HEIGHT - 50 + + self.health = 150 + self.max_health = 150 + self.speed = 3 + self.damage = 3 + + self.vel_y = 0 + self.gravity = 0.8 + self.on_ground = False + + self.facing_right = True + self.attacking = False + self.attack_cooldown = 0 + self.attack_box = pygame.Rect(0, 0, 0, 0) + self.hit_timer = 0 + + self.target = None + + def ai_move(self, targets): + closest_dist = 99999 + target = None + # - Attālums līdz target - + for t in targets: + if t.health > 0: + dist = abs(self.rect.centerx - t.rect.centerx) + if dist < closest_dist: + closest_dist = dist + target = t + + if target: + self.target = target + if target.rect.centerx < self.rect.centerx: + self.rect.x -= self.speed + self.facing_right = False + else: + self.rect.x += self.speed + self.facing_right = True + + if closest_dist < 180: + self.attack() + + self.vel_y += self.gravity + self.rect.y += self.vel_y + if self.rect.bottom >= HEIGHT - 50: + self.rect.bottom = HEIGHT - 50 + self.vel_y = 0 + self.on_ground = True + + def attack(self): + if self.attack_cooldown == 0: + self.attacking = True + self.attack_cooldown = 45 + if self.facing_right: + self.attack_box = pygame.Rect(self.rect.right, self.rect.y + 80, 160, 160) + else: + self.attack_box = pygame.Rect(self.rect.left - 160, self.rect.y + 80, 160, 160) + + def update(self): + if self.attack_cooldown > 0: self.attack_cooldown -= 1 + else: self.attacking = False + if self.hit_timer > 0: self.hit_timer -= 1 -def draw_city(surface): - surface.fill((20, 30, 50)) # Nakts debesis - pygame.draw.circle(surface, (200, 200, 200), (WIDTH//2, 100), 60) # Mēness - for i in range(5): - w = random.randint(50, 150) - h = random.randint(200, 400) - x = i * (WIDTH // 5) + 20 - pygame.draw.rect(surface, (10, 10, 20), (x, HEIGHT - 50 - h, w-10, h)) # Ēkas - pygame.draw.rect(surface, BROWN, (0, HEIGHT - 50, WIDTH, 50)) # Zeme + def draw(self, surface): + img_to_draw = pygame.transform.flip(self.image, not self.facing_right, False) + surface.blit(img_to_draw, self.rect) + if self.attacking: + surface.blit(BOOM_IMG_LARGE, self.attack_box) + + def take_damage(self, amount): + self.health -= amount + self.hit_timer = 10 + if self.rect.centerx < WIDTH // 2: self.rect.x -= 5 + else: self.rect.x += 5 -def draw_forest(surface): - surface.fill((50, 150, 50)) # Gaiši zaļš debesis/ugs - pygame.draw.circle(surface, (255, 255, 100), (WIDTH - 100, 80), 50) # Saule - for i in range(8): - x = i * (WIDTH // 8) + 40 - # Koku stumbri - pygame.draw.rect(surface, (80, 50, 20), (x, HEIGHT - 200, 40, 150)) - # Koku vainagi (trīsstūri stilā) - pygame.draw.polygon(surface, (20, 100, 20), [(x-40, HEIGHT-200), (x+40, HEIGHT-200), (x, HEIGHT-300)]) - pygame.draw.polygon(surface, (20, 100, 20), [(x-35, HEIGHT-240), (x+35, HEIGHT-240), (x, HEIGHT-340)]) - pygame.draw.rect(surface, (30, 100, 30), (0, HEIGHT - 50, WIDTH, 50)) # Zāle - -def draw_dojo(surface): - surface.fill((180, 100, 50)) # Koka sieni - # Girdīngs - pygame.draw.rect(surface, (100, 50, 0), (0, HEIGHT - 200, WIDTH, 50)) - pygame.draw.rect(surface, (100, 50, 0), (0, 0, WIDTH, 50)) - # Vairogzīmes - for i in range(1, 10): - x = i * (WIDTH // 10) - pygame.draw.line(surface, (50, 0, 0), (x, 50), (x, HEIGHT - 200), 2) - pygame.draw.rect(surface, (50, 0, 0), (0, HEIGHT - 50, WIDTH, 50)) # Sarkanā grīda - -def get_bg_function(name): - if name == "CITY": return draw_city - if name == "FOREST": return draw_forest - return draw_dojo +def draw_background(surface, bg_name): + img = bg_images.get(bg_name, list(bg_images.values())[0]) + surface.blit(img, (0, 0)) # --- Dialogi --- class DialogueManager: def __init__(self): - self.lines = [ - "PREPARE FOR BATTLE!", - "Who will win today?", - "Fight with honor!", - "Show me your moves!" - ] + self.lines = ["SAGATAVOJIES CĪŅAI!", "Kurš šodien uzvarēs?", "Cīnies ar godu!", "Parādi savas kustības!"] self.current_text = random.choice(self.lines) self.active = False self.timer = 0 - def start(self): + def start(self, is_boss=False): self.active = True self.timer = pygame.time.get_ticks() - self.current_text = random.choice(self.lines) + if is_boss: + self.current_text = "BOSS APPROACHING!" + else: + self.current_text = random.choice(self.lines) def draw(self, surface): if not self.active: return - - # Kaste - box_rect = pygame.Rect(WIDTH//2 - 300, HEIGHT//2 - 50, 600, 100) + text_surf = FONT_SMALL.render(self.current_text, True, YELLOW) + text_width = text_surf.get_width() + text_height = text_surf.get_height() + padding_x = 40 + padding_y = 25 + box_w = text_width + padding_x * 2 + box_h = text_height + padding_y * 2 + box_rect = pygame.Rect(WIDTH//2 - box_w//2, HEIGHT//2 - box_h//2, box_w, box_h) pygame.draw.rect(surface, BLACK, box_rect) pygame.draw.rect(surface, WHITE, box_rect, 4) - - # Teksts - text_surf = FONT_MED.render(self.current_text, True, YELLOW) - surface.blit(text_surf, (box_rect.centerx - text_surf.get_width()//2, box_rect.centery - text_surf.get_height()//2)) - - # Instrukcija - sub_surf = FONT_SMALL.render("Nospiediet [SPACE] lai sāktu", True, WHITE) - surface.blit(sub_surf, (box_rect.centerx - sub_surf.get_width()//2, box_rect.bottom + 10)) + surface.blit(text_surf, (box_rect.centerx - text_width//2, box_rect.centery - text_height//2)) + sub_surf = FONT_TINY.render("Nospiediet [SPACE] lai saktu", True, WHITE) + surface.blit(sub_surf, (WIDTH//2 - sub_surf.get_width()//2, box_rect.bottom + 15)) # --- Galvenā Spēle --- - def main(): - global STATE, P1_COLOR, P2_COLOR, SELECTED_BG + global STATE, P1_CHAR_INDEX, P2_CHAR_INDEX, SELECTED_BG, GAME_MODE, sound_on - # Kontroles controls_p1 = {'left': pygame.K_a, 'right': pygame.K_d, 'jump': pygame.K_w, 'attack': pygame.K_SPACE} - # P2 uzbrukums tagad ir Enter taustiņš controls_p2 = {'left': pygame.K_LEFT, 'right': pygame.K_RIGHT, 'jump': pygame.K_UP, 'attack': pygame.K_RETURN} dialogue_mgr = DialogueManager() - # Izveidojam pogas + # Pogas (novietotas centrā) + btn_x = WIDTH//2 - 100 menu_buttons = [ - Button(WIDTH//2 - 100, 200, 200, 50, "Sakt Cīnu", GRAY, DARK_GRAY, "START"), - Button(WIDTH//2 - 100, 270, 200, 50, "Tēlu Izvēle", GRAY, DARK_GRAY, "CHARS"), - Button(WIDTH//2 - 100, 340, 200, 50, "Fona Izvēle", GRAY, DARK_GRAY, "BG"), - Button(WIDTH//2 - 100, 410, 200, 50, "Iziet", RED, (150, 0, 0), "QUIT") + Button(btn_x, 180, 200, 50, "PvP", YELLOW, RED, "START_PVP"), + Button(btn_x, 240, 200, 50, "Cīna ar Bossu", YELLOW, RED, "START_BOSS"), + Button(btn_x, 300, 200, 50, "Tēlu Izvēle", YELLOW, RED, "CHARS"), + Button(btn_x, 360, 200, 50, "Fona Izvēle", YELLOW, RED, "BG"), + Button(btn_x, 420, 200, 50, "Kontroles", YELLOW, RED, "INSTRUCTIONS"), ] bg_buttons = [ - Button(200, 300, 150, 100, "CITY", (20, 30, 50), DARK_GRAY, "CITY"), - Button(425, 300, 150, 100, "FOREST", (50, 150, 50), DARK_GRAY, "FOREST"), - Button(650, 300, 150, 100, "DOJO", (180, 100, 50), DARK_GRAY, "DOJO"), - Button(WIDTH//2 - 100, 450, 200, 50, "Atpakaļ", GRAY, DARK_GRAY, "BACK") + Button(150, 200, 200, 50, "Pludmale", WHITE, YELLOW, "BEACH"), + Button(412, 200, 200, 50, "Nakts iela", WHITE, YELLOW, "EVENINGSTREET"), + Button(674, 200, 200, 50, "Tirgus", WHITE, YELLOW, "MARKET"), + Button(150, 280, 200, 50, "Restorāns", WHITE, YELLOW, "RESTAURANT"), + Button(412, 280, 200, 50, "Sakuras iela", WHITE, YELLOW, "SAKURASTREET"), + Button(674, 280, 200, 50, "Ports", WHITE, YELLOW, "SHIP"), + Button(WIDTH//2 - 100, 360, 200, 50, "Ielu tirgus", WHITE, YELLOW, "STREETMARKETS"), + Button(WIDTH//2 - 100, 450, 200, 50, "Atpakaļ", GRAY, WHITE, "BACK") ] - back_btn = Button(20, 20, 100, 40, "Atpakaļ", GRAY, DARK_GRAY, "BACK") + back_btn_chars = Button(WIDTH//2 - 100, HEIGHT - 80, 200, 50, "Atpakal", GRAY, WHITE, "BACK") + back_btn_inst = Button(WIDTH//2 - 100, HEIGHT - 80, 200, 50, "Atpakal", GRAY, WHITE, "BACK") - # Spēlētāji (sākotnēji None, tiek veidoti pirms spēles) fighter1 = None fighter2 = None + boss = None + + p1_score = 0 + p2_score = 0 + current_round = 1 + round_winner_name = "" + match_winner_name = "" + + state_timer = 0 + + # --- SKAŅAS POGA --- + mute_btn_rect = pygame.Rect(20, HEIGHT - 35, 140, 25) run = True while run: CLOCK.tick(60) - mouse_pos = pygame.mouse.get_pos() for event in pygame.event.get(): if event.type == pygame.QUIT: run = False - # Pogu apstrāde atkarībā no stāvokļa + # --- Skaņas pogas loģika (LABOTS) --- + if event.type == pygame.MOUSEBUTTONDOWN: + if mute_btn_rect.collidepoint(event.pos): + sound_on = not sound_on + # Mainām skaļumu tikai tad, ja audio sistēma ir inicializēta + if mixer_initialized: + if sound_on: + pygame.mixer.music.set_volume(0.5) + else: + pygame.mixer.music.set_volume(0) + if STATE == "MENU": for btn in menu_buttons: if btn.is_clicked(event): - if btn.action_code == "START": - dialogue_mgr.start() + if btn.action_code == "START_PVP": + GAME_MODE = "PVP" + p1_score = 0 + p2_score = 0 + current_round = 1 + fighter1 = Fighter(200, 300, CHARACTERS[P1_CHAR_INDEX], True, controls_p1) + fighter2 = Fighter(800, 300, CHARACTERS[P2_CHAR_INDEX], False, controls_p2) + dialogue_mgr.start(is_boss=False) STATE = "DIALOGUE" + + elif btn.action_code == "START_BOSS": + GAME_MODE = "BOSS" + fighter1 = Fighter(150, 300, CHARACTERS[P1_CHAR_INDEX], True, controls_p1) + fighter2 = Fighter(300, 300, CHARACTERS[P2_CHAR_INDEX], True, controls_p2) + boss_img = random.choice(BOSS_IMAGES) + boss = Boss(boss_img) + dialogue_mgr.start(is_boss=True) + STATE = "DIALOGUE" + elif btn.action_code == "CHARS": STATE = "CHAR_SELECT" elif btn.action_code == "BG": STATE = "BG_SELECT" - elif btn.action_code == "QUIT": - run = False + elif btn.action_code == "INSTRUCTIONS": + STATE = "INSTRUCTIONS" elif STATE == "CHAR_SELECT": - # P1 izvēle (kreisā puse) - for i, color in enumerate(COLORS): - rect = pygame.Rect(150 + i*60, 200, 50, 50) - if event.type == pygame.MOUSEBUTTONDOWN and rect.collidepoint(event.pos): - P1_COLOR = color + icon_w = 100 + gap = 10 + total_w = len(CHARACTERS) * icon_w + (len(CHARACTERS)-1) * gap + start_x = (WIDTH - total_w) // 2 + y_p1 = 150 + for i, char in enumerate(CHARACTERS): + icon_rect = pygame.Rect(start_x + i * (icon_w + gap), y_p1, icon_w, icon_w) + if event.type == pygame.MOUSEBUTTONDOWN and icon_rect.collidepoint(event.pos): + P1_CHAR_INDEX = i - # P2 izvēle (labā puse) - for i, color in enumerate(COLORS): - rect = pygame.Rect(WIDTH - 450 + i*60, 200, 50, 50) - if event.type == pygame.MOUSEBUTTONDOWN and rect.collidepoint(event.pos): - P2_COLOR = color + y_p2 = 350 + for i, char in enumerate(CHARACTERS): + icon_rect = pygame.Rect(start_x + i * (icon_w + gap), y_p2, icon_w, icon_w) + if event.type == pygame.MOUSEBUTTONDOWN and icon_rect.collidepoint(event.pos): + P2_CHAR_INDEX = i - if back_btn.is_clicked(event): + if back_btn_chars.is_clicked(event): STATE = "MENU" elif STATE == "BG_SELECT": @@ -319,14 +625,16 @@ def main(): STATE = "MENU" else: SELECTED_BG = btn.action_code + + elif STATE == "INSTRUCTIONS": + if back_btn_inst.is_clicked(event): + STATE = "MENU" elif STATE == "DIALOGUE": if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: dialogue_mgr.active = False - # Inicializējam spēli - fighter1 = Fighter(200, 300, P1_COLOR, True, controls_p1) - fighter2 = Fighter(800, 300, P2_COLOR, False, controls_p2) - STATE = "GAME" + state_timer = pygame.time.get_ticks() + STATE = "ROUND_START" elif STATE == "GAME": if event.type == pygame.KEYDOWN: @@ -337,98 +645,329 @@ def main(): if event.type == pygame.KEYDOWN and event.key == pygame.K_r: STATE = "MENU" - # --- Zīmēšanas Loģika --- + # --- Zīmēšana un Loģika --- if STATE == "MENU": SCREEN.fill(BLACK) - title = FONT_BIG.render("PIXEL KOMBAT", True, WHITE) - SCREEN.blit(title, (WIDTH//2 - title.get_width()//2, 100)) + + SCREEN.blit(menupic1, (0, 0)) + SCREEN.blit(menupic2, (WIDTH - MENU_PIC_WIDTH, 0)) + + title_text = "PIXEL KOMBAT" + shadow_text = FONT_BIG.render(title_text, True, (180, 0, 0)) + SCREEN.blit(shadow_text, (WIDTH//2 - shadow_text.get_width()//2 + 3, 53)) + main_text = FONT_BIG.render(title_text, True, YELLOW) + SCREEN.blit(main_text, (WIDTH//2 - main_text.get_width()//2, 50)) + for btn in menu_buttons: btn.draw(SCREEN) + + cp_text = "© PIXEL KOMBAT 2026" + cp_surf = FONT_TINY.render(cp_text, True, WHITE) + SCREEN.blit(cp_surf, (WIDTH//2 - cp_surf.get_width()//2, HEIGHT - 30)) + + elif STATE == "INSTRUCTIONS": + SCREEN.fill(BLACK) + + title = FONT_BIG.render("KONTROLES", True, YELLOW) + SCREEN.blit(title, (WIDTH//2 - title.get_width()//2, 30)) + + p1_center_x = WIDTH // 2 - 200 + p2_center_x = WIDTH // 2 + 200 + + title_y = 170 + key_row1_y = 240 + key_row2_y = 320 + key_row3_y = 420 + + p1_title = FONT_MED.render("PLAYER 1", True, BLUE) + SCREEN.blit(p1_title, (p1_center_x - p1_title.get_width()//2, title_y)) + + draw_key_visual(SCREEN, p1_center_x - 35, key_row1_y, 70, 50, "W", "LEKT", BLUE) + draw_key_visual(SCREEN, p1_center_x - 35 - 80, key_row2_y, 70, 50, "A", "KREISI", BLUE) + draw_key_visual(SCREEN, p1_center_x - 35 + 80, key_row2_y, 70, 50, "D", "LABI", BLUE) + space_w = 200 + draw_key_visual(SCREEN, p1_center_x - space_w//2, key_row3_y, space_w, 50, "SPACE", "SIT", RED) + + p2_title = FONT_MED.render("PLAYER 2", True, RED) + SCREEN.blit(p2_title, (p2_center_x - p2_title.get_width()//2, title_y)) + + draw_key_visual(SCREEN, p2_center_x - 35, key_row1_y, 70, 50, "UP", "LEKT", RED) + draw_key_visual(SCREEN, p2_center_x - 35 - 80, key_row2_y, 70, 50, "LEFT", "KREISI", RED) + draw_key_visual(SCREEN, p2_center_x - 35 + 80, key_row2_y, 70, 50, "RIGHT", "LABI", RED) + enter_w = 150 + draw_key_visual(SCREEN, p2_center_x - enter_w//2, key_row3_y, enter_w, 50, "ENTER", "SIT", BLUE) + + back_btn_inst.draw(SCREEN) elif STATE == "CHAR_SELECT": SCREEN.fill(DARK_GRAY) + title1 = FONT_SMALL.render("IZVELIES TELU", True, WHITE) + SCREEN.blit(title1, (WIDTH//2 - title1.get_width()//2, 30)) - title = FONT_MED.render("IZVĒLIES TĒLU", True, WHITE) - SCREEN.blit(title, (WIDTH//2 - title.get_width()//2, 50)) + icon_w = 100 + gap = 10 + total_w = len(CHARACTERS) * icon_w + (len(CHARACTERS)-1) * gap + start_x = (WIDTH - total_w) // 2 + + p1_text = FONT_SMALL.render("PLAYER 1", True, CHARACTERS[P1_CHAR_INDEX]['color']) + SCREEN.blit(p1_text, (WIDTH//2 - p1_text.get_width()//2, 110)) - # Zīmējam P1 paneli - p1_text = FONT_SMALL.render("PLAYER 1", True, P1_COLOR) - SCREEN.blit(p1_text, (200, 150)) - for i, color in enumerate(COLORS): - r = pygame.Rect(150 + i*60, 200, 50, 50) - pygame.draw.rect(SCREEN, color, r) - pygame.draw.rect(SCREEN, WHITE, r, 2 if color != P1_COLOR else 5) + y_p1 = 150 + for i, char in enumerate(CHARACTERS): + icon_rect = pygame.Rect(start_x + i * (icon_w + gap), y_p1, icon_w, icon_w) + SCREEN.blit(char['icon'], icon_rect.topleft) + border_color = WHITE if i != P1_CHAR_INDEX else YELLOW + border_width = 2 if i != P1_CHAR_INDEX else 4 + pygame.draw.rect(SCREEN, border_color, icon_rect, border_width) - # Zīmējam P2 paneli - p2_text = FONT_SMALL.render("PLAYER 2", True, P2_COLOR) - SCREEN.blit(p2_text, (WIDTH - 350, 150)) - for i, color in enumerate(COLORS): - r = pygame.Rect(WIDTH - 450 + i*60, 200, 50, 50) - pygame.draw.rect(SCREEN, color, r) - pygame.draw.rect(SCREEN, WHITE, r, 2 if color != P2_COLOR else 5) + p2_text = FONT_SMALL.render("PLAYER 2", True, CHARACTERS[P2_CHAR_INDEX]['color']) + SCREEN.blit(p2_text, (WIDTH//2 - p2_text.get_width()//2, 300)) + + y_p2 = 340 + for i, char in enumerate(CHARACTERS): + icon_rect = pygame.Rect(start_x + i * (icon_w + gap), y_p2, icon_w, icon_w) + SCREEN.blit(char['icon'], icon_rect.topleft) + border_color = WHITE if i != P2_CHAR_INDEX else YELLOW + border_width = 2 if i != P2_CHAR_INDEX else 4 + pygame.draw.rect(SCREEN, border_color, icon_rect, border_width) - back_btn.draw(SCREEN) + back_btn_chars.draw(SCREEN) elif STATE == "BG_SELECT": SCREEN.fill(BLACK) - title = FONT_MED.render("IZVĒLIES VIDI", True, WHITE) - SCREEN.blit(title, (WIDTH//2 - title.get_width()//2, 50)) - + title = FONT_MED.render("IZVELIES VIDI", True, WHITE) + SCREEN.blit(title, (WIDTH//2 - title.get_width()//2, 100)) for btn in bg_buttons: btn.draw(SCREEN) elif STATE == "DIALOGUE": - # Rādam fona priekšskatījumu aiz dialoga - get_bg_function(SELECTED_BG)(SCREEN) + draw_background(SCREEN, SELECTED_BG) dialogue_mgr.draw(SCREEN) + + elif STATE == "ROUND_START": + draw_background(SCREEN, SELECTED_BG) + fighter1.draw(SCREEN) + fighter2.draw(SCREEN) + if GAME_MODE == "BOSS" and boss: + boss.draw(SCREEN) + if GAME_MODE == "BOSS" and boss: + pygame.draw.rect(SCREEN, BLACK, (WIDTH//2 - 302, 18, 604, 34)) + pygame.draw.rect(SCREEN, RED, (WIDTH//2 - 300, 20, 600, 30)) + w = (boss.health / boss.max_health) * 600 + pygame.draw.rect(SCREEN, PURPLE, (WIDTH//2 - 300, 20, w, 30)) + pygame.draw.rect(SCREEN, WHITE, (WIDTH//2 - 300, 20, 600, 30), 2) + else: + pygame.draw.rect(SCREEN, BLACK, (20, 20, 400, 40)) + pygame.draw.rect(SCREEN, fighter1.color_accent, (20, 20, 400, 40)) + pygame.draw.rect(SCREEN, WHITE, (20, 20, 400, 40), 2) + + pygame.draw.rect(SCREEN, BLACK, (WIDTH-420, 20, 400, 40)) + pygame.draw.rect(SCREEN, fighter2.color_accent, (WIDTH-420, 20, 400, 40)) + pygame.draw.rect(SCREEN, WHITE, (WIDTH-420, 20, 400, 40), 2) + + elapsed = pygame.time.get_ticks() - state_timer + + if elapsed < 1500: + txt = FONT_MED.render(f"ROUND {current_round}" if GAME_MODE == "PVP" else "BOSS FIGHT", True, YELLOW) + SCREEN.blit(txt, (WIDTH//2 - txt.get_width()//2, HEIGHT//2 - 50)) + elif elapsed < 3000: + txt = FONT_BIG.render("FIGHT!", True, WHITE) + offset_x = random.randint(-2, 2) + offset_y = random.randint(-2, 2) + SCREEN.blit(txt, (WIDTH//2 - txt.get_width()//2 + offset_x, HEIGHT//2 - 50 + offset_y)) + else: + STATE = "GAME" + elif STATE == "GAME": keys = pygame.key.get_pressed() - # Spēles loģika fighter1.move(keys) fighter2.move(keys) fighter1.update() fighter2.update() - if fighter1.attacking and fighter1.attack_box.colliderect(fighter2.rect): - if fighter2.hit_timer == 0: fighter2.take_damage(5) - if fighter2.attacking and fighter2.attack_box.colliderect(fighter1.rect): - if fighter1.hit_timer == 0: fighter1.take_damage(5) + if GAME_MODE == "PVP": + # P1 sit P2 + if fighter1.attacking and fighter1.attack_box.colliderect(fighter2.rect): + if fighter2.hit_timer == 0: + fighter2.take_damage(5) + # SKAŅA: P1 sitiena skaņa (pārbaude vai ir) + if sound_on and hit_sound: + hit_sound.play() - if fighter1.health <= 0 or fighter2.health <= 0: - STATE = "GAMEOVER" - winner = "PLAYER 1" if fighter2.health <= 0 else "PLAYER 2" + # P2 sit P1 + if fighter2.attacking and fighter2.attack_box.colliderect(fighter1.rect): + if fighter1.hit_timer == 0: + fighter1.take_damage(5) + # SKAŅA: P2 sitiena skaņa (pārbaude vai ir) + if sound_on and hit_sound: + hit_sound.play() + + if fighter1.health <= 0 or fighter2.health <= 0: + if fighter2.health <= 0: + p1_score += 1 + round_winner_name = "PLAYER 1" + else: + p2_score += 1 + round_winner_name = "PLAYER 2" + state_timer = pygame.time.get_ticks() + STATE = "ROUND_OVER" + + elif GAME_MODE == "BOSS" and boss: + targets = [fighter1, fighter2] + boss.ai_move(targets) + boss.update() + + # Spēlētāji sit Bosu + if fighter1.attacking and fighter1.attack_box.colliderect(boss.rect): + if boss.hit_timer == 0: + boss.take_damage(5) + if sound_on and hit_sound: hit_sound.play() + + if fighter2.attacking and fighter2.attack_box.colliderect(boss.rect): + if boss.hit_timer == 0: + boss.take_damage(5) + if sound_on and hit_sound: hit_sound.play() + + # Boss sit spēlētājus + if boss.attacking: + if boss.attack_box.colliderect(fighter1.rect): + if fighter1.hit_timer == 0: fighter1.take_damage(boss.damage) + if boss.attack_box.colliderect(fighter2.rect): + if fighter2.hit_timer == 0: fighter2.take_damage(boss.damage) + + if boss.health <= 0: + match_winner_name = "PLAYERS" + save_highscore("Players (Team)") + STATE = "GAMEOVER" + + if fighter1.health <= 0 and fighter2.health <= 0: + match_winner_name = "BOSS" + STATE = "GAMEOVER" - # Zīmēšana - bg_func = get_bg_function(SELECTED_BG) - bg_func(SCREEN) + draw_background(SCREEN, SELECTED_BG) + fighter1.draw(SCREEN) + fighter2.draw(SCREEN) + if GAME_MODE == "BOSS" and boss: + boss.draw(SCREEN) + + if GAME_MODE == "BOSS" and boss: + pygame.draw.rect(SCREEN, BLACK, (WIDTH//2 - 302, 18, 604, 34)) + pygame.draw.rect(SCREEN, RED, (WIDTH//2 - 300, 20, 600, 30)) + w = (boss.health / boss.max_health) * 600 + pygame.draw.rect(SCREEN, PURPLE, (WIDTH//2 - 300, 20, w, 30)) + pygame.draw.rect(SCREEN, WHITE, (WIDTH//2 - 300, 20, 600, 30), 2) + + pygame.draw.rect(SCREEN, BLACK, (20, HEIGHT - 60, 200, 20)) + pygame.draw.rect(SCREEN, fighter1.color_accent, (20, HEIGHT - 60, (fighter1.health/100)*200, 20)) + pygame.draw.rect(SCREEN, WHITE, (20, HEIGHT - 60, 200, 20), 2) + + pygame.draw.rect(SCREEN, BLACK, (WIDTH-220, HEIGHT - 60, 200, 20)) + pygame.draw.rect(SCREEN, fighter2.color_accent, (WIDTH-220, HEIGHT - 60, (fighter2.health/100)*200, 20)) + pygame.draw.rect(SCREEN, WHITE, (WIDTH-220, HEIGHT - 60, 200, 20), 2) + + else: + pygame.draw.rect(SCREEN, BLACK, (20, 20, 400, 40)) + pygame.draw.rect(SCREEN, RED, (20, 20, 400, 40)) + pygame.draw.rect(SCREEN, fighter1.color_accent, (20, 20, (fighter1.health/100)*400, 40)) + pygame.draw.rect(SCREEN, WHITE, (20, 20, 400, 40), 2) + + pygame.draw.rect(SCREEN, BLACK, (WIDTH-420, 20, 400, 40)) + pygame.draw.rect(SCREEN, RED, (WIDTH-420, 20, 400, 40)) + pygame.draw.rect(SCREEN, fighter2.color_accent, (WIDTH-420, 20, (fighter2.health/100)*400, 40)) + pygame.draw.rect(SCREEN, WHITE, (WIDTH-420, 20, 400, 40), 2) + + score_text = FONT_MED.render(f"{p1_score} - {p2_score}", True, WHITE) + SCREEN.blit(score_text, (WIDTH//2 - score_text.get_width()//2, 25)) + + elif STATE == "ROUND_OVER": + draw_background(SCREEN, SELECTED_BG) fighter1.draw(SCREEN) fighter2.draw(SCREEN) - # Health bars pygame.draw.rect(SCREEN, BLACK, (20, 20, 400, 40)) - pygame.draw.rect(SCREEN, RED, (20, 20, 400, 40)) - pygame.draw.rect(SCREEN, P1_COLOR, (20, 20, (fighter1.health/100)*400, 40)) + pygame.draw.rect(SCREEN, fighter1.color_accent, (20, 20, 400, 40)) pygame.draw.rect(SCREEN, WHITE, (20, 20, 400, 40), 2) pygame.draw.rect(SCREEN, BLACK, (WIDTH-420, 20, 400, 40)) - pygame.draw.rect(SCREEN, RED, (WIDTH-420, 20, 400, 40)) - pygame.draw.rect(SCREEN, P2_COLOR, (WIDTH-420, 20, (fighter2.health/100)*400, 40)) + pygame.draw.rect(SCREEN, fighter2.color_accent, (WIDTH-420, 20, 400, 40)) pygame.draw.rect(SCREEN, WHITE, (WIDTH-420, 20, 400, 40), 2) + score_text = FONT_MED.render(f"{p1_score} - {p2_score}", True, WHITE) + SCREEN.blit(score_text, (WIDTH//2 - score_text.get_width()//2, 25)) + + txt1 = FONT_MED.render(f"{round_winner_name} WINS!", True, YELLOW) + SCREEN.blit(txt1, (WIDTH//2 - txt1.get_width()//2, HEIGHT//2 - 50)) + + elapsed = pygame.time.get_ticks() - state_timer + + if elapsed > 2000: + if p1_score == 3 or p2_score == 3: + match_winner_name = "PLAYER 1" if p1_score == 3 else "PLAYER 2" + save_highscore(match_winner_name) + STATE = "GAMEOVER" + else: + current_round += 1 + fighter1.reset_round() + fighter2.reset_round() + state_timer = pygame.time.get_ticks() + STATE = "ROUND_START" + elif STATE == "GAMEOVER": SCREEN.fill(BLACK) - txt = FONT_BIG.render(f"{winner} WINS!", True, YELLOW) - restart = FONT_SMALL.render("Nospied [R] atgriezties uz izvēlni", True, WHITE) - SCREEN.blit(txt, (WIDTH//2 - txt.get_width()//2, HEIGHT//2 - 50)) - SCREEN.blit(restart, (WIDTH//2 - restart.get_width()//2, HEIGHT//2 + 50)) + if GAME_MODE == "BOSS": + if match_winner_name == "PLAYERS": + txt = FONT_BIG.render("PLAYERS WIN!", True, GREEN) + else: + txt = FONT_BIG.render("PLAYERS LOSE!", True, RED) + SCREEN.blit(txt, (WIDTH//2 - txt.get_width()//2, 150)) + else: + txt = FONT_BIG.render(f"{match_winner_name} WINS!", True, YELLOW) + SCREEN.blit(txt, (WIDTH//2 - txt.get_width()//2, 100)) + + hs_title = FONT_MED.render("HIGH SCORES", True, WHITE) + SCREEN.blit(hs_title, (WIDTH//2 - hs_title.get_width()//2, 200)) + + scores = load_highscores() + scores.reverse() + + y_offset = 260 + for i, score in enumerate(scores[:5]): + if score == match_winner_name: + color = YELLOW + else: + color = WHITE + + s_text = FONT_SMALL.render(f"{i+1}. {score}", True, color) + SCREEN.blit(s_text, (WIDTH//2 - s_text.get_width()//2, y_offset)) + y_offset += 35 + + restart = FONT_SMALL.render("Nospied [R] atgriezties uz izvelni", True, GRAY) + SCREEN.blit(restart, (WIDTH//2 - restart.get_width()//2, HEIGHT - 80)) + + # --- Zīmēt skaņas pogu --- + btn_color = GREEN if sound_on else RED + pygame.draw.rect(SCREEN, DARK_GRAY, mute_btn_rect) + pygame.draw.rect(SCREEN, btn_color, mute_btn_rect, 2) + + btn_label = "Skaņa: ON" if sound_on else "Skaņa: OFF" + text_surf = FONT_TINY.render(btn_label, True, btn_color) + text_x = mute_btn_rect.centerx - text_surf.get_width() // 2 + text_y = mute_btn_rect.centery - text_surf.get_height() // 2 + SCREEN.blit(text_surf, (text_x, text_y)) + + # --- Zīmēt kursoru --- + if CURSOR_IMG: + mouse_pos = pygame.mouse.get_pos() + SCREEN.blit(CURSOR_IMG, mouse_pos) pygame.display.update() pygame.quit() + sys.exit() if __name__ == "__main__": main() \ No newline at end of file diff --git a/highscores.txt b/highscores.txt new file mode 100644 index 0000000..dc0bd02 --- /dev/null +++ b/highscores.txt @@ -0,0 +1,12 @@ +PLAYER 2 +PLAYER 2 +PLAYER 2 +PLAYER 1 +PLAYER 2 +PLAYER 2 +PLAYER 1 +PLAYER 2 +Players (Team) +Players (Team) +Players (Team) +PLAYER 2 diff --git a/lofiewme-pixel-fantasia-355123.mp3 b/lofiewme-pixel-fantasia-355123.mp3 new file mode 100644 index 0000000..b104334 Binary files /dev/null and b/lofiewme-pixel-fantasia-355123.mp3 differ diff --git a/menupic1.png b/menupic1.png new file mode 100644 index 0000000..dafb457 Binary files /dev/null and b/menupic1.png differ diff --git a/menupic2.png b/menupic2.png new file mode 100644 index 0000000..7642e8b Binary files /dev/null and b/menupic2.png differ