科普:Pygame 中,`pg.Surface` v.s. `screen`
在 Pygame 中,pg.Surface
和 screen
是两个紧密相关但概念不同的对象,核心区别在于:pg.Surface
是通用的“图像容器”(画布),而 screen
是特殊的 Surface
,专门用于最终显示到屏幕上。
1. pg.Surface
:通用的“画布”或“图像容器”
pg.Surface
是 Pygame 中最基础的图像类,本质是一个像素数据的容器,可以理解为一块“内存中的画布”。它的核心作用是:
- 绘制图形(矩形、圆形等)、文字或加载图片;
- 存储图像数据(如精灵的
image
属性就是一个Surface
); - 实现“离屏渲染”(先在内存中绘制,再一次性显示到屏幕)。
特点:
- 可以创建多个
Surface
对象(如一个用于玩家图像,一个用于背景,一个用于临时特效); - 自身不会直接显示在屏幕上,其内容需要通过
blit()
方法“复制”到screen
上才会被用户看到; - 支持所有绘图操作(
fill()
填充颜色、draw
绘制图形、blit()
粘贴其他图像等)。
示例:
import pygame as pg
pg.init()# 创建一个 200x200 的红色 Surface(内存中的画布)
my_surface = pg.Surface((200, 200))
my_surface.fill((255, 0, 0)) # 填充红色# 创建一个 30x30 的蓝色小 Surface
small_surface = pg.Surface((30, 30))
small_surface.fill((0, 0, 255)) # 填充蓝色# 将小 Surface 粘贴到 my_surface 上(坐标 (50,50))
my_surface.blit(small_surface, (50, 50))
2. screen
:关联屏幕的“显示表面”
screen
是通过 pg.display.set_mode()
创建的特殊 Surface
对象,它是唯一直接与物理屏幕关联的表面。所有最终需要显示给用户的内容,必须绘制到 screen
上(或通过它间接显示)。
特点:
- 一个游戏通常只创建一个
screen
(对应一个窗口或全屏显示); - 其尺寸由
pg.display.set_mode((width, height))
决定,即窗口/屏幕的分辨率; - 调用
pg.display.flip()
或pg.display.update()
时,screen
上的内容会被刷新到物理屏幕上; - 本质上是
pg.Surface
的子类,因此支持所有Surface
的方法(fill()
、blit()
等)。
示例:
# 创建屏幕(800x600 分辨率),返回的 screen 是一个特殊的 Surface
screen = pg.display.set_mode((800, 600))# 可以像操作普通 Surface 一样操作 screen
screen.fill((0, 0, 0)) # 填充黑色背景# 将前面创建的 my_surface 粘贴到 screen 上(坐标 (100, 100))
screen.blit(my_surface, (100, 100))# 刷新屏幕,使 screen 上的内容显示出来
pg.display.flip()
核心区别
维度 | pg.Surface (普通表面) | screen (显示表面) |
---|---|---|
本质 | 内存中的通用画布,用于存储/绘制图像 | 与物理屏幕关联的特殊 Surface ,用于最终显示 |
数量 | 可创建多个(按需创建) | 通常只创建一个(对应一个窗口/屏幕) |
显示方式 | 需通过 blit() 复制到 screen 才会显示 | 调用 flip() /update() 后直接显示到物理屏幕 |
用途 | 存储图像、离屏渲染、精灵图像等 | 作为最终显示的“载体”,所有可见内容必须绘制到这里 |
关键关系
screen
是 pg.Surface
的一种特殊实例(继承关系),因此它拥有 pg.Surface
的所有方法(fill()
、blit()
等)。两者的关系类似:pg.Surface
是“草稿纸”,screen
是“最终要展示给观众的画框”——草稿纸上的内容需要复制到画框里,才能被看到。
例如,游戏中精灵的 image
是 Surface
(存储精灵外观),精灵组的 draw(screen)
方法本质是将所有精灵的 image
(Surface
)通过 blit()
复制到 screen
上,最后通过 flip()
刷新显示。
代码示例
我们可以用“画画”的场景类比:pg.Surface
就像“草稿纸”,screen
就像“画展的展示墙”。 可总结为如下三步曲:
- 你会先在草稿纸上画好细节(
Surface
上绘制内容), - 最后把草稿纸上的画贴到展示墙上(
blit
到screen
), - 观众才能看到(
flip()
刷新后显示)。
import pygame as pg
pg.init()# 1. 创建“展示墙”(screen,特殊的Surface,关联屏幕)
screen = pg.display.set_mode((400, 300)) # 窗口大小400x300
pg.display.set_caption("Surface vs screen 示例")# 2. 创建“草稿纸1”(普通Surface,内存中的画布)
# 画一个200x200的红色方块
red_surface = pg.Surface((200, 200))
red_surface.fill((255, 0, 0)) # 红色填充# 3. 创建“草稿纸2”(普通Surface)
# 画一个50x50的蓝色小圆
blue_surface = pg.Surface((50, 50), pg.SRCALPHA) # 带透明通道
pg.draw.circle(blue_surface, (0, 0, 255), (25, 25), 25) # 蓝色圆形# 4. 在“草稿纸1”上贴“草稿纸2”(红色方块上贴蓝色圆)
red_surface.blit(blue_surface, (80, 80)) # 坐标(80,80)# 5. 把“草稿纸1”贴到“展示墙”上(screen)
screen.blit(red_surface, (100, 50)) # 坐标(100,50)# 6. 刷新“展示墙”,让观众看到最终画面
pg.display.flip()# 保持窗口打开
running = True
while running:for event in pg.event.get():if event.type == pg.QUIT:running = False
pg.quit()
效果类比
red_surface
和blue_surface
是普通Surface
(草稿纸): 草稿纸是“透明的”,即草稿纸“贴到”另一草稿纸上时,仅考虑图片的叠放。Surface
(草稿纸)只在内存中处理,即使你在上面画了内容,不贴到screen
上也看不到。screen
是特殊Surface
(展示墙):需要显示的内容都要通过这里“贴”的方式, 贴到screen
上。- 只有贴到
screen
上的内容,经过pg.display.flip()
刷新后,才能显示在窗口中被你看到。