以不同的帧率呈现图像,而不是游戏窗口。

huangapple go评论110阅读模式
英文:

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(&#39;assets/Explosion/E_1.png&#39;), pygame.image.load(&#39;assets/Explosion/E_2.png&#39;),
                pygame.image.load(&#39;assets/Explosion/E_3.png&#39;), pygame.image.load(&#39;assets/Explosion/E_4.png&#39;),
                pygame.image.load(&#39;assets/Explosion/E_5.png&#39;), pygame.image.load(&#39;assets/Explosion/E_6.png&#39;),
                pygame.image.load(&#39;assets/Explosion/E_7.png&#39;), pygame.image.load(&#39;assets/Explosion/E_8.png&#39;))
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(&#39;#000000&#39;)
    for animation in animations[:]:
        animation[1] += 1
        frame_index = animation[1] // animate_frames
        if frame_index &lt; 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?

huangapple
  • 本文由 发表于 2023年3月12日 16:56:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定