鱼C论坛

 找回密码
 立即注册
查看: 316|回复: 7

[已解决]pygame显示闪烁问题

[复制链接]
发表于 2024-2-24 22:40:54 | 显示全部楼层 |阅读模式
20鱼币
本帖最后由 flyps 于 2024-2-24 22:44 编辑
  1. import pygame
  2. import sys
  3. from pygame.locals import *
  4. pygame.init()
  5. size = width, height = 600, 400
  6. bg_colour = (255, 255, 255)
  7. fullscreen = False
  8. modes = pygame.display.list_modes()
  9. clock = pygame.time.Clock()
  10. bg = pygame.image.load("waterfall.jpg")
  11. pygame.display.set_caption("MyUndertale")
  12. bg_position = bg.get_rect()
  13. while True:
  14.     for event in pygame.event.get():
  15.         if event.type == QUIT:
  16.             sys.exit()
  17.         if event.type == KEYDOWN:
  18.             if event.key == K_F4:
  19.                 fullscreen = not fullscreen
  20.     if fullscreen:
  21.         screen = pygame.display.set_mode(modes[0], FULLSCREEN | HWSURFACE)
  22.     else:
  23.         screen = pygame.display.set_mode(size)
  24.     screen.fill(bg_colour)
  25.     screen.blit(bg, bg_position)
  26.     pygame.display.flip()
  27.     clock.tick(100)
  28.     #pygame.time.delay(10)
复制代码

问为什么程序运行以后会闪烁?在线等,急!
最佳答案
2024-2-24 22:40:55
已经找到闪烁的原因,是在循环中每循环一次都要执行的
if fullscreen:
        screen = pygame.display.set_mode(modes[0], FULLSCREEN | HWSURFACE)
    else:
        screen = pygame.display.set_mode(size)


将这部分代码移到按键判断里去,就能减少这段代码的执行次数
  1. import pygame
  2. import sys
  3. from pygame.locals import *

  4. pygame.init()
  5. size = width, height = 600, 400
  6. bg_colour = (255, 255, 255)
  7. fullscreen = False
  8. modes = pygame.display.list_modes()
  9. clock = pygame.time.Clock()
  10. bg = pygame.image.load("waterfall.jpg")
  11. pygame.display.set_caption("MyUndertale")
  12. bg_position = bg.get_rect()
  13. screen = pygame.display.set_mode(size)

  14. while True:
  15.     for event in pygame.event.get():
  16.         if event.type == QUIT:
  17.             pygame.quit()
  18.             sys.exit()
  19.         if event.type == KEYDOWN and event.key == K_F4:
  20.             fullscreen = not fullscreen
  21.             if fullscreen:
  22.                 screen = pygame.display.set_mode(modes[0], FULLSCREEN | HWSURFACE)
  23.             else:
  24.                 screen = pygame.display.set_mode(size)
  25.     screen.fill(bg_colour)
  26.     screen.blit(bg, bg_position)
  27.     pygame.display.flip()
复制代码

最佳答案

查看完整内容

已经找到闪烁的原因,是在循环中每循环一次都要执行的 将这部分代码移到按键判断里去,就能减少这段代码的执行次数

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-24 22:40:55 | 显示全部楼层    本楼为最佳答案   
已经找到闪烁的原因,是在循环中每循环一次都要执行的
if fullscreen:
        screen = pygame.display.set_mode(modes[0], FULLSCREEN | HWSURFACE)
    else:
        screen = pygame.display.set_mode(size)


将这部分代码移到按键判断里去,就能减少这段代码的执行次数
  1. import pygame
  2. import sys
  3. from pygame.locals import *

  4. pygame.init()
  5. size = width, height = 600, 400
  6. bg_colour = (255, 255, 255)
  7. fullscreen = False
  8. modes = pygame.display.list_modes()
  9. clock = pygame.time.Clock()
  10. bg = pygame.image.load("waterfall.jpg")
  11. pygame.display.set_caption("MyUndertale")
  12. bg_position = bg.get_rect()
  13. screen = pygame.display.set_mode(size)

  14. while True:
  15.     for event in pygame.event.get():
  16.         if event.type == QUIT:
  17.             pygame.quit()
  18.             sys.exit()
  19.         if event.type == KEYDOWN and event.key == K_F4:
  20.             fullscreen = not fullscreen
  21.             if fullscreen:
  22.                 screen = pygame.display.set_mode(modes[0], FULLSCREEN | HWSURFACE)
  23.             else:
  24.                 screen = pygame.display.set_mode(size)
  25.     screen.fill(bg_colour)
  26.     screen.blit(bg, bg_position)
  27.     pygame.display.flip()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-24 22:41:20 | 显示全部楼层
