Python pygame动画精灵表
我想创建一个自上而下的RPG在pygame使用精灵表 例如,我希望能够按空格键进行攻击,这将触发攻击动画,然后恢复正常Python pygame动画精灵表,python,animation,pygame,sprite-sheet,Python,Animation,Pygame,Sprite Sheet,我想创建一个自上而下的RPG在pygame使用精灵表 例如,我希望能够按空格键进行攻击,这将触发攻击动画,然后恢复正常 import pygame from pygame.locals import * pygame.init() image = pygame.image.load("sprite_sheet.png") clock = pygame.time.Clock() screen = pygame.display.set_mode((400, 250)) class Pla
import pygame
from pygame.locals import *
pygame.init()
image = pygame.image.load("sprite_sheet.png")
clock = pygame.time.Clock()
screen = pygame.display.set_mode((400, 250))
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.current_animation = 0
self.max_animation = 5
self.animation_cooldown = 150
self.last_animation = pygame.time.get_ticks()
self.status = {"prev": "standing",
"now": "standing"}
def animate_attack(self):
time_now = pygame.time.get_ticks()
if time_now - self.last_animation >= self.animation_cooldown:
self.last_animation = pygame.time.get_ticks()
if self.current_animation == self.max_animation:
self.current_animation = 0
joshua.status["now"] = joshua.status["prev"]
else:
self.current_animation += 1
joshua = Player()
while True:
screen.fill(0)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
joshua.status["prev"] = joshua.status["now"]
joshua.status["now"] = "attacking"
if joshua.status["now"] == "attacking":
joshua.animate_attack()
screen.blit(image, (0, 0), (joshua.current_animation * 64, 0, 64, 64))
pygame.display.flip()
clock.tick(60)
上面的代码就是我所拥有的。如果我按一次空格键,它将通过动画并停止,但如果我按两次空格键,它将循环,因为它是如何编程的
希望获得动画方面的帮助,谢谢当第二次按空格键时,问题是由以下调用引起的:
joshua.status["prev"] = joshua.status["now"]
这将“上一个”和“现在”状态设置为“攻击”。
因此,当在animate_attack()
方法中重置状态时,
它将保持“攻击性”:
作为一种快速修复方法,请确保仅在尚未设置状态时才更改状态:
if event.key == pygame.K_SPACE:
if not joshua.status["now"] == "attacking":
joshua.status["prev"] = joshua.status["now"]
joshua.status["now"] = "attacking"
作为更好的修复方法,您应该封装状态,
因此,只有Player类处理自己的状态,例如:
class Player():
def __init__(self):
self.current_animation = 0
self.max_animation = 5
self.animation_cooldown = 150
self.last_animation = pygame.time.get_ticks()
self.status = "standing" # Simplified state
def attack(self):
self.status = "attacking"
def animate_attack(self):
if self.status == "attacking":
time_now = pygame.time.get_ticks()
if time_now - self.last_animation >= self.animation_cooldown:
self.last_animation = pygame.time.get_ticks()
if self.current_animation == self.max_animation:
self.current_animation = 0
self.status = "standing" # Reset state
else:
self.current_animation += 1
这样,就不需要知道任何关于类外状态的信息:
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
joshua.attack()
joshua.animate_attack()
screen.fill(0)
screen.blit(image, (0, 0), (joshua.current_animation * 64, 0, 64, 64))
pygame.display.flip()
clock.tick(60)
非常感谢你。假设我有WASD的控件,并尝试通过将状态设置为“left”向左移动来移动。如果我在攻击中,点击W,它会覆盖攻击并停止动画。在触发另一个事件之前,是否有办法使动画完成?您可以使用单独的状态变量,例如
self.movement
(“站立”、“左”、…)和self.attacking
(真、假)。这样,可以独立于攻击状态更新移动状态。对于动画,如果self.attacking
为真,则计算当前攻击帧,否则为当前移动使用适当的帧。
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
joshua.attack()
joshua.animate_attack()
screen.fill(0)
screen.blit(image, (0, 0), (joshua.current_animation * 64, 0, 64, 64))
pygame.display.flip()
clock.tick(60)