Upload files to "/"

25.02 izmaiņas
Diāna Dorogova 2026-02-25 07:53:06 +00:00
parent f5475cf164
commit 742dc6e779
1 changed files with 500 additions and 119 deletions

585
game.py
View File

@ -2,6 +2,7 @@ import pygame
import random
import sys
import os
import math
# --- Inicializācija ---
pygame.init()
@ -23,6 +24,8 @@ 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):
@ -42,77 +45,97 @@ 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 ---
# ============================================================
# 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
(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"
"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
# 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",
"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."""
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)
# 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)
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 = pygame.font.SysFont('arial', 18)
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] - 30))
surf.blit(txt, (size[0]//2 - txt.get_width()//2, size[1] - 40))
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:
@ -123,10 +146,7 @@ def load_character_images():
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)
@ -134,38 +154,72 @@ def load_character_images():
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
})
chars_data.append({'game_img': game_img, 'icon': icon_img, 'color': color})
return chars_data
def load_image_safe(filename, fallback_color):
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((WIDTH, HEIGHT))
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 = {}
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),
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):
@ -179,7 +233,6 @@ class Button:
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))
@ -189,6 +242,20 @@ class Button:
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):
@ -196,14 +263,17 @@ class Fighter(pygame.sprite.Sprite):
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 # Grīdas līmenis
self.rect.bottom = HEIGHT - 50
self.vel_y = 0
self.speed = 7
self.jump_power = -20 # Nedaudz lielāks lecams augstums lielākam tēlam
self.jump_power = -20
self.gravity = 0.8
self.on_ground = False
@ -215,6 +285,16 @@ class Fighter(pygame.sprite.Sprite):
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']]:
@ -244,7 +324,6 @@ class Fighter(pygame.sprite.Sprite):
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:
@ -253,21 +332,13 @@ class Fighter(pygame.sprite.Sprite):
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
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)
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
@ -276,6 +347,88 @@ class Fighter(pygame.sprite.Sprite):
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])
@ -289,35 +442,47 @@ class DialogueManager:
self.active = False
self.timer = 0
def start(self):
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
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)
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))
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
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(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")
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 = [
@ -332,10 +497,19 @@ def main():
]
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
winner = "PLAYER 1"
boss = None
p1_score = 0
p2_score = 0
current_round = 1
round_winner_name = ""
match_winner_name = ""
state_timer = 0
run = True
while run:
@ -348,30 +522,43 @@ def main():
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 (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)
@ -389,12 +576,15 @@ def main():
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
fighter1 = Fighter(200, 300, CHARACTERS[P1_CHAR_INDEX], True, controls_p1)
fighter2 = Fighter(800, 300, CHARACTERS[P2_CHAR_INDEX], False, controls_p2)
STATE = "GAME"
state_timer = pygame.time.get_ticks()
STATE = "ROUND_START"
elif STATE == "GAME":
if event.type == pygame.KEYDOWN:
@ -405,42 +595,88 @@ def main():
if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
STATE = "MENU"
# --- Zīmēšana ---
# --- 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))
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 == "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)
# 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))
@ -452,7 +688,6 @@ def main():
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))
@ -477,6 +712,41 @@ def main():
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()
@ -485,21 +755,70 @@ def main():
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"
winner = "PLAYER 1" if fighter2.health <= 0 else "PLAYER 2"
draw_background(SCREEN, SELECTED_BG)
fighter1.draw(SCREEN)
fighter2.draw(SCREEN)
if GAME_MODE == "BOSS" and boss:
boss.draw(SCREEN)
# Health bars (saglabāts vecais stils)
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))
@ -510,12 +829,74 @@ def main():
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)
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))
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()