闪烁问题可能是由于两个原因导致的,一个是更新屏幕时屏幕被清空以及重新绘制,另一个是程序运行速度过快。

首先,我们来解决屏幕被清空和重新绘制的问题。在你的代码中,每次循环开始时,你都使用`screen.fill(bg_colour)`来填充整个屏幕,这会导致屏幕上之前绘制的图像被清空。为了避免这种情况,你可以将`screen.fill(bg_colour)`移动到while循环的外面,并且在循环内部只更新你想要绘制的图像。修改后的代码如下:

  1. while True:
  2.     for event in pygame.event.get():
  3.         if event.type == QUIT:
  4.             sys.exit()
  5.         if event.type == KEYDOWN:
  6.             if event.key == K_F4:
  7.                 fullscreen = not fullscreen
  8.     if fullscreen:
  9.         screen = pygame.display.set_mode(modes, FULLSCREEN | HWSURFACE)
  10.     else:
  11.         screen = pygame.display.set_mode(size)
  12.     screen.fill(bg_colour)  # 将填充屏幕的操作放到循环外面
  13.     screen.blit(bg, bg_position)
  14.     pygame.display.flip()
  15.     clock.tick(100)
  16.     #pygame.time.delay(10)
复制代码


接下来,我们来解决程序运行速度过快的问题。在你的代码中,你使用了`clock.tick(100)`来限制帧率为100帧/秒,但是这个方法无法保证达到精确的帧率,而且在有些系统上可能会导致闪烁。我建议你使用`pygame.time.delay(10)`来在每一次循环后延迟10毫秒,这样可以降低程序运行速度,减少闪烁的可能性。

修改后的代码如下:

  1. while True:
  2.     for event in pygame.event.get():
  3.         if event.type == QUIT:
  4.             sys.exit()
  5.         if event.type == KEYDOWN:
  6.             if event.key == K_F4:
  7.                 fullscreen = not fullscreen
  8.     if fullscreen:
  9.         screen = pygame.display.set_mode(modes, FULLSCREEN | HWSURFACE)
  10.     else:
  11.         screen = pygame.display.set_mode(size)
  12.     screen.fill(bg_colour)
  13.     screen.blit(bg, bg_position)
  14.     pygame.display.flip()
  15.     # clock.tick(100)  # 注释掉这行
  16.     pygame.time.delay(10)  # 添加延迟
复制代码


希望以上修改能够解决你的闪烁问题!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-2-24 22:48:05 | 显示全部楼层
FishC 发表于 2024-2-24 22:41
闪烁问题可能是由于两个原因导致的,一个是更新屏幕时屏幕被清空以及重新绘制,另一个是程序运行速度过快。 ...

没用啊,能根据问题一继续修改吗?

评分

参与人数 1鱼币 +5 收起 理由
歌者文明清理员 + 5

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-24 22:48:25 | 显示全部楼层
flyps 发表于 2024-02-24 22:48
没用啊,能根据问题一继续修改吗?


抱歉没有为您解决问题。根据您的反馈,我注意到您的背景图像是`bg = pygame.image.load("waterfall.jpg")`,而在每一次循环中,您都使用`screen.blit(bg, bg_position)`将整个图像绘制到屏幕上。这可能导致闪烁问题,因为每次循环开始时,都会重新绘制整个图像。

