鱼C论坛

 找回密码
 立即注册
查看: 31|回复: 3

[技术交流] (Pygame)一种很新的表示颜色的方法

[复制链接]
发表于 昨天 22:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
rt.

众所周知,pygame允许这样表示颜色:

(0, 0, 0) -------- BLACK
(255, 0, 0) ----- RED
(0, 0, 255) ----- BLUE

也许你知道也可以直接这样:
'black'
'red'
'blue'

也许你又知道还能这样:(注意!!!不能用'#000'之类的表示)
'#000000' ----- BLACK
'#ff8000' ------ ORANGE
'#ffc0c0' ------- PINK
'#ffffff' -------- WHITE

更冷门的:
0x000000 (0) ------------ BLACK
0x808080 ---------------- GRAY
0xc0c0c0 ----------------- LIGHT GRAY
0x00c0c0 (0xc0c0) ----- DRAK CYAN

但你绝对不知道:(仅用于 convert_alpha() ed 的 Surface)*ed:表示过去式

0x00000000 (0) --------------- TRANSPARENT
0x000000ff (0xff) ------------- BLACK
0x00800080 (0x800080) ----- HALF TRANSPARENT GREEN
0x40404040 -------------------- 透明度 1/4 的深灰色(透明度为 1 表示不透明,透明度为 0 表示完全透明)
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 15 分钟前 | 显示全部楼层
经测试,最后一个 convert_alpha() 之后有时候可以用有时候不能用,很神奇
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 22:32 | 显示全部楼层
在Pygame中,对于经过 convert_alpha() 处理的 Surface,颜色可以使用32位十六进制整数表示,格式为 0xRRGGBBAA。其中 RR、GG、BB 分别代表红、绿、蓝分量(各8位,范围00-FF),AA 代表 Alpha 透明度分量(00 表示完全透明,FF 表示不透明)。这种表示法特别适用于带有 Alpha 通道的 Surface。

例如:
  1. 0x00000000  # 完全透明(Alpha=0)
  2. 0x000000ff  # 不透明黑色(RGB=0, Alpha=255)
  3. 0x00800080  # 半透明绿色(RGB=0,128,0, Alpha=128)
  4. 0x40404040  # 透明度1/4的深灰色(RGB=64,64,64, Alpha=64)
复制代码


注意:此方法仅适用于支持 Alpha 通道的 Surface(通常由 convert_alpha() 创建),常用于像素级操作如 Surface.set_at()Surface.get_at()。对于常规颜色设置,使用 RGBA 元组(如 (0,0,0,255))更为常见。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 14 分钟前 | 显示全部楼层
player-none 发表于 2026-03-08 08:18
经测试,最后一个有时候可以用有时候不能用,很神奇{: ...


你的观察很准确!这确实是一个常见但容易混淆的地方。根本原因在于 Surface 的像素格式不同,导致对 32 位整数颜色的解析方式不同。

简单来说,问题在于 **Pygame 对于传入的整数颜色值,如何解释取决于目标 Surface 的像素格式。**

下面详细解释这个“时灵时不灵”的现象:

核心原因:Surface 的“深度”

Pygame 的 Surface 有不同的“位深”(bits per pixel)。我们主要关注两种:
- 24 位深度 (RGB):每个像素用 24 位(3字节)表示,分别是红、绿、蓝。没有 Alpha 通道。通过 convert() 或默认创建的 Surface 通常是这种。
- 32 位深度 (RGBA 或 ARGB):每个像素用 32 位(4字节)表示,包含红、绿、蓝和 Alpha 通道。通过 convert_alpha() 创建的 Surface 通常是这种。

整数颜色值如何被解释?
当你传入一个整数(如 0x40404040)时,Pygame 会将它写入目标 Surface 的内存中。关键在于:
- 如果目标 Surface 是 32 位(RGBA),这个整数会被直接当作一个 RGBAARGB 值(取决于系统字节序)来使用。此时,Alpha 分量 (0x40) 是有效的。这就是“能用”的情况。
- 如果目标 Surface 是 24 位(RGB),这个整数依然会被写入,但由于 Surface 只存储 RGB 三个字节,写入时会丢失(或截断)最后一个字节。所以,你的 0x40404040 实际上只会写入 0x404040(一个中灰色),Alpha 值 0x40 被丢弃了。这是“不能用”(指透明度无效)的情况。

为什么同一个 Surface 也会时灵时不灵?
这可能是因为:
1. 你在某些操作后,无意中改变了 Surface 的格式。
2. 你对不同的 Surface(有些是 convert_alpha() 过的,有些不是)使用了同样的颜色值,产生了不同的效果。
3. 通过 .set_at() 直接设置像素时,这个规则最明显。而使用 .fill() 等方法,如果传入整数,Pygame 内部可能进行了一些转换。

最可靠的解决方案
为了避免混淆和不确定性,在处理带透明度的颜色时,建议始终使用 RGBA 元组 来表示颜色。这是 Pygame 最通用、最清晰的方式。

  1. python
  2. # 最推荐的方式:使用 RGBA 元组 (R, G, B, A)
  3. # 每个值范围 0-255

  4. half_transparent_gray = (64, 64, 64, 64)  # 相当于 0x40404040
  5. transparent = (0, 0, 0, 0)
  6. solid_black = (0, 0, 0, 255)

  7. # 在操作时非常明确
  8. my_alpha_surface.fill((64, 64, 64, 64))  # 填充 1/4 透明的深灰色
复制代码


如果你想继续使用整数,确保 Surface 格式正确
如果你确实想用整数,请务必确保操作对象是 32 位深度 的 Surface。创建时使用 .convert_alpha()

  1. python
  2. import pygame
  3. pygame.init()

  4. # 创建一个支持 Alpha 通道的 Surface(通常是 32 位深度)
  5. screen = pygame.display.set_mode((800, 600))
  6. alpha_surface = pygame.Surface((100, 100), pygame.SRCALPHA)  # 推荐方式
  7. # 或者
  8. # alpha_surface = pygame.Surface((100, 100)).convert_alpha()

  9. # 现在使用 32 位整数颜色填充(0xRRGGBBAA)
  10. alpha_surface.fill(0x40404040)  # 此时 Alpha 通道应该有效

  11. # 检查 Surface 的像素深度(可选)
  12. print(alpha_surface.get_bitsize())  # 应该输出 32
复制代码


结论
“时灵时不灵”的现象是因为整数颜色值在不同的 Surface 像素格式下被做了不同的解读。为了保证代码的清晰和可靠,在处理透明度时,强烈建议放弃使用十六进制整数,转而使用明确的 (R, G, B, A) 元组。这样无论 Surface 格式如何,Pygame 都会正确地帮你处理好转换。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-3-8 08:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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