import pygame import random import sys # --- 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) BROWN = (139, 69, 19) GREEN = (50, 200, 50) CYAN = (0, 255, 255) PURPLE = (160, 32, 240) # Pieejamās raksturu krāsas 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 ] # --- Fonti (ar rezerves variantu) --- def get_font(name, size): try: return pygame.font.Font(name, size) except FileNotFoundError: # Ja fonts nav atrasts, izmanto noklusējuma sistēmas fontu 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 (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 # --- Fona Ģenerators (Lai novērstu mirgošanu) --- BG_ELEMENTS = [] def generate_bg_elements(bg_name): global BG_ELEMENTS BG_ELEMENTS = [] if bg_name == "CITY": for i in range(5): w = random.randint(80, 150) h = random.randint(200, 400) x = i * (WIDTH // 5) + 20 BG_ELEMENTS.append({'rect': pygame.Rect(x, HEIGHT - 50 - h, w-10, h)}) elif bg_name == "FOREST": for i in range(8): x = i * (WIDTH // 8) + 40 BG_ELEMENTS.append({'x': x}) # Inicializējam pirmo reizi generate_bg_elements("CITY") # --- UI Klases --- class Button: def __init__(self, x, y, w, h, text, color, hover_color, action_code): # Rect tiek izmantots tikai klikšķu noteikšanai (invisible hitbox) self.rect = pygame.Rect(x, y, w, h) self.text = text self.color = color # Teksta krāsa (normāla) self.hover_color = hover_color # Teksta krāsa (pele virsū) self.action_code = action_code def draw(self, surface): mouse_pos = pygame.mouse.get_pos() is_hovered = self.rect.collidepoint(mouse_pos) # Izvēlamies krāsu atkarībā no peles pozīcijas current_color = self.hover_color if is_hovered else self.color # Taisnstūrus ZĪMĒT NEVARAM (dzēsts pēc pieprasījuma) # pygame.draw.rect(surface, current_color, self.rect) # Zīmējam tikai tekstu, kas ir centrēts rect iekšpusē 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, color, facing_right, controls): super().__init__() self.original_color = color self.color = color self.rect = pygame.Rect(x, y, 50, 100) self.vel_y = 0 self.speed = 7 self.jump_power = -18 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 if self.facing_right: self.attack_box = pygame.Rect(self.rect.right, self.rect.y + 20, 60, 50) else: self.attack_box = pygame.Rect(self.rect.left - 60, self.rect.y + 20, 60, 50) 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 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)) 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ēšanas Funkcijas --- def draw_city(surface): surface.fill((20, 30, 50)) # Nakts debesis pygame.draw.circle(surface, (200, 200, 200), (WIDTH//2, 100), 60) # Mēness # Zīmējam iepriekš ģenerētās ēkas for elem in BG_ELEMENTS: pygame.draw.rect(surface, (10, 10, 20), elem['rect']) pygame.draw.rect(surface, BROWN, (0, HEIGHT - 50, WIDTH, 50)) # Zeme 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 # Zīmējam iepriekš ģenerētos kokus for elem in BG_ELEMENTS: x = elem['x'] # 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 # --- 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 # Kaste 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) # 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)) # --- Galvenā Spēle --- def main(): global STATE, P1_COLOR, P2_COLOR, SELECTED_BG, BG_ELEMENTS # Kontroles 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() # Izveidojam pogas (Bez taisnstūriem, teksta krāsas) # Zila krāsa parasti, Sarkana izceļot (pelei virsū) 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") # Iziet ir sarkans, kļūst dzeltens ] # Šeit arī nomainām krāsas, lai būtu redzams uz fona (jo rect vairs nav) bg_buttons = [ Button(200, 300, 150, 100, "CITY", WHITE, YELLOW, "CITY"), Button(425, 300, 150, 100, "FOREST", WHITE, YELLOW, "FOREST"), Button(650, 300, 150, 100, "DOJO", WHITE, YELLOW, "DOJO"), Button(WIDTH//2 - 100, 450, 200, 50, "Atpakal", GRAY, WHITE, "BACK") ] back_btn = Button(20, 20, 100, 40, "Atpakal", GRAY, WHITE, "BACK") # Spēlētāji fighter1 = None fighter2 = None winner = "PLAYER 1" # Noklusējuma vērtība run = True while run: CLOCK.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False # Pogu apstrāde atkarībā no stāvokļa 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 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 # P2 izvēle 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 if back_btn.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 generate_bg_elements(SELECTED_BG) # Ģenerējam jaunu fonu 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" 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ēšanas Loģika un Update --- if STATE == "MENU": SCREEN.fill(BLACK) # --- LOGOTIPS (Street Fighter stils) --- title_text = "PIXEL KOMBAT" # Ēna (Sarkana) shadow_text = FONT_BIG.render(title_text, True, (180, 0, 0)) SCREEN.blit(shadow_text, (WIDTH//2 - shadow_text.get_width()//2 + 3, 53)) # Galvenais teksts (Dzeltena) main_text = FONT_BIG.render(title_text, True, YELLOW) SCREEN.blit(main_text, (WIDTH//2 - main_text.get_width()//2, 50)) # Apakšvirsraksts 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)) # --- POGAS (Tikai teksts) --- for btn in menu_buttons: btn.draw(SCREEN) # --- APAKŠĒJĀ INFORMĀCIJA --- # Copyright cp_text = "© PIXEL KOMBAT 2024" cp_surf = FONT_TINY.render(cp_text, True, WHITE) SCREEN.blit(cp_surf, (WIDTH//2 - cp_surf.get_width()//2, HEIGHT - 30)) # Credits (Labajā pusē) credit_text = "CREDIT 01" credit_surf = FONT_SMALL.render(credit_text, True, YELLOW) SCREEN.blit(credit_surf, (WIDTH - 180, HEIGHT - 30)) elif STATE == "CHAR_SELECT": SCREEN.fill(DARK_GRAY) title = FONT_MED.render("IZVELIES TELU", True, WHITE) SCREEN.blit(title, (WIDTH//2 - title.get_width()//2, 50)) 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) # 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) back_btn.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, 50)) for btn in bg_buttons: btn.draw(SCREEN) elif STATE == "DIALOGUE": get_bg_function(SELECTED_BG)(SCREEN) dialogue_mgr.draw(SCREEN) 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 fighter1.health <= 0 or fighter2.health <= 0: STATE = "GAMEOVER" winner = "PLAYER 1" if fighter2.health <= 0 else "PLAYER 2" # Zīmēšana bg_func = get_bg_function(SELECTED_BG) bg_func(SCREEN) 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, 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, 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()