我正在使用pygame开发一个简单的打字导师。我的问题是我使用的是具有白色背景的图像waves1.png
。现在我已经指定我希望白色在图像中是透明的(self.image.set_colorkey((255, 255, 255))
),它适用于除文本块之外的所有内容。当波与text
对象相交时,波浪的白色背景显示在文本的顶部。如果你有pygame(wave1.png图像除外),你可以尝试运行它。
import pygame
from pygame.locals import *
class TextSprite(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.wordList = ['words yes', 'hello', 'this is a sentence', 'this is another sentence'] # read directly from external file
self.pos = 0
self.wordNum = 0
self.update1()
def update1(self):
# Render the given word
self.image = pygame.font.Font(None, 36).render(self.wordList[self.wordNum], 1, (0, 0, 0))
# Render the correctly guessed letters
self.correct = pygame.font.Font(None, 36).render(self.wordList[self.wordNum][:self.pos], 1, (255, 0, 0))
# Copy correct letters onto given word
self.image.blit(self.correct, (0, 0))
self.rect = self.image.get_rect()
# set the center of the center the given word to the center of the screen
self.rect.center = pygame.display.get_surface().get_rect().center
def keyin(self, key):
word = self.wordList[self.wordNum]
letter = word[self.pos]
if letter == key:
self.pos = self.pos + 1
if self.pos == len(word):
self.reset()
self.update1()
def reset(self):
self.pos = 0
self.wordNum = self.wordNum + 1
self.update1()
class Waves(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block,
# and its x and y position
def __init__(self, filename):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create an image of the block, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.image.load(filename).convert()
# makes any white in the image transparent
self.image.set_colorkey((255, 255, 255))
self.rect = self.image.get_rect()
# Decrease the y coordinate so the waves look like they're moving up
def update(self, text):
self.rect.y = self.rect.y - 6
if self.rect.y <= 200:
text.reset()
self.rect.y = 485
def main():
#I - Import and initialize
pygame.init()
#D - Display configuration
# The screen variable is a pygame Surface object
# Note that the set_mode() method creates a Surface object for you automatically
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Typing Game")
#E - Entities (just background for now)
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((255, 255, 255))
screen.blit(background, (0,0))
#A - Action (broken into ALTER steps)
#A - Assign values to key variables
clock = pygame.time.Clock()
keepGoing = True
# Collect the sprite in a list
all = pygame.sprite.RenderPlain()
waveList = pygame.sprite.RenderPlain()
text = TextSprite()
all.add(text)
waves = Waves("waves1.png")
waveList.add(waves)
waves.rect.x = 0
waves.rect.y = 485
#L - Set up main loop
while keepGoing:
#T - Timer to set frame rate
# Tick is a method in the Clock class that determines the maximum frame rate
clock.tick(30)
#E - Event handling
for event in pygame.event.get():
if event.type == QUIT:
keepGoing = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
keepGoing = False
else:
text.keyin(event.unicode)
# update position of waves
waves.update(text)
# clears screen
all.clear(screen, background)
# update screen
all.draw(screen)
waveList.clear(screen, background)
waveList.draw(screen)
# display.flip is a method that copies everything from the screen object to the actual visual display
pygame.display.flip()
pygame.quit ()
if __name__ == '__main__': main()
答案 0 :(得分:1)
我不知道它是否适合你,但你应该通过png的原生alpha透明度获得更好的结果。
如果您可以自己编辑/重新创建png,请尝试使用透明背景。
从那里,您可以在加载图像后使用convert_alpha()。 (而不是使用颜色键)
http://pygame.org/docs/ref/surface.html#Surface.convert_alpha
编辑:另一个方面是,图片可能有一个alpha通道干扰了colorkey。最好确保你不要同时使用它们。
我被告知您可以通过编程方式检测图像的Alpha通道。有点像...
if self.image.get_masks()[3]!=0:
print "image has alpha!"
请参阅此处http://pygame.org/docs/ref/surface.html#Surface.get_masks
HTH
答案 1 :(得分:1)
干得好!您实际上已经正确地完成了所有操作以利用透明度和colorkey(即确保在表面上调用convert,确保将颜色传递给set_colorkey方法等)。
问题在于调用和清除相应精灵组的调用顺序,&#34;所有&#34;和#34; waveList&#34;。在通过调用all.draw渲染文本块之后,然后通过调用waveList.clear来跟随它。
问题在于:一旦你画了文字精灵,你就不想清除波浪精灵下方的空间,或者会消除与已经重叠的区域 - 绘制的文本块。
如果您想要正确执行此操作,请尝试按此顺序执行此操作:
(更简单地说,只需将waveList.clear(屏幕,背景)移动到all.clear(屏幕,背景)下方的行;应该这样做)
当我使用精灵组时,我通常会尝试对其进行分组,以便每个精灵组按此顺序调用相同的方法:清除,更新,碰撞检查(如果有),绘制。
这通常以正确的顺序处理事情。那么你仍然可能需要注意是否有任何精灵的分层,但那是另一天的另一个故事。