|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 496 B |
|
After Width: | Height: | Size: 440 B |
|
After Width: | Height: | Size: 171 B |
|
After Width: | Height: | Size: 124 B |
|
After Width: | Height: | Size: 95 B |
|
After Width: | Height: | Size: 481 B |
|
After Width: | Height: | Size: 485 B |
|
After Width: | Height: | Size: 440 B |
|
After Width: | Height: | Size: 458 B |
|
After Width: | Height: | Size: 438 B |
|
After Width: | Height: | Size: 451 B |
|
After Width: | Height: | Size: 473 B |
|
After Width: | Height: | Size: 490 B |
|
After Width: | Height: | Size: 469 B |
|
After Width: | Height: | Size: 431 B |
|
After Width: | Height: | Size: 448 B |
|
After Width: | Height: | Size: 516 B |
|
After Width: | Height: | Size: 439 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 |
|
After Width: | Height: | Size: 219 B |
|
After Width: | Height: | Size: 492 B |
|
After Width: | Height: | Size: 217 B |
|
After Width: | Height: | Size: 458 B |
|
After Width: | Height: | Size: 454 B |
|
After Width: | Height: | Size: 424 B |
|
After Width: | Height: | Size: 290 B |
|
After Width: | Height: | Size: 203 B |
|
After Width: | Height: | Size: 221 B |
|
After Width: | Height: | Size: 458 B |
385
main.py
|
|
@ -1,235 +1,254 @@
|
||||||
import pygame
|
import pygame
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
pygame.init()
|
pygame.init()
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# НАСТРОЙКИ
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
|
WIDTH, HEIGHT = 1000, 800
|
||||||
|
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||||
|
pygame.display.set_caption("Goblin & Knight")
|
||||||
|
|
||||||
CLOCK = pygame.time.Clock()
|
CLOCK = pygame.time.Clock()
|
||||||
SCREEN = pygame.display.set_mode((1000, 800))
|
|
||||||
BLACK = (0, 0, 0)
|
BLACK = (0, 0, 0)
|
||||||
|
GRAVITY = 1
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# ЗАГРУЗКА ФОНОВ
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
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, (1000, 800)).convert_alpha()
|
BACK_MAIN = pygame.transform.scale(BACK_MAIN, (WIDTH, HEIGHT))
|
||||||
level = 0
|
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# ФУНКЦИЯ ВЫРЕЗКИ СПРАЙТОВ
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
class Goblin:
|
def get_image(sheet, frame_x, frame_y, width, height, scale, color):
|
||||||
def __init__(self):
|
|
||||||
self.x = 100
|
|
||||||
self.y = 800
|
|
||||||
self.gravity = 1
|
|
||||||
self.jump_height = 20
|
|
||||||
self.y_velocity = 20
|
|
||||||
self.jumping = False
|
|
||||||
self.start_x = 100
|
|
||||||
self.start_y = 800
|
|
||||||
|
|
||||||
def reset_position(self):
|
|
||||||
self.x = self.start_x
|
|
||||||
self.y = self.start_y
|
|
||||||
g_facing_right = True
|
|
||||||
|
|
||||||
class Knight:
|
|
||||||
def __init__(self):
|
|
||||||
self.x = 300
|
|
||||||
self.y = 700
|
|
||||||
self.gravity = 1
|
|
||||||
self.jump_height = 20
|
|
||||||
self.y_velocity = 20
|
|
||||||
self.jumping = False
|
|
||||||
|
|
||||||
self.start_x = 300
|
|
||||||
self.start_y = 700
|
|
||||||
|
|
||||||
def reset_position(self):
|
|
||||||
self.x = self.start_x
|
|
||||||
self.y = self.start_y
|
|
||||||
|
|
||||||
k_facing_right = True
|
|
||||||
|
|
||||||
def get_image(sheet,frame_w, frame_h, width, height, scale, color):
|
|
||||||
image = pygame.Surface((width, height)).convert_alpha()
|
image = pygame.Surface((width, height)).convert_alpha()
|
||||||
image.blit(sheet, (0,0),((frame_w*width),(frame_h*height), width, height))
|
image.blit(sheet, (0, 0), (frame_x * width, frame_y * height, width, height))
|
||||||
image = pygame.transform.scale(image, (width*scale, height*scale)).convert_alpha()
|
image = pygame.transform.scale(image, (width * scale, height * scale))
|
||||||
if color is not None:
|
|
||||||
image.set_colorkey(color)
|
image.set_colorkey(color)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
# GOBLIN
|
|
||||||
goblin = pygame.image.load("images/GoblinWorker/GoblinWorker.png").convert_alpha()
|
|
||||||
STANDING_SURFACE = get_image(goblin, 1, 1, 48, 48, 3, BLACK)
|
|
||||||
|
|
||||||
frame_0 = get_image(goblin, 0,0, 48, 48, 3, BLACK)
|
# =====================================================
|
||||||
frame_1 = get_image(goblin, 4,2 , 48, 48, 3, BLACK)
|
# КЛАСС ИГРОКА
|
||||||
walk_a = get_image(goblin, 5, 1, 48, 48, 3, BLACK)
|
# =====================================================
|
||||||
walk_b = get_image(goblin, 0, 2, 48, 48, 3, BLACK)
|
|
||||||
|
|
||||||
# KNIGHT
|
class Player:
|
||||||
knight = pygame.image.load("images/sprites/knight.png").convert_alpha()
|
def __init__(self, x, y, sprite_sheet, frame_size, scale, controls):
|
||||||
K_STAND = get_image(knight, 2, 0, 32, 32, 3, BLACK)
|
self.start_x = x
|
||||||
k_walk_a = get_image(knight, 1, 2, 32, 32, 3, BLACK)
|
self.start_y = y
|
||||||
k_walk_b = get_image(knight, 5, 2, 32, 32, 3, BLACK)
|
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
|
||||||
|
self.y_velocity = 0
|
||||||
|
self.jump_power = 20
|
||||||
|
self.jumping = False
|
||||||
|
self.facing_right = True
|
||||||
|
self.moving = False
|
||||||
|
|
||||||
|
self.controls = controls
|
||||||
|
|
||||||
|
self.anim_counter = 0
|
||||||
|
self.ANIM_SPEED = 8
|
||||||
|
|
||||||
|
w, h = frame_size
|
||||||
|
|
||||||
|
# Анимации
|
||||||
|
self.stand = get_image(sprite_sheet, 0, 0, w, h, scale, BLACK)
|
||||||
|
self.walk1 = get_image(sprite_sheet, 1, 0, w, h, scale, BLACK)
|
||||||
|
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.surface = self.stand
|
||||||
|
self.rect = self.surface.get_rect(center=(self.x, self.y))
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# СБРОС ПЕРСОНАЖА
|
||||||
|
# -------------------------
|
||||||
|
def reset(self):
|
||||||
|
self.x = self.start_x
|
||||||
|
self.y = self.start_y
|
||||||
|
self.y_velocity = 0
|
||||||
|
self.jumping = False
|
||||||
|
self.moving = False
|
||||||
|
self.anim_counter = 0
|
||||||
|
self.facing_right = True
|
||||||
|
self.rect = self.surface.get_rect(center=(self.x, self.y))
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# УПРАВЛЕНИЕ
|
||||||
|
# -------------------------
|
||||||
|
def handle_input(self, keys):
|
||||||
|
self.moving = False
|
||||||
|
|
||||||
|
if keys[self.controls["right"]]:
|
||||||
|
self.x += 5
|
||||||
|
self.facing_right = True
|
||||||
|
self.moving = True
|
||||||
|
|
||||||
|
if keys[self.controls["left"]]:
|
||||||
|
self.x -= 5
|
||||||
|
self.facing_right = False
|
||||||
|
self.moving = True
|
||||||
|
|
||||||
|
if keys[self.controls["jump"]] and not self.jumping:
|
||||||
|
self.jumping = True
|
||||||
|
self.y_velocity = self.jump_power
|
||||||
|
|
||||||
|
# Ограничение по экрану
|
||||||
|
if self.x < 0:
|
||||||
|
self.x = 0
|
||||||
|
if self.x > WIDTH:
|
||||||
|
self.x = WIDTH
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# ГРАВИТАЦИЯ
|
||||||
|
# -------------------------
|
||||||
|
def apply_gravity(self):
|
||||||
|
self.y_velocity -= GRAVITY
|
||||||
|
self.y -= self.y_velocity
|
||||||
|
|
||||||
|
if self.y >= HEIGHT:
|
||||||
|
self.y = HEIGHT
|
||||||
|
self.y_velocity = 0
|
||||||
|
self.jumping = False
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# АНИМАЦИЯ
|
||||||
|
# -------------------------
|
||||||
|
def update_animation(self):
|
||||||
|
if self.jumping:
|
||||||
|
self.surface = self.jump_img
|
||||||
|
elif self.moving:
|
||||||
|
self.anim_counter += 1
|
||||||
|
frame = (self.anim_counter // self.ANIM_SPEED) % 2
|
||||||
|
self.surface = self.walk1 if frame == 0 else self.walk2
|
||||||
|
else:
|
||||||
|
self.surface = self.stand
|
||||||
|
|
||||||
|
if not self.facing_right:
|
||||||
|
self.surface = pygame.transform.flip(self.surface, True, False)
|
||||||
|
|
||||||
|
self.rect = self.surface.get_rect(center=(self.x, self.y))
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# ОТРИСОВКА
|
||||||
|
# -------------------------
|
||||||
|
def draw(self, screen):
|
||||||
|
screen.blit(self.surface, self.rect)
|
||||||
|
|
||||||
|
|
||||||
k_jump_start = get_image(knight, 3, 5, 32, 32, 3, BLACK)
|
# =====================================================
|
||||||
k_jump_apex = get_image(knight, 4, 5, 32, 32, 3, BLACK)
|
# ЗАГРУЗКА СПРАЙТОВ
|
||||||
k_jump_fall = get_image(knight, 5, 5, 32, 32, 3, BLACK)
|
# =====================================================
|
||||||
|
|
||||||
|
goblin_sheet = pygame.image.load("images/GoblinWorker/GoblinWorker.png").convert_alpha()
|
||||||
|
knight_sheet = pygame.image.load("images/sprites/knight.png").convert_alpha()
|
||||||
|
|
||||||
|
goblin = Player(
|
||||||
|
200, 800,
|
||||||
|
goblin_sheet,
|
||||||
|
(48, 48),
|
||||||
|
3,
|
||||||
|
{
|
||||||
|
"left": pygame.K_a,
|
||||||
|
"right": pygame.K_d,
|
||||||
|
"jump": pygame.K_SPACE
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
knight = Player(
|
||||||
|
500, 800,
|
||||||
|
knight_sheet,
|
||||||
|
(32, 32),
|
||||||
|
3,
|
||||||
|
{
|
||||||
|
"left": pygame.K_KP4,
|
||||||
|
"right": pygame.K_KP6,
|
||||||
|
"jump": pygame.K_KP8
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# ОБЪЕКТЫ УРОВНЯ
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
# SPRITES / WORLD
|
|
||||||
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))
|
||||||
wall_image = pygame.image.load("images/wall.png")
|
|
||||||
wall_right = pygame.Rect(1000, 0, 1, 800)
|
|
||||||
wall_left = pygame.Rect(0, 0, 1, 800)
|
|
||||||
wall_bottom = pygame.Rect(0, 800, 1000, 1)
|
|
||||||
wall_up = pygame.Rect(0, 0, 1000, 1)
|
|
||||||
|
|
||||||
#BUTTONS
|
|
||||||
button_play = pygame.image.load("images/play_button.png")
|
button_play = pygame.image.load("images/play_button.png")
|
||||||
button_play_rect = button_play.get_rect(center=(500, 400))
|
button_rect = button_play.get_rect(center=(500, 400))
|
||||||
#PLATFORM
|
|
||||||
platform_image = pygame.image.load("images/sprites/platforms.png")
|
|
||||||
platform = get_image(platform_image, 0, 0, 16, 9, 3, BLACK)
|
|
||||||
platform_rect = platform.get_rect(topleft=(400, 700))
|
|
||||||
|
|
||||||
# ANIMATION
|
# =====================================================
|
||||||
g_anim_counter = 0
|
# ФУНКЦИЯ РЕСТАРТА
|
||||||
k_anim_counter = 0
|
# =====================================================
|
||||||
ANIM_SPEED = 8
|
|
||||||
|
|
||||||
|
def restart_level():
|
||||||
|
goblin.reset()
|
||||||
|
knight.reset()
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
# GAME LOOP
|
# GAME LOOP
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
|
level = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
keys_pressed = 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 =================
|
||||||
g_moving = False
|
|
||||||
if keys_pressed[pygame.K_d]:
|
|
||||||
G_X += 5
|
|
||||||
g_facing_right = True
|
|
||||||
g_moving = True
|
|
||||||
if keys_pressed[pygame.K_a]:
|
|
||||||
G_X -= 5
|
|
||||||
g_facing_right = False
|
|
||||||
g_moving = True
|
|
||||||
if keys_pressed[pygame.K_SPACE] and not g_jumping:
|
|
||||||
g_jumping = True
|
|
||||||
g_y_velocity = G_JUMP_HEIGHT
|
|
||||||
|
|
||||||
k_moving = False
|
|
||||||
if keys_pressed[pygame.K_KP6]:
|
|
||||||
K_X += 5
|
|
||||||
k_facing_right = True
|
|
||||||
k_moving = True
|
|
||||||
if keys_pressed[pygame.K_KP4]:
|
|
||||||
K_X -= 5
|
|
||||||
k_facing_right = False
|
|
||||||
k_moving = True
|
|
||||||
if keys_pressed[pygame.K_KP8] and not k_jumping:
|
|
||||||
k_jumping = True
|
|
||||||
k_y_velocity = K_JUMP_HEIGHT
|
|
||||||
|
|
||||||
# Goblin
|
|
||||||
g_y_velocity -= G_GRAVITY
|
|
||||||
G_Y -= g_y_velocity
|
|
||||||
|
|
||||||
# Knight
|
|
||||||
k_y_velocity -= K_GRAVITY
|
|
||||||
K_Y -= k_y_velocity
|
|
||||||
|
|
||||||
if G_X < 0: G_X = 0
|
|
||||||
if G_X > 1000: G_X = 1000
|
|
||||||
|
|
||||||
if K_X < 0: K_X = 0
|
|
||||||
if K_X > 1000: K_X = 1000
|
|
||||||
|
|
||||||
# Пол
|
|
||||||
if G_Y >= 800:
|
|
||||||
G_Y = 800
|
|
||||||
g_y_velocity = 0
|
|
||||||
g_jumping = False
|
|
||||||
|
|
||||||
if K_Y >= 800:
|
|
||||||
K_Y = 800
|
|
||||||
k_y_velocity = 0
|
|
||||||
k_jumping = False
|
|
||||||
|
|
||||||
g_anim_counter = g_anim_counter + 1 if g_moving else 0
|
|
||||||
k_anim_counter = k_anim_counter + 1 if k_moving else 0
|
|
||||||
|
|
||||||
if g_jumping:
|
|
||||||
g_surface = frame_1
|
|
||||||
elif g_moving:
|
|
||||||
g_frame_index = (g_anim_counter // ANIM_SPEED) % 2
|
|
||||||
g_surface = walk_a if g_frame_index == 0 else walk_b
|
|
||||||
else:
|
|
||||||
g_surface = STANDING_SURFACE
|
|
||||||
|
|
||||||
if not g_facing_right:
|
|
||||||
g_surface = pygame.transform.flip(g_surface, True, False)
|
|
||||||
g_surface.set_colorkey(BLACK)
|
|
||||||
|
|
||||||
g_rect = g_surface.get_rect(center=(G_X, G_Y))
|
|
||||||
|
|
||||||
if k_jumping:
|
|
||||||
up_thresh = K_JUMP_HEIGHT // 3
|
|
||||||
down_thresh = -up_thresh
|
|
||||||
if k_y_velocity > up_thresh:
|
|
||||||
k_surface = k_jump_start
|
|
||||||
elif k_y_velocity > down_thresh:
|
|
||||||
k_surface = k_jump_apex
|
|
||||||
else:
|
|
||||||
k_surface = k_jump_fall
|
|
||||||
elif k_moving:
|
|
||||||
k_frame_index = (k_anim_counter // ANIM_SPEED) % 2
|
|
||||||
k_surface = k_walk_a if k_frame_index == 0 else k_walk_b
|
|
||||||
else:
|
|
||||||
k_surface = K_STAND
|
|
||||||
|
|
||||||
if not k_facing_right:
|
|
||||||
k_surface = pygame.transform.flip(k_surface, True, False)
|
|
||||||
k_surface.set_colorkey(BLACK)
|
|
||||||
|
|
||||||
k_rect = k_surface.get_rect(center=(K_X, K_Y))
|
|
||||||
|
|
||||||
|
|
||||||
if level == 0:
|
if level == 0:
|
||||||
SCREEN.blit(BACK_MAIN, (0, 0))
|
SCREEN.blit(BACK_MAIN, (0, 0))
|
||||||
SCREEN.blit(button_play, button_play_rect)
|
SCREEN.blit(button_play, button_rect)
|
||||||
|
|
||||||
if button_play_rect.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0]:
|
if button_rect.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0]:
|
||||||
|
restart_level()
|
||||||
level = 1
|
level = 1
|
||||||
if level == 1:
|
|
||||||
|
# ================= GAME =================
|
||||||
|
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)
|
||||||
SCREEN.blit(platform, platform_rect)
|
|
||||||
SCREEN.blit(g_surface, g_rect)
|
|
||||||
SCREEN.blit(k_surface, k_rect)
|
|
||||||
# Goblin
|
|
||||||
if g_rect.colliderect(platform_rect) and g_y_velocity <= 0:
|
|
||||||
G_Y = platform_rect.top - g_rect.height / 2
|
|
||||||
g_y_velocity = 0
|
|
||||||
g_jumping = False
|
|
||||||
|
|
||||||
# Knight
|
# --- Goblin ---
|
||||||
if k_rect.colliderect(platform_rect) and k_y_velocity <= 0:
|
goblin.handle_input(keys)
|
||||||
K_Y = platform_rect.top - k_rect.height / 2
|
goblin.apply_gravity()
|
||||||
k_y_velocity = 0
|
goblin.update_animation()
|
||||||
k_jumping = False
|
goblin.draw(SCREEN)
|
||||||
|
|
||||||
if g_rect.colliderect(door_rect) and keys_pressed[pygame.K_e]:
|
# --- Knight ---
|
||||||
|
knight.handle_input(keys)
|
||||||
|
knight.apply_gravity()
|
||||||
|
knight.update_animation()
|
||||||
|
knight.draw(SCREEN)
|
||||||
|
|
||||||
|
# Победа
|
||||||
|
if goblin.rect.colliderect(door_rect) and keys[pygame.K_e]:
|
||||||
print("Goblin wins!")
|
print("Goblin wins!")
|
||||||
|
restart_level()
|
||||||
level = 0
|
level = 0
|
||||||
|
|
||||||
if k_rect.colliderect(door_rect) and keys_pressed[pygame.K_KP5]:
|
if knight.rect.colliderect(door_rect) and keys[pygame.K_KP5]:
|
||||||
print("Knight wins!")
|
print("Knight wins!")
|
||||||
|
restart_level()
|
||||||
level = 0
|
level = 0
|
||||||
pygame.display.update()
|
|
||||||
|
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
CLOCK.tick(60)
|
CLOCK.tick(60)
|
||||||