Анимация Линка
Сначала нужно добавить действие и кнопку. На атаку будет стоять кнопка "Пробел". Пропишем это в player.py
:
if keys[pygame.K_SPACE] and not 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
. Сам метод:
def cooldowns(self):
current_time = pygame.time.get_ticks()
if self.attacking:
if current_time - self.attack_time >= self.attack_cooldown:
self.attacking = False
Конструкция очень проста. Если разница во времени после нажатия меньше кулдауна атаки (в моём случае 400 мс), запрещать атаку. Не забудьте закинуть функцию cooldowns в update-функцию.
Далее, пропишем метод import_player_assets
:
def import_player_assets(self):
character_path = '../graphic/Link/'
self.animations = {'up': [], 'down': [], 'left': [], 'right': [],
'right_idle': [], 'left_idle': [], 'up_idle': [], 'down_idle': [],
'right_attack': [], 'left_attack': [], 'up_attack': [], 'down_attack': []}
В нём прописаны все возможности передвижения. Они лежат в папке "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'
). Но этого мало. Нужно получать статус автоматически, а это значит новый метод:
def get_status(self):
if self.direction.x == 0 and self.direction.y == 0:
self.status = self.status + '_idle'
Прописываем название файла "стояния" героя. Стояние — _idle
, а статус будет меняться от нажатия кнопок. Закидываем get_status()
в update-метод.
Пропишем статусы для наших методов хождения:
if keys[pygame.K_UP]:
self.direction.y = -1
self.status = 'up'
elif keys[pygame.K_DOWN]:
self.direction.y = 1
self.status = 'down'
else:
self.direction.y = 0
if keys[pygame.K_LEFT]:
self.direction.x = -1
self.status = 'left'
elif keys[pygame.K_RIGHT]:
self.direction.x = 1
self.status = 'right'
Тут всё достаточно прозрачно. Движение = статусу. Подправим функцию статуса:
if not 'idle' in self.status:
self.status = self.status + '_idle'
Если мы отпускаем кнопку — статус равен idle, а если держим просто название направления.
Теперь окончательно проапгрейдим код для атак и комбинаций с "_idle":
def get_status(self):
if self.direction.x == 0 and self.direction.y == 0:
if not 'idle' in self.status and not 'attack' in self.status:
self.status = self.status + '_idle'
if self.attacking:
self.direction.x = 0 #координаты по x
self.direction.y = 0 #координаты по y
if not 'attack' in self.status: #если нет подписи "attack"
if 'idle' in self.status: #но есть "idle"
self.status = self.status.replace('_idle', '_attack') #убираем _idle, но оставляем _attack
else:
self.status = self.status + '_attack' #если idle не было, просто стави attack
else:
if 'attack' in self.status:
self.status = self.status.replace('_attack', '') #удаляем attack при завершении статуса
Наконец, заанимируем Линка. Установим два новых демона self.frame_index = 0
— индекс первой картинки и скорость смены картинок — self.animation_speed = 0.15
. Затем создадим метод animate()
:
def animate(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-методе:
def input(self): #варьируем кнопки
if not self.attacking:
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
self.direction.y = -1
self.status = 'up'
elif keys[pygame.K_DOWN]:
self.direction.y = 1
self.status = 'down'
else:
self.direction.y = 0
if keys[pygame.K_LEFT]:
self.direction.x = -1
self.status = 'left'
elif keys[pygame.K_RIGHT]:
self.direction.x = 1
self.status = 'right'
else:
self.direction.x = 0
if keys[pygame.K_SPACE]:
self.attacking = True
self.attack_time = pygame.time.get_ticks()
Итог:

Далее прорисуем оружие. Файлы этого этапа.
Last updated