Сначала нужно добавить действие и кнопку. На атаку будет стоять кнопка "Пробел". Пропишем это в player.py:
if keys[pygame.K_SPACE]andnot self.attacking: self.attacking =True
Непонятно, что такое self.attacking. В демоны файла я добавил три параметра: статус атаки (self.attacking = False), кулдаун после атаки (self.attack_cooldown = 400) и время атаки (self.attack_time = None).
Добавим время между атаками. После успешной атаки создадим конструкцию: self.attack_time = pygame.time.get_ticks() сразу после объявление атаки флагом True. Далее перейдём к настройке нового метода cooldowns. Сам метод:
Конструкция очень проста. Если разница во времени после нажатия меньше кулдауна атаки (в моём случае 400 мс), запрещать атаку. Не забудьте закинуть функцию cooldowns в update-функцию.
В нём прописаны все возможности передвижения. Они лежат в папке "Link":
Не забудьте закинуть в базовых демонов Player-класса наши ассеты: self.import_player_assets(). Далее, "пробежимся" по нашим папкам благодаря методу import_folder в support.py:
for animation in self.animations.keys(): full_path = character_path + animation self.animations[animation]=import_folder(full_path)
Сейчас мы можем открыть все файлы, но есть дополнительная проблема — нужно прописать статусы и анимации при нажатии на кнопку. Статус по умолчанию укажем в демоне и по умолчанию Линк будет смотреть вниз (self.status = 'down'). Но этого мало. Нужно получать статус автоматически, а это значит новый метод:
Если мы отпускаем кнопку — статус равен idle, а если держим просто название направления.
Теперь окончательно проапгрейдим код для атак и комбинаций с "_idle":
defget_status(self):if self.direction.x ==0and self.direction.y ==0:ifnot'idle'in self.status andnot'attack'in self.status: self.status = self.status +'_idle'if self.attacking: self.direction.x =0#координаты по x self.direction.y =0#координаты по yifnot'attack'in self.status:#если нет подписи "attack"if'idle'in self.status:#но есть "idle" self.status = self.status.replace('_idle', '_attack')#убираем _idle, но оставляем _attackelse: self.status = self.status +'_attack'#если idle не было, просто стави attackelse:if'attack'in self.status: self.status = self.status.replace('_attack', '')#удаляем attack при завершении статуса
Наконец, заанимируем Линка. Установим два новых демона self.frame_index = 0 — индекс первой картинки и скорость смены картинок — self.animation_speed = 0.15. Затем создадим метод animate():
defanimate(self): animation = self.animations[self.status]#узнаём статус для ссылки на нужный файл self.frame_index += self.animation_speed #добовляем нашу скорость и когда добавится единица (из 0.15), сменяем картинку
if self.frame_index >=len(animation):#при вылете из массива self.frame_index =0#возвращаемся к начальной картинке и тем самым зацикливаемся self.image = animation[int(self.frame_index)]#указываем картику self.rect = self.image.get_rect(center = self.hitbox.center)#указываем хитбокс
Сейчас мы перебираем все наши картинки и главное — их зациклить, как в рилсах. Не забываем в update-функцию self.animate().
Тут у меня залогала анимация атаки, так как кнопка продолжала нажиматься. Исправим это в input-методе: