Compare commits

..

No commits in common. "ae308f594602f0ee461b9fd79de13b6d65af9211" and "70d88d20e3dd07144787852d81257440222c1f66" have entirely different histories.

22 changed files with 94 additions and 118 deletions

View File

Before

Width:  |  Height:  |  Size: 481 B

After

Width:  |  Height:  |  Size: 481 B

View File

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 485 B

View File

Before

Width:  |  Height:  |  Size: 469 B

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

View File

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

View File

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

View File

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 424 B

View File

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

View File

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 203 B

View File

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 221 B

BIN
images/walk.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

212
main.py
View File

@ -2,7 +2,10 @@ import pygame
import sys import sys
pygame.init() pygame.init()
pygame.mixer.init()
# =====================================================
# НАСТРОЙКИ
# =====================================================
WIDTH, HEIGHT = 1000, 800 WIDTH, HEIGHT = 1000, 800
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT)) SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
@ -10,68 +13,65 @@ pygame.display.set_caption("Goblin & Knight")
CLOCK = pygame.time.Clock() CLOCK = pygame.time.Clock()
BLACK = (0, 0, 0) BLACK = (0, 0, 0)
GRAVITY = 0.9 GRAVITY = 1
GROUND_Y = HEIGHT - 60
FPS = 60 # =====================================================
# ЗАГРУЗКА ФОНОВ
# =====================================================
BACKGROUND = pygame.image.load("images/back.png") BACKGROUND = pygame.image.load("images/back.png")
BACK_MAIN = pygame.image.load("images/back_main.jpg") BACK_MAIN = pygame.image.load("images/back_main.jpg")
BACK_MAIN = pygame.transform.scale(BACK_MAIN, (WIDTH, HEIGHT)) BACK_MAIN = pygame.transform.scale(BACK_MAIN, (WIDTH, HEIGHT))
ь
BG_MUSIC = None
try:
BG_MUSIC = pygame.mixer.music
pygame.mixer.music.load('music/theme.mp3')
pygame.mixer.music.set_volume(0.5)
except Exception:
BG_MUSIC = None
FONT = pygame.font.SysFont(None, 32) # =====================================================
# ФУНКЦИЯ ВЫРЕЗКИ СПРАЙТОВ
# =====================================================
score_goblin = 0 def get_image(sheet, frame_x, frame_y, width, height, scale, color):
score_knight = 0 image = pygame.Surface((width, height)).convert_alpha()
image.blit(sheet, (0, 0), (frame_x * width, frame_y * height, width, height))
paused = False image = pygame.transform.scale(image, (width * scale, height * scale))
image.set_colorkey(color)
return image
# =====================================================
# КЛАСС ИГРОКА
# =====================================================
class Player: class Player:
def __init__(self, x, y, sprites, scale, controls): def __init__(self, x, y, sprite_sheet, frame_size, scale, controls):
self.start_x = x self.start_x = x
self.start_y = y self.start_y = y
self.x = float(x) self.x = x
self.y = float(y) self.y = y
self.y_velocity = 0.0 self.y_velocity = 0
self.jump_power = 18 self.jump_power = 20
self.jumping = False self.jumping = False
self.facing_right = True self.facing_right = True
self.moving = False self.moving = False
self.speed = 5.5
self.controls = controls self.controls = controls
self.anim_counter = 0 self.anim_counter = 0
self.ANIM_SPEED = 8 self.ANIM_SPEED = 8
w, h = frame_size
self.stand = pygame.image.load(sprites["stand"]).convert_alpha() # Анимации
self.walk_left = pygame.image.load(sprites["walk_left"]).convert_alpha() self.stand = get_image(sprite_sheet, 0, 0, w, h, scale, BLACK)
self.walk_right = pygame.image.load(sprites["walk_right"]).convert_alpha() self.walk1 = get_image(sprite_sheet, 1, 0, w, h, scale, BLACK)
self.jump_img = pygame.image.load(sprites["jump"]).convert_alpha() self.walk2 = get_image(sprite_sheet, 2, 0, w, h, scale, BLACK)
self.jump_img = get_image(sprite_sheet, 3, 0, w, h, scale, BLACK)
self.stand = pygame.transform.scale(self.stand, (int(self.stand.get_width() * scale), int(self.stand.get_height() * scale)))
self.walk_left = pygame.transform.scale(self.walk_left, (int(self.walk_left.get_width() * scale), int(self.walk_left.get_height() * scale)))
self.walk_right = pygame.transform.scale(self.walk_right, (int(self.walk_right.get_width() * scale), int(self.walk_right.get_height() * scale)))
self.jump_img = pygame.transform.scale(self.jump_img, (int(self.jump_img.get_width() * scale), int(self.jump_img.get_height() * scale)))
self.surface = self.stand self.surface = self.stand
self.rect = self.surface.get_rect(midbottom=(self.x, self.y)) self.rect = self.surface.get_rect(center=(self.x, self.y))
# -------------------------
# СБРОС ПЕРСОНАЖА
# -------------------------
def reset(self): def reset(self):
self.x = self.start_x self.x = self.start_x
self.y = self.start_y self.y = self.start_y
@ -80,73 +80,82 @@ class Player:
self.moving = False self.moving = False
self.anim_counter = 0 self.anim_counter = 0
self.facing_right = True self.facing_right = True
self.rect = self.surface.get_rect(midbottom=(self.x, self.y)) self.rect = self.surface.get_rect(center=(self.x, self.y))
# -------------------------
# УПРАВЛЕНИЕ
# -------------------------
def handle_input(self, keys): def handle_input(self, keys):
self.moving = False self.moving = False
if keys[self.controls["right"]]: if keys[self.controls["right"]]:
self.x += self.speed self.x += 5
self.facing_right = True self.facing_right = True
self.moving = True self.moving = True
if keys[self.controls["left"]]: if keys[self.controls["left"]]:
self.x -= self.speed self.x -= 5
self.facing_right = False self.facing_right = False
self.moving = True self.moving = True
if keys[self.controls["jump"]] and not self.jumping: if keys[self.controls["jump"]] and not self.jumping:
self.jumping = True self.jumping = True
self.y_velocity = -self.jump_power self.y_velocity = self.jump_power
# Ограничение по экрану
if self.x < 0: if self.x < 0:
self.x = 0 self.x = 0
if self.x > WIDTH: if self.x > WIDTH:
self.x = WIDTH self.x = WIDTH
# -------------------------
# ГРАВИТАЦИЯ
# -------------------------
def apply_gravity(self): def apply_gravity(self):
self.y_velocity += GRAVITY self.y_velocity -= GRAVITY
self.y += self.y_velocity self.y -= self.y_velocity
if self.y >= GROUND_Y: if self.y >= HEIGHT:
self.y = GROUND_Y self.y = HEIGHT
self.y_velocity = 0 self.y_velocity = 0
self.jumping = False self.jumping = False
# -------------------------
# АНИМАЦИЯ
# -------------------------
def update_animation(self): def update_animation(self):
if self.jumping: if self.jumping:
self.surface = self.jump_img self.surface = self.jump_img
elif self.moving: elif self.moving:
self.anim_counter += 1 self.anim_counter += 1
frame = (self.anim_counter // self.ANIM_SPEED) % 2 frame = (self.anim_counter // self.ANIM_SPEED) % 2
self.surface = self.walk_left if frame == 0 else self.walk_right self.surface = self.walk1 if frame == 0 else self.walk2
else: else:
self.surface = self.stand self.surface = self.stand
if not self.facing_right: if not self.facing_right:
self.surface = pygame.transform.flip(self.surface, True, False) self.surface = pygame.transform.flip(self.surface, True, False)
self.rect = self.surface.get_rect(midbottom=(int(self.x), int(self.y))) self.rect = self.surface.get_rect(center=(self.x, self.y))
# -------------------------
# ОТРИСОВКА
# -------------------------
def draw(self, screen): def draw(self, screen):
screen.blit(self.surface, self.rect) screen.blit(self.surface, self.rect)
# =====================================================
# ЗАГРУЗКА СПРАЙТОВ
# =====================================================
goblin_sheet = pygame.image.load("images/GoblinWorker/GoblinWorker.png").convert_alpha()
knight_sheet = pygame.image.load("images/sprites/knight.png").convert_alpha()
goblin = Player( goblin = Player(
200, GROUND_Y, 200, 800,
{ goblin_sheet,
"stand": "images/GoblinWorker/spritePics/stand_gob.png", (48, 48),
"walk_left": "images/GoblinWorker/spritePics/walkleft.png",
"walk_right": "images/GoblinWorker/spritePics/walkright.png",
"jump": "images/GoblinWorker/spritePics/Jump.png"
},
3, 3,
{ {
"left": pygame.K_a, "left": pygame.K_a,
@ -156,13 +165,9 @@ goblin = Player(
) )
knight = Player( knight = Player(
500, GROUND_Y, 500, 800,
{ knight_sheet,
"stand": "images/sprites/knight.png", (32, 32),
"walk_left": "images/sprites/knight.png",
"walk_right": "images/sprites/knight.png",
"jump": "images/sprites/knight.png"
},
3, 3,
{ {
"left": pygame.K_KP4, "left": pygame.K_KP4,
@ -171,7 +176,9 @@ knight = Player(
} }
) )
# =====================================================
# ОБЪЕКТЫ УРОВНЯ
# =====================================================
door_image = pygame.image.load("images/door.png") door_image = pygame.image.load("images/door.png")
door_rect = door_image.get_rect(center=(800, 700)) door_rect = door_image.get_rect(center=(800, 700))
@ -179,14 +186,19 @@ door_rect = door_image.get_rect(center=(800, 700))
button_play = pygame.image.load("images/play_button.png") button_play = pygame.image.load("images/play_button.png")
button_rect = button_play.get_rect(center=(500, 400)) button_rect = button_play.get_rect(center=(500, 400))
# =====================================================
# ФУНКЦИЯ РЕСТАРТА
# =====================================================
def restart_level(): def restart_level():
goblin.reset() goblin.reset()
knight.reset() knight.reset()
# =====================================================
# GAME LOOP
# =====================================================
level = 0 level = 0
level_start_time = None
while True: while True:
@ -194,85 +206,49 @@ while True:
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
pygame.quit() pygame.quit()
sys.exit() sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE and level == 1:
paused = not paused
if event.key == pygame.K_r:
restart_level()
level = 0
keys = pygame.key.get_pressed() keys = pygame.key.get_pressed()
mouse_pos = pygame.mouse.get_pos() mouse_pos = pygame.mouse.get_pos()
SCREEN.fill((0, 0, 0)) SCREEN.fill((0, 0, 0))
# ================= MENU =================
if level == 0: if level == 0:
SCREEN.blit(BACK_MAIN, (0, 0)) SCREEN.blit(BACK_MAIN, (0, 0))
SCREEN.blit(button_play, button_rect) SCREEN.blit(button_play, button_rect)
title_surf = FONT.render('Goblin & Knight', True, (255,255,255))
SCREEN.blit(title_surf, (WIDTH//2 - title_surf.get_width()//2, 120))
if button_rect.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0]: if button_rect.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0]:
restart_level() restart_level()
level = 1 level = 1
level_start_time = pygame.time.get_ticks()
if BG_MUSIC:
try:
pygame.mixer.music.play(-1)
except Exception:
pass
# ================= GAME =================
elif level == 1: elif level == 1:
SCREEN.blit(BACKGROUND, (0, 0)) SCREEN.blit(BACKGROUND, (0, 0))
SCREEN.blit(door_image, door_rect) SCREEN.blit(door_image, door_rect)
if not paused: # --- Goblin ---
goblin.handle_input(keys)
goblin.handle_input(keys) goblin.apply_gravity()
goblin.apply_gravity() goblin.update_animation()
goblin.update_animation()
knight.handle_input(keys)
knight.apply_gravity()
knight.update_animation()
goblin.draw(SCREEN) goblin.draw(SCREEN)
# --- Knight ---
knight.handle_input(keys)
knight.apply_gravity()
knight.update_animation()
knight.draw(SCREEN) knight.draw(SCREEN)
elapsed = 0
if level_start_time:
elapsed = (pygame.time.get_ticks() - level_start_time) // 1000
hud_g = FONT.render(f'Goblin: {score_goblin}', True, (255,255,255))
hud_k = FONT.render(f'Knight: {score_knight}', True, (255,255,255))
hud_t = FONT.render(f'Time: {elapsed}s', True, (255,255,255))
SCREEN.blit(hud_g, (20, 20))
SCREEN.blit(hud_k, (WIDTH - hud_k.get_width() - 20, 20))
SCREEN.blit(hud_t, (WIDTH//2 - hud_t.get_width()//2, 20))
if paused:
p = FONT.render('PAUSED - press ESC to resume', True, (255,255,0))
SCREEN.blit(p, (WIDTH//2 - p.get_width()//2, HEIGHT//2 - 20))
# Победа
if goblin.rect.colliderect(door_rect) and keys[pygame.K_e]: if goblin.rect.colliderect(door_rect) and keys[pygame.K_e]:
score_goblin += 1 print("Goblin wins!")
restart_level() restart_level()
level = 0 level = 0
if BG_MUSIC:
try:
pygame.mixer.music.stop()
except Exception:
pass
if knight.rect.colliderect(door_rect) and keys[pygame.K_KP5]: if knight.rect.colliderect(door_rect) and keys[pygame.K_KP5]:
score_knight += 1 print("Knight wins!")
restart_level() restart_level()
level = 0 level = 0
if BG_MUSIC:
try:
pygame.mixer.music.stop()
except Exception:
pass
pygame.display.update() pygame.display.update()
CLOCK.tick(FPS) CLOCK.tick(60)