You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:25:00