我按照nkorth的建议屏蔽了pygame中的曲面,以回答问题is there any way to only blit or update in a mask,更新每帧的蒙版和蒙版曲面。虽然可以使用他的方法实现这一点,但帧速率会立即下降,并且在任何时候都只在屏幕上呈现此表面的一个实例。
Here是我要屏蔽的图像,here是应用程序的外观。这些其他圆圈并不重要,它们是按顺序创建的,并且彼此重叠绘制。我尝试将图像压缩到100kb(超过它的原始尺寸的10倍),但这只能帮助一点点。它仍然运行不佳。
这在pygame上甚至可能吗?如果是这样,那怎么样?
以下是相应的课程:
class NoiseCircle(Circle):
def __init__(self, center=SCREEN_CENTER, radius=5):
# init code
...
def draw(self, surf):
self.masked.blit(self.noise_image, (0, 0))
self.mask.fill((0, 0, 0, 0))
pygame.draw.circle(self.mask, (255, 255, 255), self.center, self.radius)
self.masked.blit(self.mask, (0, 0), None, pygame.BLEND_RGBA_MULT)
pygame.draw.circle(self.masked, (0, 0, 0), self.center, self.radius, 1)
surf.blit(self.masked, (0, 0))
主循环只是将显示表面传递给 draw(),它负责对象渲染。
答案 0 :(得分:0)
很难说你编程的瓶颈在哪里。可能是draw.circle
。尝试使用我的代码,它实现了我自己的圆绘制算法(注意,它不是精确的圆)。在Windows上使用pygame 1.9.2进行测试,计算速度非常慢 - Atom 1.6 GHz,它给我大约40毫秒(参见代码中的DT)。然后尝试实现,看看它是更快还是更慢。比较会很有趣。顺便说一下,使用colorkey怎么样?
def circle(r, x0, y0, dest, value):
x1 = int(r / math.sqrt(2))
h = []
x = x1
while(1):
x += 1
if x == r:
h.append(ch/3)
break
ch = int(math.sqrt(r**2-x**2))
h.append(ch)
p = 0
dest[x0-x1:x0+x1+1, y0-x1:y0+x1+1] = value
while p < len(h):
dest[x0+x1+p+1, y0-h[p]:y0+h[p]+1] = value
dest[x0-x1-p-1, y0-h[p]:y0+h[p]+1] = value
dest[x0-h[p]:x0+h[p]+1, y0-x1-p-1] = value
dest[x0-h[p]:x0+h[p]+1, y0+x1+p+1] = value
p += 1
def put_alpha(Dest, Src): # write alpha values
ref = pygame.surfarray.pixels_alpha (Dest)
numpy.copyto(ref, Src)
del ref
Layer = pygame.Surface ((w,h),flags = pygame.SRCALPHA)
Layer.fill(0xff4B432E)
Mask = numpy.zeros((w,h), dtype = numpy.uint8)
Mask[:] = 255
cur_time = pygame.time.get_ticks()
old_time = cur_time
circle(125, 400, 300, Mask, 125)
circle(75, 400, 300, Mask, 255)
put_alpha(Layer, Mask)
cur_time = pygame.time.get_ticks()
DT = cur_time - old_time
print DT
<强>更新强>: 首先,自定义循环函数的行为比pygame慢5倍,所以它不会减慢速度。 我已经通过各种变体提升了一些性能结果。首先,确保在任何地方都使用24位表面,除非你想要完整的256级透明度,单单这可以提供更好的结果。如果您运行以下示例,则输出必须提供&#34; 24 32 24&#34;。那些是相应表面的位深度。对于这种特殊情况,这将是最佳的。
pygame.init()
w = 800
h = 600
DISP = pygame.display.set_mode((w, h), 0, 24)
clock = pygame.time.Clock( )
Noise = pygame.Surface ((w,h))
Noise.fill((110,0,10))
color24bit = (169, 163, 144) # r g b
color = (169, 163, 144, 255) # r g b a
color_a = (169, 163, 144, 112) # r g b a
Layer = pygame.Surface ((w,h), flags = pygame.SRCALPHA)
Layer.fill(color) # ( 169, 163, 144, 255)
Layer_colorkey = pygame.Surface ((w,h))
Layer_colorkey.fill(color24bit)
color_key = (50, 50, 50)
Layer_colorkey.set_colorkey(color_key)
print Noise.get_bitsize(), Layer.get_bitsize(), Layer_colorkey.get_bitsize()
Mask = numpy.zeros((w,h), dtype = numpy.uint8)
Mask[:] = 255
t=0
cur_time = pygame.time.get_ticks()
old_time = cur_time
# 1. blit with per-pixel alpha and custom Mask array
while t < 0:
circle(296, 400, 300, Mask, 112)
circle(15, 400, 300, Mask, 255)
put_alpha(Layer, Mask)
Noise.blit(Layer,(0,0))
DISP.blit(Noise,(0,0))
t += 1
# 2. blit with per-pixel alpha and draw functions
while t < 0:
pygame.draw.circle(Layer, color_a, (400,300), 296, 0)
pygame.draw.circle(Layer, color, (400,300), 15, 0)
Noise.blit(Layer,(0,0))
DISP.blit(Noise,(0,0))
t += 1
# 3. blit with colorkey
while t < 1:
pygame.draw.circle(Layer_colorkey, color_key, (400,300), 296, 0)
pygame.draw.circle(Layer_colorkey, color, (400,300), 15, 0)
Noise.blit(Layer_colorkey,(0,0))
DISP.blit(Noise,(0,0))
t += 1
cur_time = pygame.time.get_ticks()
DT = cur_time - old_time
print "time:", DT
结论:
1.应用自定义Mask数组的完整alpha:最慢,但您可以完全控制蒙版形式,并可以透明地制作炫酷效果。
2.完整的alpha +只使用内置的绘图功能,只需用所需的alpha值定义颜色。比较快(ITPC),但没有直接控制颜色值
3.带有colorkey的正常24位表面。比上面快2倍,但没有自定义透明度。