鱼C论坛

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

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

[复制链接]
发表于 2024-2-24 22:40:54 | 显示全部楼层 |阅读模式
20鱼币
本帖最后由 flyps 于 2024-2-24 22:44 编辑
import pygame
import sys
from pygame.locals import *
pygame.init()
size = width, height = 600, 400
bg_colour = (255, 255, 255)
fullscreen = False
modes = pygame.display.list_modes()
clock = pygame.time.Clock()
bg = pygame.image.load("waterfall.jpg")
pygame.display.set_caption("MyUndertale")
bg_position = bg.get_rect()
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_F4:
                fullscreen = not fullscreen
    if fullscreen:
        screen = pygame.display.set_mode(modes[0], FULLSCREEN | HWSURFACE)
    else:
        screen = pygame.display.set_mode(size)
    screen.fill(bg_colour)
    screen.blit(bg, bg_position)
    pygame.display.flip()
    clock.tick(100)
    #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)


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

pygame.init()
size = width, height = 600, 400
bg_colour = (255, 255, 255)
fullscreen = False
modes = pygame.display.list_modes()
clock = pygame.time.Clock()
bg = pygame.image.load("waterfall.jpg")
pygame.display.set_caption("MyUndertale")
bg_position = bg.get_rect()
screen = pygame.display.set_mode(size)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN and event.key == K_F4:
            fullscreen = not fullscreen
            if fullscreen:
                screen = pygame.display.set_mode(modes[0], FULLSCREEN | HWSURFACE)
            else:
                screen = pygame.display.set_mode(size)
    screen.fill(bg_colour)
    screen.blit(bg, bg_position)
    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)


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

pygame.init()
size = width, height = 600, 400
bg_colour = (255, 255, 255)
fullscreen = False
modes = pygame.display.list_modes()
clock = pygame.time.Clock()
bg = pygame.image.load("waterfall.jpg")
pygame.display.set_caption("MyUndertale")
bg_position = bg.get_rect()
screen = pygame.display.set_mode(size)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN and event.key == K_F4:
            fullscreen = not fullscreen
            if fullscreen:
                screen = pygame.display.set_mode(modes[0], FULLSCREEN | HWSURFACE)
            else:
                screen = pygame.display.set_mode(size)
    screen.fill(bg_colour)
    screen.blit(bg, bg_position)
    pygame.display.flip()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

首先,我们来解决屏幕被清空和重新绘制的问题。在你的代码中,每次循环开始时,你都使用`screen.fill(bg_colour)`来填充整个屏幕,这会导致屏幕上之前绘制的图像被清空。为了避免这种情况,你可以将`screen.fill(bg_colour)`移动到while循环的外面,并且在循环内部只更新你想要绘制的图像。修改后的代码如下:
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_F4:
                fullscreen = not fullscreen
    if fullscreen:
        screen = pygame.display.set_mode(modes, FULLSCREEN | HWSURFACE)
    else:
        screen = pygame.display.set_mode(size)
    screen.fill(bg_colour)  # 将填充屏幕的操作放到循环外面
    screen.blit(bg, bg_position)
    pygame.display.flip()
    clock.tick(100)
    #pygame.time.delay(10)

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

修改后的代码如下:
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_F4:
                fullscreen = not fullscreen
    if fullscreen:
        screen = pygame.display.set_mode(modes, FULLSCREEN | HWSURFACE)
    else:
        screen = pygame.display.set_mode(size)
    screen.fill(bg_colour)
    screen.blit(bg, bg_position)
    pygame.display.flip()
    # clock.tick(100)  # 注释掉这行
    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`对象作为画布,并在每次循环中只绘制变化的部分。代码如下:
import pygame
import sys
from pygame.locals import *

pygame.init()

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

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

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

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_F4:
                fullscreen = not fullscreen

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

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

    screen.blit(canvas, (0, 0))  # 将画布绘制到屏幕上
    pygame.display.flip()
    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一次性地绘制到屏幕上。这样可以避免在屏幕上的可见更新过程中出现闪烁。以下是修改的示例代码:
import pygame
import sys
from pygame.locals import *

pygame.init()
size = width, height = 600, 400
bg_colour = (255, 255, 255)
fullscreen = False
modes = pygame.display.list_modes()
clock = pygame.time.Clock()
bg = pygame.image.load("waterfall.jpg")
bg_position = bg.get_rect()

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

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_F4:
                fullscreen = not fullscreen

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

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

    screen.blit(backbuffer, (0, 0))  # 将 backbuffer 绘制到屏幕上
    pygame.display.flip()

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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