import pygame import random import sys import os # --- 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) # --- 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" # ============================================================ # --- TĒLU UN FONA DATU BĀZES --- # ============================================================ # Krāsu palešu fallback attēliem FALLBACK_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 ] 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" ] P1_CHAR_INDEX = 0 P2_CHAR_INDEX = 1 # Fona faili (failu nosaukumi) 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" } # Failu ielādes funkcijas def create_placeholder_image(color, size=(80, 160), text=""): """Izveido vienkāršu attēlu, ja fails nav atrasts.""" surf = pygame.Surface(size) surf.fill(color) pygame.draw.rect(surf, BLACK, (0, 0, size[0], size[1]), 2) # Galva (piemērota lielākam izmēram) 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) # Acis eye_y = head_rect.y + head_h // 3 pygame.draw.circle(surf, BLACK, (int(head_rect.centerx - head_w//5), int(eye_y)), 4) pygame.draw.circle(surf, BLACK, (int(head_rect.centerx + head_w//5), int(eye_y)), 4) if text: font = pygame.font.SysFont('arial', 18) txt = font.render(text, True, WHITE) surf.blit(txt, (size[0]//2 - txt.get_width()//2, size[1] - 30)) return surf def load_character_images(): chars_data = [] # === IZMĒRU IESTATĪJUMI (ŠEIT MAINĪTS) === 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: # Ja faila nav, veidojam lielu "placeholder" game_img = create_placeholder_image(color, SPRITE_SIZE, f"T{i+1}") # Ikonas placeholder 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_image_safe(filename, fallback_color): try: if os.path.exists(filename): img = pygame.image.load(filename) img = pygame.transform.scale(img, (WIDTH, HEIGHT)) return img else: raise FileNotFoundError except: surf = pygame.Surface((WIDTH, HEIGHT)) surf.fill(fallback_color) return surf # --- RESURSU IELĀDE --- CHARACTERS = load_character_images() bg_images = {} for key, path in BG_FILES.items(): # Vienkāršotas krāsas fallback 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)} bg_images[key] = load_image_safe(path, cols.get(key, GRAY)) # --- 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 # --- 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.rect = self.image.get_rect() self.rect.center = (x, y) self.rect.bottom = HEIGHT - 50 # Grīdas līmenis self.vel_y = 0 self.speed = 7 self.jump_power = -20 # Nedaudz lielāks lecams augstums lielākam tēlam 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 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 # Uzbrukuma kaste pieregulēta lielākam tēlam 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): if self.facing_right: img_to_draw = self.image else: img_to_draw = pygame.transform.flip(self.image, True, 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) 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 # --- 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): self.active = True self.timer = pygame.time.get_ticks() self.current_text = random.choice(self.lines) def draw(self, surface): if not self.active: return box_rect = pygame.Rect(WIDTH//2 - 300, HEIGHT//2 - 50, 600, 100) pygame.draw.rect(surface, BLACK, box_rect) pygame.draw.rect(surface, WHITE, box_rect, 4) 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)) sub_surf = FONT_SMALL.render("Nospiediet [SPACE] lai saktu", True, WHITE) surface.blit(sub_surf, (box_rect.centerx - sub_surf.get_width()//2, box_rect.bottom + 10)) # --- Galvenā Spēle --- def main(): global STATE, P1_CHAR_INDEX, P2_CHAR_INDEX, SELECTED_BG 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() menu_buttons = [ Button(WIDTH//2 - 100, 250, 200, 50, "Sakt Cinu", BLUE, RED, "START"), Button(WIDTH//2 - 100, 320, 200, 50, "Telu Izvele", BLUE, RED, "CHARS"), Button(WIDTH//2 - 100, 390, 200, 50, "Fona Izvele", BLUE, RED, "BG"), Button(WIDTH//2 - 100, 460, 200, 50, "Iziet", RED, YELLOW, "QUIT") ] 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") fighter1 = None fighter2 = None winner = "PLAYER 1" 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": dialogue_mgr.start() 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 STATE == "CHAR_SELECT": # P1 izvēle (Augšējā rinda) 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 (Apakšējā rinda) 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 == "DIALOGUE": if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: dialogue_mgr.active = False fighter1 = Fighter(200, 300, CHARACTERS[P1_CHAR_INDEX], True, controls_p1) fighter2 = Fighter(800, 300, CHARACTERS[P2_CHAR_INDEX], False, controls_p2) STATE = "GAME" 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 --- if STATE == "MENU": SCREEN.fill(BLACK) 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)) sub_text = "- ULTIMATE EDITION -" sub_surf = FONT_SMALL.render(sub_text, True, WHITE) SCREEN.blit(sub_surf, (WIDTH//2 - sub_surf.get_width()//2, 130)) 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 == "CHAR_SELECT": SCREEN.fill(DARK_GRAY) # Teksts title1 = FONT_SMALL.render("IZVELIES TELU", True, WHITE) SCREEN.blit(title1, (WIDTH//2 - title1.get_width()//2, 30)) title2 = FONT_TINY.render("(Uzspied uz ikonas)", True, GRAY) SCREEN.blit(title2, (WIDTH//2 - title2.get_width()//2, 60)) # Ikonu izmēri un novietojums icon_w = 100 gap = 10 total_w = len(CHARACTERS) * icon_w + (len(CHARACTERS)-1) * gap start_x = (WIDTH - total_w) // 2 # P1 Zīmēšana 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 Zīmēšana 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 == "GAME": keys = pygame.key.get_pressed() 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 fighter1.health <= 0 or fighter2.health <= 0: STATE = "GAMEOVER" winner = "PLAYER 1" if fighter2.health <= 0 else "PLAYER 2" draw_background(SCREEN, SELECTED_BG) fighter1.draw(SCREEN) fighter2.draw(SCREEN) # Health bars (saglabāts vecais stils) 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) elif STATE == "GAMEOVER": SCREEN.fill(BLACK) txt = FONT_BIG.render(f"{winner} WINS!", True, YELLOW) restart = FONT_SMALL.render("Nospied [R] atgriezties uz izvelni", 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)) pygame.display.update() pygame.quit() sys.exit() if __name__ == "__main__": main()