为了解决这个问题,您可以尝试使用`pygame.Surface`对象作为画布,并在每次循环中只绘制变化的部分。代码如下:

  1. import pygame
  2. import sys
  3. from pygame.locals import *

  4. pygame.init()

  5. size = width, height = 600, 400
  6. bg_colour = (255, 255, 255)
  7. fullscreen = False
  8. modes = pygame.display.list_modes()
  9. clock = pygame.time.Clock()

  10. bg = pygame.image.load("waterfall.jpg")
  11. bg_position = bg.get_rect()

  12. canvas = pygame.Surface(size)  # 创建画布

  13. while True:
  14.     for event in pygame.event.get():
  15.         if event.type == QUIT:
  16.             sys.exit()
  17.         if event.type == KEYDOWN:
  18.             if event.key == K_F4:
  19.                 fullscreen = not fullscreen

  20.     if fullscreen:
  21.         screen = pygame.display.set_mode(modes, FULLSCREEN | HWSURFACE)
  22.     else:
  23.         screen = pygame.display.set_mode(size)

  24.     canvas.fill(bg_colour)  # 在画布上填充背景颜色
  25.     canvas.blit(bg, bg_position)  # 绘制背景图像到画布上

  26.     screen.blit(canvas, (0, 0))  # 将画布绘制到屏幕上
  27.     pygame.display.flip()
  28.     clock.tick(100)
复制代码


通过这样的修改,您只需要在循环中更新画布上的变动部分,而不是每次都重新绘制整个图像。希望这次能解决您的闪烁问题!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-2-24 22:52:05 | 显示全部楼层
FishC 发表于 2024-2-24 22:48
抱歉没有为您解决问题。根据您的反馈,我注意到您的背景图像是`bg = pygame.image.load("waterfall.jpg ...

还是不行啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-24 22:52:35 | 显示全部楼层


非常抱歉我的解决方案没有解决您的问题。闪烁问题可能是由于不同的原因引起的,这需要进一步的调试和排查。以下是几种可能的原因和解决方案:

1. 双缓冲技术:尝试使用双缓冲技术来减少闪烁。在你的代码中,创建一个额外的`pygame.Surface`对象,称为backbuffer。在每次循环中,首先绘制所有的图像到backbuffer上,然后将backbuffer一次性地绘制到屏幕上。这样可以避免在屏幕上的可见更新过程中出现闪烁。以下是修改的示例代码:

  1. import pygame
  2. import sys
  3. from pygame.locals import *

  4. pygame.init()
  5. size = width, height = 600, 400
  6. bg_colour = (255, 255, 255)
  7. fullscreen = False
  8. modes = pygame.display.list_modes()
  9. clock = pygame.time.Clock()
  10. bg = pygame.image.load("waterfall.jpg")
  11. bg_position = bg.get_rect()

  12. # 创建 backbuffer
  13. backbuffer = pygame.Surface(size)

  14. while True:
  15.     for event in pygame.event.get():
  16.         if event.type == QUIT:
  17.             sys.exit()
  18.         if event.type == KEYDOWN:
  19.             if event.key == K_F4:
  20.                 fullscreen = not fullscreen

  21.     if fullscreen:
  22.         screen = pygame.display.set_mode(modes, FULLSCREEN | HWSURFACE)
  23.     else:
  24.         screen = pygame.display.set_mode(size)

  25.     backbuffer.fill(bg_colour)  # 在 backbuffer 上填充背景颜色
  26.     backbuffer.blit(bg, bg_position)  # 绘制背景图像到 backbuffer 上

  27.     screen.blit(backbuffer, (0, 0))  # 将 backbuffer 绘制到屏幕上
  28.     pygame.display.flip()
复制代码


2. 使用硬件加速:尝试使用硬件加速模式,以实现更平滑的绘制。在创建窗口时,将`screen`对象的标志位设置为`HWSURFACE`,这可以充分利用硬件来进行绘制:

  1. screen = pygame.display.set_mode(size, HWSURFACE)
复制代码


3. 降低帧率:减少程序的帧率可能会减少闪烁。可以尝试调整`clock.tick()`中的值,或者使用`pygame.time.delay()`在每一次循环中添加延迟。

如果以上解决方案仍然无法解决您的问题,我建议您检查您的硬件和驱动程序是否正常运行,并确保您的图像文件没有任何问题。另外,您还可以尝试在其他机器上运行您的代码,以查看是否存在特定于您当前计算机的问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-25 12:28:11 | 显示全部楼层
你这看起来没问题啊把waterfall.jpg发过来,我运行试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 21:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表