Оружие героя

Карта немного поменялась, так как Линк врезался в мосты, которые соединяют нижние острова. Изменения делал непосредственно в Tiles и сохранял карту и csv-файлы. Чтобы всё было канонично, Линку выдадим меч. Спрайты на мечи я тоже отрисовал. Он лежит в папке weapons/sword. Там 5 картинок, где full обозначает сам меч, а остальные 4 — направления меча. Приступим к коду.

В файле setting.py, создаем словарь из оружий. У меня будет только один меч, но вы можете добавить больше оружия. Сам словарь:

weapon_data = {'sword': {'cooldown': 300, 'damage': 15, 'graphic':'../graphic/weapons/sword/full.png'}}

Далее, создадим новый файл с настойкой оружия weapon.py:

import pygame

class Weapon(pygame.sprite.Sprite):
    def __init__(self, player, groups):
        super().__init__(groups)
        self.image = pygame.Surface((40, 40)) #сама графика
        self.rect = self.image.get_rect(center = player.rect.center) #место отрисовки

Тут всё традиционно и без нового. Мы центруемся от самого игрока последней строкой в коде. Сейчас посередине будет рисоваться чёрный квадрат 40 на 40 пикселей. Импортируем новый файл в Level и создаём новый метод create_attack.

def create_attack(self):
    Weapon(self.player, [self.visible_sprites]) 

Далее в самой отрисовке игрока, добавим наш метод как ссылку на него:

self.player = Player((1000, 1000), [self.visible_sprites], self.obstacle_sprites, self.create_attack)

Далее перейдём в файл player.py и там передадим create_attack и создадим демона. Также, при нажатии на пробел, добавим метод self.create_attak(). Теперь можем вернуться к отрисовке нашего оружия:

import pygame

class Weapon(pygame.sprite.Sprite):
    def __init__(self, player, groups):
        super().__init__(groups)
        direction = player.status.split('_')[0] #обрезаем строку по "_" чтобы понимать куда он смотрит
        full_path = f'../graphic/weapons/{player.weapon}/{direction}.png' #адрес оружия
        self.image = pygame.image.load(full_path).convert_alpha() #сама графика
        if direction == 'right':
            self.rect = self.image.get_rect(midleft = player.rect.midright + pygame.math.Vector2(-10, 16))
        elif direction == 'left':
            self.rect = self.image.get_rect(midright = player.rect.midleft + pygame.math.Vector2(10, 16))
        elif direction == 'down':
            self.rect = self.image.get_rect(midtop = player.rect.midbottom + pygame.math.Vector2(-15, 0))
        else:
            self.rect = self.image.get_rect(midbottom = player.rect.midtop + pygame.math.Vector2(-15, 0))

Интересные моменты: во-первых, обрезаем строку по "_" чтобы понять куда смотрит герой (неважно с "attack" или без). Затем отрисовка. Нам нужно чтобы меч рисовался в руке у Линка. Я выбрал следующий метод, если меч слева, то "приклеиться" он должен справа от Линка, то есть midleft = player.rect.midright + pygame.math.Vector2(-10, 16). Далее, плюсуем вектор направления чтобы меч был ровно в руке. Далее всё повторяется в зависимости от направления.

Добавим в player.py новых демонов:

self.create_attak = create_attak #создали атаку
self.weapon_index = 0 #номер оружия (если у вас будет несколько орудий пыток монстров)
self.weapon = list(weapon_data.keys())[self.weapon_index] #выбрали конкретное оружие и все его параметры

Теперь есть меч, но есть проблема. Мечи не исчезают:

Создадим новый метод в level.py: destroy_weapon. Помимо прочего, нужно немного переработать код в самом level.py. Создадим нового демона self.current_attack = None, а также переработаем метод create_attack.

def create_attack(self):
    self.current_attack = Weapon(self.player, [self.visible_sprites])   

def destroy_weapon(self):
    if self.current_attack:
        self.current_attack.kill()
    self.current_attack = None

Таким образом, при наличии атаки, мы убиваем процесс и обнуляем указатель атаки (current_attak). Нужен ещё кулдаун. Также, не забудьте сослаться на self.destroy_weapon в player:

self.player = Player((1000, 1000), [self.visible_sprites], self.obstacle_sprites, self.create_attack, self.destroy_weapon)

Далее пропишем метод в player.py и внесём в кулдаун новую функцию: self.destroy_weapon(). Результат:

Файлы этапа можно скачать здесь. Теперь настроим интерфейс.

Last updated