英文:
Rendering Images At a Different Framerate Than The Game Window
问题
我需要在每次单击鼠标按钮时播放动画。
我将帧存储在一个列表中,对于Pygame渲染的每一帧,列表中的一帧被“blit”到屏幕上。
我的问题是,因为这发生在每一帧,所以动画以每秒1000帧的速度播放,即使只有8帧,因此动画几乎不可见。是否有办法以每秒16帧的速度运行动画,同时仍然允许Pygame以正常速度运行游戏循环?我有一个需要以Pygame的正常渲染速度运行的游戏,但动画应该播放得更慢。
以下是我当前正在做的示例:
pygame.init()
screen = pygame.display.set_mode((800, 600))
running = True
while running:
screen.fill('#000000')
mouse_pos = pygame.mouse.get_pos()
explosion = (pygame.image.load('assets/Explosion/E_1.png'), pygame.image.load('assets/Explosion/E_2.png'),
pygame.image.load('assets/Explosion/E_3.png'), pygame.image.load('assets/Explosion/E_4.png'),
pygame.image.load('assets/Explosion/E_5.png'), pygame.image.load('assets/Explosion/E_6.png'),
pygame.image.load('assets/Explosion/E_7.png'), pygame.image.load('assets/Explosion/E_8.png'))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
for frame in explosion:
framerect = frame.get_rect(center=mouse_pos)
screen.blit(frame, framerect)
pygame.display.update()
pygame.quit()
英文:
I have an animation I need to play every time the mouse button is clicked.
I have the frames stored in a list, for every frame that Pygame renders, one frame in the list is blit
to the screen.
My issue is that because this happens every frame, the animation is played at 1000fps, even though there are only 8 frames, so the animation is unnoticeable. Is there any way to run the animation at 16fps while still allowing Pygame to run through the game loop at normal speeds? I have a game that needs to be run at Pygame's normal render speed but the animations should be played slower.
Here is an example of what I am currently doing:
pygame.init()
screen = pygame.display.set_mode((800, 600))
running = True
while running:
screen.fill('#000000')
mouse_pos = pygame.mouse.get_pos()
explosion = (pygame.image.load('assets/Explosion/E_1.png'), pygame.image.load('assets/Explosion/E_2.png'),
pygame.image.load('assets/Explosion/E_3.png'), pygame.image.load('assets/Explosion/E_4.png'),
pygame.image.load('assets/Explosion/E_5.png'), pygame.image.load('assets/Explosion/E_6.png'),
pygame.image.load('assets/Explosion/E_7.png'), pygame.image.load('assets/Explosion/E_8.png'))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
for frame in explosion:
framerect = frame.get_rect(center=mouse_pos)
screen.blit(frame, framerect)
pygame.display.update()
pygame.quit()
答案1
得分: 2
以下是您要翻译的内容:
"Actually, the animation is rendered in 1 frame because you render the animations in a for loop inside the application loop. You need to use the application loop. Limit the number of frames with pygame.time.Clock.tick
and load the frames once before the application loop to improve performance.
In the following example, clock.tick(100)
sets the frames per second, and animate_frames = 10
defines how many frames of animation will be displayed:
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
try:
explosion = (pygame.image.load('assets/Explosion/E_1.png'), pygame.image.load('assets/Explosion/E_2.png'),
pygame.image.load('assets/Explosion/E_3.png'), pygame.image.load('assets/Explosion/E_4.png'),
pygame.image.load('assets/Explosion/E_5.png'), pygame.image load('assets/Explosion/E_6.png'),
pygame.image.load('assets/Explosion/E_7.png'), pygame.image.load('assets/Explosion/E_8.png'))
except:
explosion = []
for i in range(10):
e = pygame.Surface((100, 100), pygame.SRCALPHA)
pygame.draw.circle(e, (200 - i * 10, 200 - i * 20, 0), (50, 50), i*5)
explosion.append(e)
clock = pygame.time.Clock()
animate_frames = 10
animations = []
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
animations.append([event.pos, 0])
screen.fill('#000000')
for animation in animations[:]:
animation[1] += 1
frame_index = animation[1] // animate_frames
if frame_index < len(explosion):
frame = explosion[frame_index]
framerect = frame.get_rect(center=animation[0])
screen.blit(frame, framerect)
else:
animations.remove(animation)
pygame.display.update()
clock.tick(100)
pygame.quit()
Also see How can I show explosion image when collision happens?
英文:
Actually, the animation is rendered in 1 frame because you render the animations in a for loop inside the application loop. You need to use the application loop. Limit the number of frames with pygame.time.Clock.tick
and load the frames once before the application loop to improve performance.
In the following example, clock.tick(100)
sets the frames per second, and animate_frames = 10
defines how many frames of animation will be displayed:
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
try:
explosion = (pygame.image.load('assets/Explosion/E_1.png'), pygame.image.load('assets/Explosion/E_2.png'),
pygame.image.load('assets/Explosion/E_3.png'), pygame.image.load('assets/Explosion/E_4.png'),
pygame.image.load('assets/Explosion/E_5.png'), pygame.image.load('assets/Explosion/E_6.png'),
pygame.image.load('assets/Explosion/E_7.png'), pygame.image.load('assets/Explosion/E_8.png'))
except:
explosion = []
for i in range(10):
e = pygame.Surface((100, 100), pygame.SRCALPHA)
pygame.draw.circle(e, (200 - i * 10, 200 - i * 20, 0), (50, 50), i*5)
explosion.append(e)
clock = pygame.time.Clock()
animate_frames = 10
animations = []
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
exit()
if event.type == pygame.MOUSEBUTTONDOWN:
animations.append([event.pos, 0])
screen.fill('#000000')
for animation in animations[:]:
animation[1] += 1
frame_index = animation[1] // animate_frames
if frame_index < len(explosion):
frame = explosion[frame_index]
framerect = frame.get_rect(center=animation[0])
screen.blit(frame, framerect)
else:
animations.remove(animation)
pygame.display.update()
clock.tick(100)
pygame.quit()
Also see How can I show explosion image when collision happens?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论