Загрузка данных
import random
import pygame as pg
import pygame_menu
GESTURE_MODE = False
if GESTURE_MODE:
from gesture import Gesture
pg.init()
SCREEN_WIDTH = 900
SCREEN_HEIGHT = 550
CHARACTER_WIDTH = 300
CHARACTER_HEIGHT = 375
FPS = 60
font = pg.font.Font(None, 40)
def load_image(file, width, height):
image = pg.image.load(file).convert_alpha()
image = pg.transform.scale(image, (width, height))
return image
def text_render(text):
return font.render(str(text), True, "black")
class Enemy(pg.sprite.Sprite):
def __init__(self, folder):
super().__init__()
self.folder = folder
self.load_animations()
self.hp = 200
self.image = self.idle_animation_left[0]
self.current_image = 0
self.current_animation = self.idle_animation_left
self.rect = self.image.get_rect()
self.rect.center = (SCREEN_WIDTH - 100, SCREEN_HEIGHT // 2)
self.timer = pg.time.get_ticks()
self.interval = 300
self.side = "left"
self.animation_mode = True
self.magic_balls = pg.sprite.Group()
self.attack_mode = False
self.attack_interval = 500
self.move_interval = 800
self.move_duration = 100
self.direction = 0
self.move_timer = pg.time.get_ticks()
self.charge_power = 0
def load_animations(self):
self.idle_animation_right = [load_image(f"images/{self.folder}/idle{i}.png", CHARACTER_WIDTH, CHARACTER_HEIGHT)
for i in range(1, 4)]
self.idle_animation_left = [pg.transform.flip(image, True, False) for image in self.idle_animation_right]
self.move_animation_right = [load_image(f"images/{self.folder}/move{i}.png", CHARACTER_WIDTH, CHARACTER_HEIGHT)
for i in range(1, 5)]
self.move_animation_left = [pg.transform.flip(image, True, False) for image in self.move_animation_right]
self.attack = [load_image(f"images/{self.folder}/attack.png", CHARACTER_WIDTH, CHARACTER_HEIGHT)]
self.attack.append(pg.transform.flip(self.attack[0], True, False))
def update(self, player):
self.handle_attack_mode(player)
self.handle_movement()
self.handle_animation()
def handle_attack_mode(self, player):
if not self.attack_mode:
attack_probability = 1
if player.charge_mode:
attack_probability += 2
if random.randint(1, 250) <= attack_probability:
self.attack_mode = True
self.charge_power = random.randint(1, 100)
if player.rect.centerx < self.rect.centerx:
self.side = "left"
else:
self.side = "right"
self.animation_mode = False
self.image = self.attack[self.side != "right"]
if self.attack_mode:
if pg.time.get_ticks() - self.timer > self.attack_interval:
self.attack_mode = False
self.timer = pg.time.get_ticks()
def handle_movement(self):
if self.attack_mode:
return
now = pg.time.get_ticks()
if now - self.move_timer < self.move_duration:
if random.randint(1, 100) == 1 and now - self.move_timer > self.move_interval:
self.move_timer = pg.time.get_ticks()
self.move_duration = (400, 1500)
self.direction = random.choice([-1, 1])
else:
self.animation_mode = True
self.current_animation = self.idle_animation_left if self.side == "left" else self.idle_animation_right
def handle_animation(self):
if self.animation_mode and not self.attack_mode:
if pg.time.get_ticks() - self.timer > self.interval:
self.current_image += 1
if self.current_image >= len(self.current_animation):
self.current_image = 0
self.image = self.current_animation[self.current_image]
self.timer = pg.time.get_ticks()
if self.attack_mode and self.charge_power > 0:
fireball_position = self.rect.topright if self.side == "right" else self.rect.topleft
self.magic_balls.add(Magicball(fireball_position, self.side, self.charge_power, "earth monk"))
self.charge_power = 0
self.charge_mode = False
self.image = self.attack[self.side != "right"]
self.timer = pg.time.get_ticks()
class Player(pg.sprite.Sprite):
def __init__(self, folder="fire wizard", first_player=True):
super().__init__()
self.folder = folder
print(folder)
self.load_animations()
if first_player:
self.coord = (100, SCREEN_HEIGHT // 2)
self.current_animation = self.idle_animation_right
self.side = "right"
self.key_right = pg.K_d
self.key_left = pg.K_a
self.key_dowm = pg.K_s
self.key_charge = pg.K_SPACE
else:
self.coord = (SCREEN_WIDTH - 100, SCREEN_HEIGHT // 2)
self.current_animation = self.idle_animation_left
self.side = "left"
self.key_right = pg.K_RIGHT
self.key_left = pg.K_LEFT
self.key_down = pg.K_DOWN
self.key_charge = pg.K_RCTRL
self.hp = 200
self.image = self.current_animation[0]
self.current_image = 0
self.rect = self.image.get_rect()
self.rect.center = (100, SCREEN_HEIGHT // 2)
self.timer = pg.time.get_ticks()
self.interval = 300
self.animation_mode = True
self.charge_power = 0
self.charge_indicator = pg.Surface((self.charge_power, 10))
self.charge_indicator.fill("orange")
self.charge_mode = False
self.attack_mode = False
self.attack_interval = 500
self.fireballs = pg.sprite.Group()
folder = "fire wizard"
def load_animations(self):
self.idle_animation_right = []
for i in range(1, 4):
self.idle_animation_right.append(
load_image(f"images/{self.folder}/idle{i}.png", CHARACTER_WIDTH, CHARACTER_HEIGHT))
self.idle_animation_left = []
for image in self.idle_animation_right:
self.idle_animation_left.append(pg.transform.flip(image, True, False))
self.move_animation_right = []
for i in range(1, 5):
self.move_animation_right.append(
load_image(f"images/{self.folder}/move{i}.png", CHARACTER_WIDTH, CHARACTER_HEIGHT))
self.move_animation_left = []
for image in self.move_animation_right:
self.move_animation_left.append(pg.transform.flip(image, True, False))
self.charge = [load_image(f"images/{self.folder}/charge.png", CHARACTER_WIDTH, CHARACTER_HEIGHT)]
self.charge.append(pg.transform.flip(self.charge[0], True, False))
self.attack = [load_image(f"images/{self.folder}/attack.png", CHARACTER_WIDTH, CHARACTER_HEIGHT)]
self.attack.append(pg.transform.flip(self.attack[0], True, False))
self.down = [load_image(f"images/{self.folder}/down.png", CHARACTER_WIDTH, CHARACTER_HEIGHT)]
self.down.append(pg.transform.flip(self.down[0], True, False))
def handle_movement(self, direction, keys, gesture):
if self.attack_mode:
return
if direction != 0:
self.animation_mode = True
self.charge_mode = False
self.rect.x += direction
self.current_animation = self.move_animation_left if direction == -1 else self.move_animation_right
elif (GESTURE_MODE and gesture == "live long") or (not GESTURE_MODE and keys[self.key_charge]):
self.animation_mode = False
self.image = self.charge[self.side != "right"]
self.charge_mode = True
else:
self.animation_mode = True
self.charge_mode = False
self.current_animation = self.idle_animation_left if self.side == "left" else self.idle_animation_right
def update(self, gesture):
keys = pg.key.get_pressed()
direction = 0
if keys[self.key_left]:
direction = -1
self.side = "left"
elif keys[self.key_right]:
direction = 1
self.side = "right"
self.handle_animation()
self.handle_movement(direction, keys, gesture)
self.handle_attack_mode()
def handle_attack_mode(self):
if self.attack_mode:
if pg.time.get_ticks() - self.timer > self.attack_interval:
self.attack_mode = False
self.timer = pg.time.get_ticks()
def handle_animation(self):
if not self.charge_mode and self.charge_power > 0:
self.attack_mode = True
if self.animation_mode and not self.attack_mode:
if pg.time.get_ticks() - self.timer > self.interval:
self.current_image += 1
if self.current_image >= len(self.current_animation):
self.current_image = 0
self.image = self.current_animation[self.current_image]
self.timer = pg.time.get_ticks()
if self.charge_mode:
self.charge_power += 1
self.charge_indicator = pg.Surface((self.charge_power, 10))
self.charge_indicator.fill("orange")
if self.charge_power >= 100:
self.attack_mode = True
if self.attack_mode and self.charge_power > 0:
fireball_position = self.rect.topright if self.side == "right" else self.rect.topleft
self.fireballs.add(Magicball(fireball_position, self.side, self.charge_power, self.folder))
self.charge_power = 0
self.charge_mode = False
self.image = self.attack[self.side != "right"]
self.timer = pg.time.get_ticks()
class Magicball(pg.sprite.Sprite):
def __init__(self, coord, side, power, folder):
super().__init__()
self.side = side
self.power = power
self.image = load_image(f"images/{folder}/magicball.png", 200, 150)
if self.side == "right":
self.image = pg.transform.flip(self.image, True, False)
self.rect = self.image.get_rect()
self.rect.x = coord[0]
self.rect.y = coord[1] + 120
def update(self):
if self.side == "right":
self.rect.x += 4
else:
self.rect.x -= 4
if self.rect.left >= SCREEN_WIDTH or self.rect.right <= 0:
self.kill()
class Menu:
def __init__(self):
title_bar_style = pygame_menu.widgets.MENUBAR_STYLE_NONE
font = pygame_menu.font.FONT_COMIC_NEUE
pygame_menu.themes.THEME_ORANGE.widget_font = font
self.surface = pg.display.set_mode((900, 550))
self.menu = pygame_menu.Menu(
height=550,
width=900,
theme=pygame_menu.themes.THEME_ORANGE,
title="magic battles"
)
self.menu.add.label("singleplayer mode")
self.menu.add.selector("enemy:", [('lightning wizard', 1), ('earth monk', 2), ('random enemy', 3)],
onchange=self.set_enemy)
self.menu.add.button("play", self.start_game)
self.menu.add.label("two-player mode")
self.menu.add.selector("left player:", [("lightning wizard", 1), ("earth monk", 2), ("fire wizard", 3)])
self.menu.add.selector("right player:", [("lightning wizard", 1), ("earth monk", 2), ("fire wizard", 3)])
self.menu.add.button("play", self.start_game)
self.menu.add.button("exit", quit)
self.enemies = ["lightning wizard", "earth monk"]
self.enemy = None
self.enemies = ["lightning wizard", "earth monk"]
self.enemy = self.enemies[0]
# Эти три строки — новые. Они нужны для хранения информации, кто за кого играет
self.players = ["lightning wizard", "earth monk", "fire wizard"]
self.left_player = self.players[0]
self.right_player = self.players[0]
self.run()
def set_enemy(self, selected, value):
if value in (1, 2):
self.enemy = self.enemies[value - 1]
else:
self.enemy = random.choice(self.enemies)
def start_game(self):
Game(self.enemy, self.left_player)
def run(self):
self.menu.mainloop(self.surface)
class Game:
def __init__(self, enemy, player):
# Создание окна
self.screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pg.display.set_caption("Битва магов")
self.background = load_image("images/background.png", SCREEN_WIDTH, SCREEN_HEIGHT)
self.enemy = Enemy(enemy)
self.player = Player(player)
self.clock = pg.time.Clock()
self.gesture = None
if GESTURE_MODE:
print("Загрузка модуля жестов...")
self.g = Gesture()
print("Загрузка завершена")
self.GET_GESTURE = pg.USEREVENT + 1
pg.time.set_timer(self.GET_GESTURE, 1000)
self.is_running = True
self.run()
def run(self):
while True:
self.event()
self.update()
self.draw()
self.clock.tick(FPS)
def event(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.is_running = False
if GESTURE_MODE:
if event.type == self.GET_GESTURE:
self.gesture = self.g.get_gesture()
def update(self):
self.player.update(self.gesture)
self.enemy.update(self.player)
self.player.fireballs.update()
self.enemy.magic_balls.update()
hits = pg.sprite.spritecollide(self.enemy, self.player.fireballs, True)
for hit in hits:
self.enemy.hp -= hit.power
if self.player.image not in self.player.down:
hits = pg.sprite.spritecollide(self.player, self.enemy.magic_balls, True)
for hit in hits:
self.player.hp -= hit.power
def draw(self):
self.screen.blit(self.enemy.image, self.enemy.rect)
self.screen.blit(self.player.image, self.player.rect)
if self.player.charge_mode:
self.screen.blit(self.player.charge_indicator, (self.player.rect.left + 120, self.player.rect.top))
self.player.fireballs.draw(self.screen)
self.screen.blit(text_render(self.gesture), (0, 0))
# Отрисовка интерфейса
self.screen.blit(self.background, (0, 0))
self.enemy.magic_balls.draw(self.screen)
pg.draw.rect(self.screen, "black", (10, 10, 100, 10))
pg.draw.rect(self.screen, "green", (11, 11, 98, 8))
pg.display.flip()
if __name__ == "__main__":
Menu()