Compare commits
No commits in common. "ae308f594602f0ee461b9fd79de13b6d65af9211" and "70d88d20e3dd07144787852d81257440222c1f66" have entirely different histories.
ae308f5946
...
70d88d20e3
|
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 481 B |
|
Before Width: | Height: | Size: 485 B After Width: | Height: | Size: 485 B |
|
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 469 B |
|
After Width: | Height: | Size: 516 B |
|
After Width: | Height: | Size: 567 B |
|
After Width: | Height: | Size: 561 B |
|
After Width: | Height: | Size: 639 B |
|
After Width: | Height: | Size: 583 B |
|
After Width: | Height: | Size: 570 B |
|
After Width: | Height: | Size: 462 B |
|
After Width: | Height: | Size: 516 B |
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 219 B |
|
After Width: | Height: | Size: 492 B |
|
After Width: | Height: | Size: 217 B |
|
Before Width: | Height: | Size: 458 B After Width: | Height: | Size: 458 B |
|
After Width: | Height: | Size: 454 B |
|
Before Width: | Height: | Size: 424 B After Width: | Height: | Size: 424 B |
|
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 290 B |
|
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 203 B |
|
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 221 B |
|
After Width: | Height: | Size: 754 B |
212
main.py
|
|
@ -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)
|
||||||