使用PyGame SDL2渲染单个绿色像素报错问题求助
问题原因与解决方案
错误原因
SDL2渲染器(pygame._sdl2.Renderer)的blit方法不支持直接传入普通的pygame.Surface对象,它要求传入的源必须是SDL2兼容的可绘制对象(比如pygame._sdl2.Texture),这就是报错TypeError: source must be drawable的核心原因。
解决方案
有两种可行的修正方式:
方式一:将普通Surface转换为SDL2 Texture
把你创建的green_pixel Surface转换成SDL2渲染器能识别的Texture,再进行blit操作:
import pygame import pygame._sdl2 SCREEN_W = 800 SCREEN_H = 800 pygame.init() pygame_screen = pygame.display.set_mode((SCREEN_W, SCREEN_H), vsync=0, flags=pygame.SCALED) window = pygame._sdl2.Window.from_display_module() renderer = pygame._sdl2.Renderer.from_window(window) renderer.draw_color = (0, 255, 0, 255) # 设置绘制颜色为绿色 clock = pygame.time.Clock() scale_factor = 1 # 创建绿色Surface并转换为SDL2 Texture green_pixel = pygame.Surface((scale_factor, scale_factor)) green_pixel.fill((0, 255, 0, 255)) # 关键:将Surface转为SDL2 Texture green_texture = pygame._sdl2.Texture.from_surface(renderer, green_pixel) use_sdl2 = True while True: msec = clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if use_sdl2: renderer.clear() dest_rect = pygame.rect.Rect(100, 100, scale_factor, scale_factor) # 使用Texture进行blit renderer.blit(green_texture, dest_rect) renderer.present() else: pygame_screen.fill((0, 0, 0)) dest_rect = pygame.rect.Rect(100, 100, scale_factor, scale_factor) pygame_screen.blit(green_pixel, dest_rect) pygame.display.flip()
方式二:直接使用Renderer绘制点(更高效)
如果只是渲染单个像素,没必要创建Surface和Texture,直接用SDL2渲染器的draw_point方法即可:
import pygame import pygame._sdl2 SCREEN_W = 800 SCREEN_H = 800 pygame.init() pygame_screen = pygame.display.set_mode((SCREEN_W, SCREEN_H), vsync=0, flags=pygame.SCALED) window = pygame._sdl2.Window.from_display_module() renderer = pygame._sdl2.Renderer.from_window(window) renderer.draw_color = (0, 255, 0, 255) # 设置绘制颜色为绿色 clock = pygame.time.Clock() scale_factor = 1 use_sdl2 = True while True: msec = clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if use_sdl2: renderer.clear() # 直接绘制单个点,坐标(100,100) renderer.draw_point((100, 100)) renderer.present() else: pygame_screen.fill((0, 0, 0)) dest_rect = pygame.rect.Rect(100, 100, scale_factor, scale_factor) green_pixel = pygame.Surface((scale_factor, scale_factor)) green_pixel.fill((0, 255, 0, 255)) pygame_screen.blit(green_pixel, dest_rect) pygame.display.flip()
注意:SDL2渲染模式下不需要再调用pygame_screen.fill((0,0,0)),因为renderer.clear()已经会清空画面。
内容的提问来源于stack exchange,提问作者Thegerdfather
相关产品推荐
相关产品推荐

