import pygame import random import sys import os import math # --- Inicializācija --- pygame.init() # Ekrāna iestatījumi WIDTH, HEIGHT = 1024, 576 SCREEN = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Pixel Kombat: Ultimate") CLOCK = pygame.time.Clock() # --- KRĀSAS --- WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) BLUE = (0, 0, 255) GRAY = (50, 50, 50) DARK_GRAY = (20, 20, 20) YELLOW = (255, 215, 0) GREEN = (50, 200, 50) CYAN = (0, 255, 255) PURPLE = (160, 32, 240) 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" # ============================================================ # --- HIGH SCORE FUNKCIJAS --- # ============================================================ 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/first_char.png", "characters/second_char.png", "characters/third_char.png", "characters/forth_char.png", "characters/fifth_char.png", "characters/sixth_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" } def create_placeholder_image(color, size=(80, 160), text="", is_boss=False): surf = pygame.Surface(size) surf.fill(color) pygame.draw.rect(surf, BLACK, (0, 0, size[0], size[1]), 2) head_w = size[0] * 0.4 head_h = size[1] * 0.3 head_rect = pygame.Rect(size[0]//2 - head_w//2, 10, head_w, head_h) pygame.draw.rect(surf, (200, 200, 200), head_rect) pygame.draw.rect(surf, BLACK, head_rect, 2) eye_y = head_rect.y + head_h // 3 eye_size = 6 if is_boss else 4 pygame.draw.circle(surf, BLACK, (int(head_rect.centerx - head_w//5), int(eye_y)), eye_size) pygame.draw.circle(surf, BLACK, (int(head_rect.centerx + head_w//5), int(eye_y)), eye_size) if is_boss: horn_scale = size[0] // 10 pygame.draw.polygon(surf, RED, [ (head_rect.left, head_rect.top), (head_rect.left - horn_scale, head_rect.top - horn_scale*2), (head_rect.left + horn_scale, head_rect.top) ]) pygame.draw.polygon(surf, RED, [ (head_rect.right, head_rect.top), (head_rect.right + horn_scale, head_rect.top - horn_scale*2), (head_rect.right - horn_scale, head_rect.top) ]) if text: font_size = 24 if is_boss else 18 font = pygame.font.SysFont('arial', font_size) txt = font.render(text, True, WHITE) surf.blit(txt, (size[0]//2 - txt.get_width()//2, size[1] - 40)) return surf 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 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 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 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 # --- RESURSU IELĀDE --- 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)) 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. PNG IELĀDE --- try: 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: BOOM_IMG = pygame.Surface((80, 80)); BOOM_IMG.fill(YELLOW) BOOM_IMG_LARGE = pygame.Surface((160, 160)); BOOM_IMG_LARGE.fill(ORANGE) # --- UI Klases --- class Button: def __init__(self, x, y, w, h, text, color, hover_color, action_code): self.rect = pygame.Rect(x, y, w, h) self.text = text self.color = color self.hover_color = hover_color self.action_code = action_code def draw(self, surface): mouse_pos = pygame.mouse.get_pos() 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): if event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1 and self.rect.collidepoint(event.pos): return True return False # --- Palīgfunkcija Instrukciju pogām --- def draw_key_visual(surface, x, y, w, h, key_text, action_text, color): # Zīmē pogas rāmi pygame.draw.rect(surface, color, (x, y, w, h), 2) pygame.draw.rect(surface, DARK_GRAY, (x+4, y+4, w-8, h-8)) # Teksts uz pogas txt_surf = FONT_SMALL.render(key_text, True, WHITE) surface.blit(txt_surf, (x + w//2 - txt_surf.get_width()//2, y + 10)) # Paskaidrojums zem pogas desc_surf = FONT_TINY.render(action_text, True, GRAY) surface.blit(desc_surf, (x + w//2 - desc_surf.get_width()//2, y + h + 5)) # --- Klase Spēlētājam --- class Fighter(pygame.sprite.Sprite): def __init__(self, x, y, char_data, facing_right, controls): super().__init__() 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 self.rect = self.image.get_rect() self.rect.center = (x, y) self.rect.bottom = HEIGHT - 50 self.vel_y = 0 self.speed = 7 self.jump_power = -20 self.gravity = 0.8 self.on_ground = False self.facing_right = facing_right self.controls = controls self.attacking = False self.attack_cooldown = 0 self.attack_box = pygame.Rect(0, 0, 0, 0) self.health = 100 self.hit_timer = 0 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 def move(self, keys): dx = 0 if keys[self.controls['left']]: dx = -self.speed self.facing_right = False if keys[self.controls['right']]: dx = self.speed self.facing_right = True self.rect.x += dx if self.rect.left < 0: self.rect.left = 0 if self.rect.right > WIDTH: self.rect.right = WIDTH if keys[self.controls['jump']] and self.on_ground: self.vel_y = self.jump_power self.on_ground = False 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 = 20 if self.facing_right: self.attack_box = pygame.Rect(self.rect.right, self.rect.y + 40, 80, 80) else: self.attack_box = pygame.Rect(self.rect.left - 80, self.rect.y + 40, 80, 80) 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(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, self.attack_box) def take_damage(self, amount): self.health -= amount self.hit_timer = 10 self.vel_y = -5 if self.rect.centerx < WIDTH // 2: self.rect.x -= 20 else: self.rect.x += 20 # --- Klase Bossam --- 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 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(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 # --- Fona Zīmēšana --- 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.current_text = random.choice(self.lines) self.active = False self.timer = 0 def start(self, is_boss=False): self.active = True self.timer = pygame.time.get_ticks() 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 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) 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_CHAR_INDEX, P2_CHAR_INDEX, SELECTED_BG, GAME_MODE controls_p1 = {'left': pygame.K_a, 'right': pygame.K_d, 'jump': pygame.K_w, 'attack': pygame.K_SPACE} controls_p2 = {'left': pygame.K_LEFT, 'right': pygame.K_RIGHT, 'jump': pygame.K_UP, 'attack': pygame.K_RETURN} dialogue_mgr = DialogueManager() # Pogas (novietotas centrā, ņemot vērā malu bildes) btn_x = WIDTH//2 - 100 menu_buttons = [ Button(btn_x, 180, 200, 50, "PvP", BLUE, RED, "START_PVP"), Button(btn_x, 240, 200, 50, "Cina ar Bossu", PURPLE, ORANGE, "START_BOSS"), Button(btn_x, 300, 200, 50, "Telu Izvele", BLUE, RED, "CHARS"), Button(btn_x, 360, 200, 50, "Fona Izvele", BLUE, RED, "BG"), Button(btn_x, 420, 200, 50, "Kontroles", GREEN, YELLOW, "INSTRUCTIONS"), ] bg_buttons = [ Button(150, 200, 200, 50, "Beach", WHITE, YELLOW, "BEACH"), Button(412, 200, 200, 50, "Evening St.", WHITE, YELLOW, "EVENINGSTREET"), Button(674, 200, 200, 50, "Market", WHITE, YELLOW, "MARKET"), Button(150, 280, 200, 50, "Restaurant", WHITE, YELLOW, "RESTAURANT"), Button(412, 280, 200, 50, "Sakura St.", WHITE, YELLOW, "SAKURASTREET"), Button(674, 280, 200, 50, "Ship", WHITE, YELLOW, "SHIP"), Button(WIDTH//2 - 100, 360, 200, 50, "Street Markets", WHITE, YELLOW, "STREETMARKETS"), Button(WIDTH//2 - 100, 450, 200, 50, "Atpakal", GRAY, WHITE, "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") fighter1 = None fighter2 = None boss = None p1_score = 0 p2_score = 0 current_round = 1 round_winner_name = "" match_winner_name = "" state_timer = 0 run = True while run: CLOCK.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if STATE == "MENU": for btn in menu_buttons: if btn.is_clicked(event): 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 == "INSTRUCTIONS": STATE = "INSTRUCTIONS" elif STATE == "CHAR_SELECT": 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 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_chars.is_clicked(event): STATE = "MENU" elif STATE == "BG_SELECT": for btn in bg_buttons: if btn.is_clicked(event): if btn.action_code == "BACK": 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 state_timer = pygame.time.get_ticks() STATE = "ROUND_START" elif STATE == "GAME": if event.type == pygame.KEYDOWN: if event.key == fighter1.controls['attack']: fighter1.attack() if event.key == fighter2.controls['attack']: fighter2.attack() elif STATE == "GAMEOVER": if event.type == pygame.KEYDOWN and event.key == pygame.K_r: STATE = "MENU" # --- Zīmēšana un Loģika --- if STATE == "MENU": SCREEN.fill(BLACK) # Zīmējam malu bildes (no augšas līdz lejai) SCREEN.blit(menupic1, (0, 0)) # Kreisā puse SCREEN.blit(menupic2, (WIDTH - MENU_PIC_WIDTH, 0)) # Labā puse # Virsraksts centrā 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) # Virsraksts "KONTROLES" pašā augšā title = FONT_BIG.render("KONTROLES", True, YELLOW) SCREEN.blit(title, (WIDTH//2 - title.get_width()//2, 30)) # --- Izkārtojuma mainīgie --- # Centri katrai kolonnai (simetriski attiecībā pret ekrāna centru) p1_center_x = WIDTH // 2 - 200 p2_center_x = WIDTH // 2 + 200 # Y pozīcijas (palielinātas atstarpes) title_y = 170 # Kur sākas "PLAYER X" teksts key_row1_y = 240 # Augšējā poga (W / UP) key_row2_y = 320 # Vidējās pogas (A,D / LEFT, RIGHT) key_row3_y = 420 # Apakšējā poga (SPACE / ENTER) # --- PLAYER 1 (Kreisā puse) --- p1_title = FONT_MED.render("PLAYER 1", True, BLUE) # Centrējam tekstu virs pogu kolonnas SCREEN.blit(p1_title, (p1_center_x - p1_title.get_width()//2, title_y)) # W (Jump) - centrēta draw_key_visual(SCREEN, p1_center_x - 35, key_row1_y, 70, 50, "W", "LEKT", BLUE) # A (Left) - pa kreisi no centra draw_key_visual(SCREEN, p1_center_x - 35 - 80, key_row2_y, 70, 50, "A", "KREISI", BLUE) # D (Right) - pa labi no centra draw_key_visual(SCREEN, p1_center_x - 35 + 80, key_row2_y, 70, 50, "D", "LABI", BLUE) # SPACE (Hit) - plata poga apakšā, centrēta space_w = 200 draw_key_visual(SCREEN, p1_center_x - space_w//2, key_row3_y, space_w, 50, "SPACE", "SIT", RED) # --- PLAYER 2 (Labā puse) --- p2_title = FONT_MED.render("PLAYER 2", True, RED) # Centrējam tekstu virs pogu kolonnas SCREEN.blit(p2_title, (p2_center_x - p2_title.get_width()//2, title_y)) # UP (Jump) draw_key_visual(SCREEN, p2_center_x - 35, key_row1_y, 70, 50, "UP", "LEKT", RED) # LEFT (Left) draw_key_visual(SCREEN, p2_center_x - 35 - 80, key_row2_y, 70, 50, "LEFT", "KREISI", RED) # RIGHT (Right) draw_key_visual(SCREEN, p2_center_x - 35 + 80, key_row2_y, 70, 50, "RIGHT", "LABI", RED) # ENTER (Hit) 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)) 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)) 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) 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_chars.draw(SCREEN) elif STATE == "BG_SELECT": SCREEN.fill(BLACK) 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": 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() fighter1.move(keys) fighter2.move(keys) fighter1.update() fighter2.update() if GAME_MODE == "PVP": 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 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() if fighter1.attacking and fighter1.attack_box.colliderect(boss.rect): if boss.hit_timer == 0: boss.take_damage(5) if fighter2.attacking and fighter2.attack_box.colliderect(boss.rect): if boss.hit_timer == 0: boss.take_damage(5) 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" 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) 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) 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) 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)) pygame.display.update() pygame.quit() sys.exit() if __name__ == "__main__": main()