Обновить решение, которое я нашел на данный момент.
Изначально я хочу запустить отдельную анимацию для способности, а затем для основной, потому что главного героя я использую как для врагов, так и для героя, но не могу понять, почему не запускается анимация отдельной способности
Я переделал ее и вставил в анимацию персонажа, но она воспроизводится слишком быстро или воспроизводится неправильно, потому что я могу видеть только первый png из последовательностей png.
Поэтому я хочу иметь отдельную способность, которую может использовать только игрок, или чтобы персонаж правильно воспроизводил анимацию.
import pygame
import os
pygame.init()
SCREEN_WIDTH = 600
SCREEN_HEIGHT = int(SCREEN_WIDTH * 0.8)
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Idle Runner')
#set framerate
clock = pygame.time.Clock()
FPS = 60
#define game variables
GRAVITY = 0.75
#define player action variables
moving_left = False
moving_right = False
shoot = False
slash = False
#load images
#bullet
bullet_img = pygame.image.load('img/icons/bullet.png').convert_alpha()
#slash
slash_img = pygame.image.load('img/icons/slash.png').convert_alpha()
#define color
BG = (144, 201, 120)
RED = (255, 0, 0)
def draw_bg():
screen.fill(BG)
pygame.draw.line(screen, RED, (0, 300), (SCREEN_WIDTH, 300))
#width = background_img.get_width()
#for x in range(5):
#screen.blit(background_img, ((x * width) - bg_scroll * 0.5, 0))
class Character(pygame.sprite.Sprite):
def __init__(self, char_type, x, y, scale, speed, mana, slashes):
pygame.sprite.Sprite.__init__(self)
self.alive = True
self.char_type = char_type
self.speed = speed
self.mana = mana
self.start_mana = mana
self.shoot_cooldown = 0
self.slash_cooldown = 0
self.slashes = slashes
self.health = 100 # for different enemy health set self.health = health and add the variable to (def __init__(self, char_type, x, y, scale, speed, mana):)
self.max_health = self.health
self.direction = 1
self.vel_y = 0
self.jump = False
self.in_air = True
self.flip = False
self.animation_list = []
self.frame_index = 0
self.action = 0
self.update_time = pygame.time.get_ticks()
#load all images for the players
animation_types = ['Idle', 'Run', 'Jump', 'Death','Slash']
for animation in animation_types:
#reset temporary list of images
temp_list = []
#count number of files in the folder
num_of_frames = len(os.listdir(f'img/{self.char_type}/{animation}'))
for i in range(num_of_frames):
img = pygame.image.load(f'img/{self.char_type}/{animation}/{i}.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
temp_list.append(img)
self.animation_list.append(temp_list)
self.image = self.animation_list[self.action][self.frame_index]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def update(self):
self.update_animation()
self.check_alive()
#update cooldown
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
if self.slash_cooldown > 0: # Reduce slash cooldown over time
self.slash_cooldown -= 1
def move(self, moving_left, moving_right):
#reset movement variables
dx = 0
dy = 0
#assign movement variables if moving left or right
if moving_left:
dx = -self.speed
self.flip = True
self.direction = -1
if moving_right:
dx = self.speed
self.flip = False
self.direction = 1
#jump
if self.jump == True and self.in_air == False:
self.vel_y = -11
self.jump = False
self.in_air = True
#apply gravity
self.vel_y += GRAVITY
if self.vel_y > 10:
self.vel_y
dy += self.vel_y
#check collision with foor
if self.rect.bottom + dy > 300:
dy = 300 - self.rect.bottom
self.in_air = False
#update rectangle position
self.rect.x += dx
self.rect.y += dy
def shoot(self):
if self.shoot_cooldown == 0 and self.mana > 0:
self.shoot_cooldown = 20
bullet = Bullet(self.rect.centerx + (0.6 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
bullet_group.add(bullet)
#reduce mana
self.mana -= 1
def slash(self):
if self.slash_cooldown == 0 and self.slashes > 0:
self.slash_cooldown = 100 # Cooldown before next slash
#self.update_action(4) # 4 corresponds to the Slash animation action
# Spawn slash attack animation
slash = Slash(self.rect.centerx + (0.5 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
slash_group.add(slash)
self.slashes -= 1 # Reduce slashes
def update_animation(self):
#update animation
ANIMATION_COOLDOWN = 150
SLASH_ANIMATION_COOLDOWN = 300
if self.action == 4: # Slash action
ANIMATION_COOLDOWN = SLASH_ANIMATION_COOLDOWN
#update image depending on the current frame
self.image = self.animation_list[self.action][self.frame_index]
#check if enough time has passed since the last update
if pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN:
self.update_time = pygame.time.get_ticks()
self.frame_index += 1
#if the animation has run out then reset back to the end
if self.frame_index >= len(self.animation_list[self.action]):
if self.action == 4: # Slash animation
self.update_action(0) # Reset to idle after slash
elif self.action == 3: # Death animation
self.frame_index = len(self.animation_list[self.action]) - 1
else:
self.frame_index = 0
def update_action(self, new_action):
#check if the new action is different to the previous one
if new_action != self.action:
self.action = new_action
#update the animation settings
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
def check_alive(self):
if self.health SCREEN_WIDTH:
self.kill()
#check collision with characters
if pygame.sprite.spritecollide(player, bullet_group, False):
if player.alive:
player.health -= 5
self.kill()
if pygame.sprite.spritecollide(enemy, bullet_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
class Slash(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 7
self.image = slash_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
def update(self):
#move slash
self.rect.x += (self.direction * self.speed)
#check if slash has gone off screen
if self.rect.right < 0 or self.rect.left > SCREEN_WIDTH:
self.kill()
#check collision with characters
if pygame.sprite.spritecollide(enemy, slash_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
#create sprite group
bullet_group = pygame.sprite.Group()
slash_group = pygame.sprite.Group()
player = Character('Player', 200, 200, 3, 5, 20, 5)
enemy = Character('Enemy', 400, 200, 3, 5, 20, 0)
#define game variables
bg_scroll = 0
#load images
background_img = pygame.image.load('img/Background/Background.png').convert_alpha()
run = True
while run:
clock.tick(FPS)
#update background
draw_bg()
player.update()
player.draw()
enemy.update()
enemy.draw()
#update and draw groups
bullet_group.update()
slash_group.update()
bullet_group.draw(screen)
slash_group.draw(screen)
#update player actions
if player.alive:
#shoot bullets
if shoot:
player.shoot()
#throw slashes
if slash:
player.update_action(4) #4 means slash attack
player.slash()
if player.in_air:
player.update_action(2) #2 means jump
elif moving_left or moving_right:
player.update_action(1) #1 means running
else:
player.update_action(0) #0 means idle
player.move(moving_left, moving_right)
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
#mouse click
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
shoot = True
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 3:
if player.slash_cooldown == 0: # Ensure slash is triggered only once
player.update_action(4)
player.slash()
#keyboard presses
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
moving_left = True
if event.key == pygame.K_d:
moving_right = True
if event.key == pygame.K_SPACE and player.alive:
player.jump = True
if event.key == pygame.K_ESCAPE: # Exit when ESC is pressed
run = False
#keyboard relesed
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
shoot = False
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 3:
slash = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
moving_left = False
if event.key == pygame.K_d:
moving_right = False
pygame.display.update()
pygame.quit()
я вижу, что анимация воспроизводится, только если здесь есть эта строка (действие обновления проигрывателя (4))
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 3:
if player.slash_cooldown == 0: # Ensure slash is triggered only once
player.update_action(4)
player.slash()
Чтобы отделить способности от персонажа, я использовал
#class Slash_attack(pygame.sprite.Sprite):
#def __init__(self, x, y, direction, scale):
#pygame.sprite.Sprite.__init__(self)
#self.update_time = pygame.time.get_ticks()
#self.images = []
#for num in range(1, 4):
# img = pygame. image.load(f'img/slash/slash{num}.png').convert_alpha()
#img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
#self.images.append(img)
#self.frame_index = 0
#self.image = self.images[self.frame_index]
#self.rect = self.image.get_rect()
#self.rect.center = (x, y)
#self.direction = direction
#self.update_time = pygame.time.get_ticks()
#def update(self):
#SLASH_COOLDOWN = 100
#if pygame.time.get_ticks() - self.update_time > SLASH_COOLDOWN:
#self.update_time = pygame.time.get_ticks()
#self.frame_index += 1
#if self.frame_index >= len(self.images):
#self.kill() # Remove slash animation
#else:
#self.image = self.images[self.frame_index]
slash_attack_group = pygame.sprite.Group()
elif slash and slash_power == False and player.slashes > 0:
slash = Slash(player.rect.centerx + (0.5 * player.rect.size[0] * player.direction), player.rect.centery, player.direction)
slash_group.add(slash)
#reduce slashes
player.slashes -= 1
slash_power = True
Мне удалось это сделать, вот полный код, если вам все еще интересно, как я это сделал.
Я изменил кнопки мыши вверх и вниз. , // if player.alive: // def update_animation(self): // def update_action(self, new_action):
import pygame
import os
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = int(SCREEN_WIDTH * 0.8)
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Idle Runner')
#set framerate
clock = pygame.time.Clock()
FPS = 60
#define game variables
GRAVITY = 0.75
#define player action variables
moving_left = False
moving_right = False
shoot = False
slash = False
#load images
#bullet
bullet_img = pygame.image.load('img/icons/bullet.png').convert_alpha()
#slash
slash_img = pygame.image.load('img/icons/slash.png').convert_alpha()
#define color
BG = (144, 201, 120)
RED = (255, 0, 0)
def draw_bg():
screen.fill(BG)
pygame.draw.line(screen, RED, (0, 300), (SCREEN_WIDTH, 300))
#width = background_img.get_width()
#for x in range(5):
#screen.blit(background_img, ((x * width) - bg_scroll * 0.5, 0))
class Character(pygame.sprite.Sprite):
def __init__(self, char_type, x, y, scale, speed, mana, slashes):
pygame.sprite.Sprite.__init__(self)
self.alive = True
self.char_type = char_type
self.speed = speed
self.mana = mana
self.start_mana = mana
self.shoot_cooldown = 0
self.slash_cooldown = 0
self.slashes = slashes
self.health = 100 # for different enemy health set self.health = health and add the variable to (def __init__(self, char_type, x, y, scale, speed, mana):)
self.max_health = self.health
self.direction = 1
self.vel_y = 0
self.jump = False
self.in_air = True
self.flip = False
self.animation_list = []
self.frame_index = 0
self.action = 0
self.update_time = pygame.time.get_ticks()
#load all images for the players
animation_types = ['Idle', 'Run', 'Jump', 'Death','Slash']
for animation in animation_types:
#reset temporary list of images
temp_list = []
#count number of files in the folder
num_of_frames = len(os.listdir(f'img/{self.char_type}/{animation}'))
for i in range(num_of_frames):
img = pygame.image.load(f'img/{self.char_type}/{animation}/{i}.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
temp_list.append(img)
self.animation_list.append(temp_list)
self.image = self.animation_list[self.action][self.frame_index]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def update(self):
self.update_animation()
self.check_alive()
#update cooldown
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
if self.slash_cooldown > 0: # Reduce slash cooldown over time
self.slash_cooldown -= 1
def move(self, moving_left, moving_right):
#reset movement variables
dx = 0
dy = 0
#assign movement variables if moving left or right
if moving_left:
dx = -self.speed
self.flip = True
self.direction = -1
if moving_right:
dx = self.speed
self.flip = False
self.direction = 1
#jump
if self.jump == True and self.in_air == False:
self.vel_y = -11
self.jump = False
self.in_air = True
#apply gravity
self.vel_y += GRAVITY
if self.vel_y > 10:
self.vel_y
dy += self.vel_y
#check collision with foor
if self.rect.bottom + dy > 300:
dy = 300 - self.rect.bottom
self.in_air = False
#update rectangle position
self.rect.x += dx
self.rect.y += dy
def shoot(self):
if self.shoot_cooldown == 0 and self.mana > 0:
self.shoot_cooldown = 20
bullet = Bullet(self.rect.centerx + (0.6 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
bullet_group.add(bullet)
#reduce mana
self.mana -= 1
def slash(self):
if self.slash_cooldown == 0 and self.slashes > 0:
self.slash_cooldown = 100 # Cooldown before next slash
# Spawn slash attack animation
slash = Slash(self.rect.centerx + (0.5 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
slash_group.add(slash)
self.slashes -= 1 # Reduce slashes
self.update_action(4)
def update_animation(self):
#update animation
ANIMATION_COOLDOWN = 100
#update image depending on current frame
self.image = self.animation_list[self.action][self.frame_index]
#check if enough time has passed since the last update
if pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN:
self.update_time = pygame.time.get_ticks()
self.frame_index += 1
#if the animation has run out the reset back to the start
if self.frame_index >= len(self.animation_list[self.action]):
if self.action == 3:
self.frame_index = len(self.animation_list[self.action]) - 1
elif self.action == 4: # Slash animation should return to idle when finished
self.update_action(0) # Return to idle animation
else:
self.frame_index = 0
def update_action(self, new_action):
if self.action == 4 and self.frame_index < len(self.animation_list[4]) - 1:
return
#check if the new action is different to the previous one
if new_action != self.action:
self.action = new_action
#update the animation settings
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
def check_alive(self):
if self.health SCREEN_WIDTH:
self.kill()
#check collision with characters
if pygame.sprite.spritecollide(player, bullet_group, False):
if player.alive:
player.health -= 5
self.kill()
if pygame.sprite.spritecollide(enemy, bullet_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
class Slash(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 7
self.image = slash_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
def update(self):
#move slash
self.rect.x += (self.direction * self.speed)
#check if slash has gone off screen
if self.rect.right < 0 or self.rect.left > SCREEN_WIDTH:
self.kill()
#check collision with characters
if pygame.sprite.spritecollide(enemy, slash_group, False):
if enemy.alive:
enemy.health -= 50
self.kill()
#create sprite group
bullet_group = pygame.sprite.Group()
slash_group = pygame.sprite.Group()
player = Character('Player', 200, 200, 3, 5, 20, 5)
enemy = Character('Enemy', 400, 200, 3, 5, 20, 0)
#define game variables
bg_scroll = 0
#load images
background_img = pygame.image.load('img/Background/Background.png').convert_alpha()
run = True
while run:
clock.tick(FPS)
#update background
draw_bg()
player.update()
player.draw()
enemy.update()
enemy.draw()
#update and draw groups
bullet_group.update()
slash_group.update()
bullet_group.draw(screen)
slash_group.draw(screen)
#update player actions
if player.alive:
#shoot bullets
if shoot:
player.shoot()
#throw slashes
if slash:
player.slash()
if player.in_air:
player.update_action(2) #2 means jump
elif moving_left or moving_right:
player.update_action(1) #1 means running
elif player.action == 4:
pass
else:
player.update_action(0) #0 means idle
player.move(moving_left, moving_right)
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
#mouse click
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
shoot = True
elif event.button == 3:
if player.slash_cooldown == 0: # Ensure slash is triggered only once
player.slash()
#keyboard presses
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
moving_left = True
if event.key == pygame.K_d:
moving_right = True
if event.key == pygame.K_SPACE and player.alive:
player.jump = True
if event.key == pygame.K_ESCAPE: # Exit when ESC is pressed
run = False
#keyboard relesed
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
shoot = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
moving_left = False
if event.key == pygame.K_d:
moving_right = False
pygame.display.update()
pygame.quit()
Подробнее здесь: https://stackoverflow.com/questions/793 ... ite-sprite
Анимация не работает pygame, pygame.sprite.Sprite ⇐ Python
Программы на Python
1737479206
Anonymous
Обновить решение, которое я нашел на данный момент.
Изначально я хочу запустить отдельную анимацию для способности, а затем для основной, потому что главного героя я использую как для врагов, так и для героя, но не могу понять, почему не запускается анимация отдельной способности
Я переделал ее и вставил в анимацию персонажа, но она воспроизводится слишком быстро или воспроизводится неправильно, потому что я могу видеть только первый png из последовательностей png.
Поэтому я хочу иметь отдельную способность, которую может использовать только игрок, или чтобы персонаж правильно воспроизводил анимацию.
import pygame
import os
pygame.init()
SCREEN_WIDTH = 600
SCREEN_HEIGHT = int(SCREEN_WIDTH * 0.8)
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Idle Runner')
#set framerate
clock = pygame.time.Clock()
FPS = 60
#define game variables
GRAVITY = 0.75
#define player action variables
moving_left = False
moving_right = False
shoot = False
slash = False
#load images
#bullet
bullet_img = pygame.image.load('img/icons/bullet.png').convert_alpha()
#slash
slash_img = pygame.image.load('img/icons/slash.png').convert_alpha()
#define color
BG = (144, 201, 120)
RED = (255, 0, 0)
def draw_bg():
screen.fill(BG)
pygame.draw.line(screen, RED, (0, 300), (SCREEN_WIDTH, 300))
#width = background_img.get_width()
#for x in range(5):
#screen.blit(background_img, ((x * width) - bg_scroll * 0.5, 0))
class Character(pygame.sprite.Sprite):
def __init__(self, char_type, x, y, scale, speed, mana, slashes):
pygame.sprite.Sprite.__init__(self)
self.alive = True
self.char_type = char_type
self.speed = speed
self.mana = mana
self.start_mana = mana
self.shoot_cooldown = 0
self.slash_cooldown = 0
self.slashes = slashes
self.health = 100 # for different enemy health set self.health = health and add the variable to (def __init__(self, char_type, x, y, scale, speed, mana):)
self.max_health = self.health
self.direction = 1
self.vel_y = 0
self.jump = False
self.in_air = True
self.flip = False
self.animation_list = []
self.frame_index = 0
self.action = 0
self.update_time = pygame.time.get_ticks()
#load all images for the players
animation_types = ['Idle', 'Run', 'Jump', 'Death','Slash']
for animation in animation_types:
#reset temporary list of images
temp_list = []
#count number of files in the folder
num_of_frames = len(os.listdir(f'img/{self.char_type}/{animation}'))
for i in range(num_of_frames):
img = pygame.image.load(f'img/{self.char_type}/{animation}/{i}.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
temp_list.append(img)
self.animation_list.append(temp_list)
self.image = self.animation_list[self.action][self.frame_index]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def update(self):
self.update_animation()
self.check_alive()
#update cooldown
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
if self.slash_cooldown > 0: # Reduce slash cooldown over time
self.slash_cooldown -= 1
def move(self, moving_left, moving_right):
#reset movement variables
dx = 0
dy = 0
#assign movement variables if moving left or right
if moving_left:
dx = -self.speed
self.flip = True
self.direction = -1
if moving_right:
dx = self.speed
self.flip = False
self.direction = 1
#jump
if self.jump == True and self.in_air == False:
self.vel_y = -11
self.jump = False
self.in_air = True
#apply gravity
self.vel_y += GRAVITY
if self.vel_y > 10:
self.vel_y
dy += self.vel_y
#check collision with foor
if self.rect.bottom + dy > 300:
dy = 300 - self.rect.bottom
self.in_air = False
#update rectangle position
self.rect.x += dx
self.rect.y += dy
def shoot(self):
if self.shoot_cooldown == 0 and self.mana > 0:
self.shoot_cooldown = 20
bullet = Bullet(self.rect.centerx + (0.6 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
bullet_group.add(bullet)
#reduce mana
self.mana -= 1
def slash(self):
if self.slash_cooldown == 0 and self.slashes > 0:
self.slash_cooldown = 100 # Cooldown before next slash
#self.update_action(4) # 4 corresponds to the Slash animation action
# Spawn slash attack animation
slash = Slash(self.rect.centerx + (0.5 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
slash_group.add(slash)
self.slashes -= 1 # Reduce slashes
def update_animation(self):
#update animation
ANIMATION_COOLDOWN = 150
SLASH_ANIMATION_COOLDOWN = 300
if self.action == 4: # Slash action
ANIMATION_COOLDOWN = SLASH_ANIMATION_COOLDOWN
#update image depending on the current frame
self.image = self.animation_list[self.action][self.frame_index]
#check if enough time has passed since the last update
if pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN:
self.update_time = pygame.time.get_ticks()
self.frame_index += 1
#if the animation has run out then reset back to the end
if self.frame_index >= len(self.animation_list[self.action]):
if self.action == 4: # Slash animation
self.update_action(0) # Reset to idle after slash
elif self.action == 3: # Death animation
self.frame_index = len(self.animation_list[self.action]) - 1
else:
self.frame_index = 0
def update_action(self, new_action):
#check if the new action is different to the previous one
if new_action != self.action:
self.action = new_action
#update the animation settings
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
def check_alive(self):
if self.health SCREEN_WIDTH:
self.kill()
#check collision with characters
if pygame.sprite.spritecollide(player, bullet_group, False):
if player.alive:
player.health -= 5
self.kill()
if pygame.sprite.spritecollide(enemy, bullet_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
class Slash(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 7
self.image = slash_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
def update(self):
#move slash
self.rect.x += (self.direction * self.speed)
#check if slash has gone off screen
if self.rect.right < 0 or self.rect.left > SCREEN_WIDTH:
self.kill()
#check collision with characters
if pygame.sprite.spritecollide(enemy, slash_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
#create sprite group
bullet_group = pygame.sprite.Group()
slash_group = pygame.sprite.Group()
player = Character('Player', 200, 200, 3, 5, 20, 5)
enemy = Character('Enemy', 400, 200, 3, 5, 20, 0)
#define game variables
bg_scroll = 0
#load images
background_img = pygame.image.load('img/Background/Background.png').convert_alpha()
run = True
while run:
clock.tick(FPS)
#update background
draw_bg()
player.update()
player.draw()
enemy.update()
enemy.draw()
#update and draw groups
bullet_group.update()
slash_group.update()
bullet_group.draw(screen)
slash_group.draw(screen)
#update player actions
if player.alive:
#shoot bullets
if shoot:
player.shoot()
#throw slashes
if slash:
player.update_action(4) #4 means slash attack
player.slash()
if player.in_air:
player.update_action(2) #2 means jump
elif moving_left or moving_right:
player.update_action(1) #1 means running
else:
player.update_action(0) #0 means idle
player.move(moving_left, moving_right)
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
#mouse click
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
shoot = True
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 3:
if player.slash_cooldown == 0: # Ensure slash is triggered only once
player.update_action(4)
player.slash()
#keyboard presses
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
moving_left = True
if event.key == pygame.K_d:
moving_right = True
if event.key == pygame.K_SPACE and player.alive:
player.jump = True
if event.key == pygame.K_ESCAPE: # Exit when ESC is pressed
run = False
#keyboard relesed
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
shoot = False
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 3:
slash = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
moving_left = False
if event.key == pygame.K_d:
moving_right = False
pygame.display.update()
pygame.quit()
я вижу, что анимация воспроизводится, только если здесь есть эта строка (действие обновления проигрывателя (4))
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 3:
if player.slash_cooldown == 0: # Ensure slash is triggered only once
player.update_action(4)
player.slash()
Чтобы отделить способности от персонажа, я использовал
#class Slash_attack(pygame.sprite.Sprite):
#def __init__(self, x, y, direction, scale):
#pygame.sprite.Sprite.__init__(self)
#self.update_time = pygame.time.get_ticks()
#self.images = []
#for num in range(1, 4):
# img = pygame. image.load(f'img/slash/slash{num}.png').convert_alpha()
#img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
#self.images.append(img)
#self.frame_index = 0
#self.image = self.images[self.frame_index]
#self.rect = self.image.get_rect()
#self.rect.center = (x, y)
#self.direction = direction
#self.update_time = pygame.time.get_ticks()
#def update(self):
#SLASH_COOLDOWN = 100
#if pygame.time.get_ticks() - self.update_time > SLASH_COOLDOWN:
#self.update_time = pygame.time.get_ticks()
#self.frame_index += 1
#if self.frame_index >= len(self.images):
#self.kill() # Remove slash animation
#else:
#self.image = self.images[self.frame_index]
slash_attack_group = pygame.sprite.Group()
elif slash and slash_power == False and player.slashes > 0:
slash = Slash(player.rect.centerx + (0.5 * player.rect.size[0] * player.direction), player.rect.centery, player.direction)
slash_group.add(slash)
#reduce slashes
player.slashes -= 1
slash_power = True
Мне удалось это сделать, вот полный код, если вам все еще интересно, как я это сделал.
Я изменил кнопки мыши вверх и вниз. , // if player.alive: // def update_animation(self): // def update_action(self, new_action):
import pygame
import os
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = int(SCREEN_WIDTH * 0.8)
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Idle Runner')
#set framerate
clock = pygame.time.Clock()
FPS = 60
#define game variables
GRAVITY = 0.75
#define player action variables
moving_left = False
moving_right = False
shoot = False
slash = False
#load images
#bullet
bullet_img = pygame.image.load('img/icons/bullet.png').convert_alpha()
#slash
slash_img = pygame.image.load('img/icons/slash.png').convert_alpha()
#define color
BG = (144, 201, 120)
RED = (255, 0, 0)
def draw_bg():
screen.fill(BG)
pygame.draw.line(screen, RED, (0, 300), (SCREEN_WIDTH, 300))
#width = background_img.get_width()
#for x in range(5):
#screen.blit(background_img, ((x * width) - bg_scroll * 0.5, 0))
class Character(pygame.sprite.Sprite):
def __init__(self, char_type, x, y, scale, speed, mana, slashes):
pygame.sprite.Sprite.__init__(self)
self.alive = True
self.char_type = char_type
self.speed = speed
self.mana = mana
self.start_mana = mana
self.shoot_cooldown = 0
self.slash_cooldown = 0
self.slashes = slashes
self.health = 100 # for different enemy health set self.health = health and add the variable to (def __init__(self, char_type, x, y, scale, speed, mana):)
self.max_health = self.health
self.direction = 1
self.vel_y = 0
self.jump = False
self.in_air = True
self.flip = False
self.animation_list = []
self.frame_index = 0
self.action = 0
self.update_time = pygame.time.get_ticks()
#load all images for the players
animation_types = ['Idle', 'Run', 'Jump', 'Death','Slash']
for animation in animation_types:
#reset temporary list of images
temp_list = []
#count number of files in the folder
num_of_frames = len(os.listdir(f'img/{self.char_type}/{animation}'))
for i in range(num_of_frames):
img = pygame.image.load(f'img/{self.char_type}/{animation}/{i}.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
temp_list.append(img)
self.animation_list.append(temp_list)
self.image = self.animation_list[self.action][self.frame_index]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def update(self):
self.update_animation()
self.check_alive()
#update cooldown
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
if self.slash_cooldown > 0: # Reduce slash cooldown over time
self.slash_cooldown -= 1
def move(self, moving_left, moving_right):
#reset movement variables
dx = 0
dy = 0
#assign movement variables if moving left or right
if moving_left:
dx = -self.speed
self.flip = True
self.direction = -1
if moving_right:
dx = self.speed
self.flip = False
self.direction = 1
#jump
if self.jump == True and self.in_air == False:
self.vel_y = -11
self.jump = False
self.in_air = True
#apply gravity
self.vel_y += GRAVITY
if self.vel_y > 10:
self.vel_y
dy += self.vel_y
#check collision with foor
if self.rect.bottom + dy > 300:
dy = 300 - self.rect.bottom
self.in_air = False
#update rectangle position
self.rect.x += dx
self.rect.y += dy
def shoot(self):
if self.shoot_cooldown == 0 and self.mana > 0:
self.shoot_cooldown = 20
bullet = Bullet(self.rect.centerx + (0.6 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
bullet_group.add(bullet)
#reduce mana
self.mana -= 1
def slash(self):
if self.slash_cooldown == 0 and self.slashes > 0:
self.slash_cooldown = 100 # Cooldown before next slash
# Spawn slash attack animation
slash = Slash(self.rect.centerx + (0.5 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
slash_group.add(slash)
self.slashes -= 1 # Reduce slashes
self.update_action(4)
def update_animation(self):
#update animation
ANIMATION_COOLDOWN = 100
#update image depending on current frame
self.image = self.animation_list[self.action][self.frame_index]
#check if enough time has passed since the last update
if pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN:
self.update_time = pygame.time.get_ticks()
self.frame_index += 1
#if the animation has run out the reset back to the start
if self.frame_index >= len(self.animation_list[self.action]):
if self.action == 3:
self.frame_index = len(self.animation_list[self.action]) - 1
elif self.action == 4: # Slash animation should return to idle when finished
self.update_action(0) # Return to idle animation
else:
self.frame_index = 0
def update_action(self, new_action):
if self.action == 4 and self.frame_index < len(self.animation_list[4]) - 1:
return
#check if the new action is different to the previous one
if new_action != self.action:
self.action = new_action
#update the animation settings
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
def check_alive(self):
if self.health SCREEN_WIDTH:
self.kill()
#check collision with characters
if pygame.sprite.spritecollide(player, bullet_group, False):
if player.alive:
player.health -= 5
self.kill()
if pygame.sprite.spritecollide(enemy, bullet_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
class Slash(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 7
self.image = slash_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
def update(self):
#move slash
self.rect.x += (self.direction * self.speed)
#check if slash has gone off screen
if self.rect.right < 0 or self.rect.left > SCREEN_WIDTH:
self.kill()
#check collision with characters
if pygame.sprite.spritecollide(enemy, slash_group, False):
if enemy.alive:
enemy.health -= 50
self.kill()
#create sprite group
bullet_group = pygame.sprite.Group()
slash_group = pygame.sprite.Group()
player = Character('Player', 200, 200, 3, 5, 20, 5)
enemy = Character('Enemy', 400, 200, 3, 5, 20, 0)
#define game variables
bg_scroll = 0
#load images
background_img = pygame.image.load('img/Background/Background.png').convert_alpha()
run = True
while run:
clock.tick(FPS)
#update background
draw_bg()
player.update()
player.draw()
enemy.update()
enemy.draw()
#update and draw groups
bullet_group.update()
slash_group.update()
bullet_group.draw(screen)
slash_group.draw(screen)
#update player actions
if player.alive:
#shoot bullets
if shoot:
player.shoot()
#throw slashes
if slash:
player.slash()
if player.in_air:
player.update_action(2) #2 means jump
elif moving_left or moving_right:
player.update_action(1) #1 means running
elif player.action == 4:
pass
else:
player.update_action(0) #0 means idle
player.move(moving_left, moving_right)
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
#mouse click
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
shoot = True
elif event.button == 3:
if player.slash_cooldown == 0: # Ensure slash is triggered only once
player.slash()
#keyboard presses
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
moving_left = True
if event.key == pygame.K_d:
moving_right = True
if event.key == pygame.K_SPACE and player.alive:
player.jump = True
if event.key == pygame.K_ESCAPE: # Exit when ESC is pressed
run = False
#keyboard relesed
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
shoot = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
moving_left = False
if event.key == pygame.K_d:
moving_right = False
pygame.display.update()
pygame.quit()
Подробнее здесь: [url]https://stackoverflow.com/questions/79371910/animation-not-working-pygame-pygame-sprite-sprite[/url]
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Анимация не работает pygame, pygame.sprite.Sprite
Anonymous » » в форуме PythonЯ хочу запустить отдельную анимацию для способности, а не для основной, потому что у меня есть отдельный персонаж, которого я использую и для врагов, и для героя, но я не могу понять, почему не запускается отдельная анимация способности
см. код... - 0 Ответы
- 18 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Анимация не работает pygame, pygame.sprite.Sprite
Anonymous » » в форуме PythonИзначально я хочу запустить отдельную анимацию для способности, а затем для основной, потому что главного героя я использую и для врагов, и для героя, но я не могу понять, почему не запускается отдельная анимация способностиЯ переделал его и... - 0 Ответы
- 20 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Анимация не работает pygame, pygame.sprite.Sprite
Anonymous » » в форуме PythonИзначально я хочу запустить отдельную анимацию для способности, а затем для основной, потому что главного героя я использую и для врагов, и для героя, но я не могу понять, почему не запускается отдельная анимация способностиЯ переделал его и... - 0 Ответы
- 8 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Анимация не работает pygame, pygame.sprite.Sprite
Anonymous » » в форуме PythonОбновите решение, которое я нашел на данный момент, если вы найдете какие-либо улучшения, я хотел бы взглянуть
Изначально я хочу запустить отдельную анимацию для способности, а затем основную потому что главного героя я использую и для врагов, и для... - 0 Ответы
- 14 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Имеют проблемы с проблемой компилятора: «Нет соответствующей функции для Call to 'sf :: sprite :: sprite ()» «Как я могу
Anonymous » » в форуме C++Я совершенно новичок в программировании и пытаюсь создать простую игру. У меня проблемы с SFML, но я думаю, что я установил его правильно. Это код:
#include
#include
using namespace std;
int main()
{
sf::VideoMode mode({800, 600,});... - 0 Ответы
- 6 Просмотры
-
Последнее сообщение Anonymous
-
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...