在使用 Pygame 创建一个简单的启动按钮时,遇到如下问题:
- 当用户点击按钮时,按钮图像应从原始图像更新到另一个稍微不同的图像,但图像更新后显示效果很差,并且第二个图像无法正常显示。
- 图像加载代码如下:
def load_image(name, colorkey=None):
fullname = os.path.join('data', name)
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print 'Cannot load image:', name
raise SystemExit, message
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
return image, image.get_rect()
- 鼠标和按钮对象代码如下:
class Mouse(pygame.sprite.Sprite):
"""moves a hand on the screen, following the computer mouse"""
def __init__(self):
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
self.clicking = 0
self.image, self.rect = load_image('game_mouse.jpg', -1)
def update(self):
"move the hand based on the computer mouse position"
pos = pygame.mouse.get_pos()
self.rect.midtop = pos
if self.clicking:
self.rect.move_ip(5, 10)
def click(self, target):
"returns true if the hand collides with the target"
if not self.clicking:
self.clicking = 1
hitbox = self.rect.inflate(-5, -5)
return hitbox.colliderect(target.rect)
def unclick(self):
self.clicking = 0
class Button(pygame.sprite.Sprite):
"""Button class used for all menus. Handles events"""
def __init__(self, original_image_source, clicked_image_source, location_coordinates):
pygame.sprite.Sprite.__init__(self) #call Sprite intializer
self.original_image_source = original_image_source
self.clicked_image_source = clicked_image_source
self.location_coordinates = location_coordinates
self.clicked = 0
self.image, self.rect = load_image(original_image_source, -1)
self.rect.midtop = location_coordinates
def update(self):
"update on click or unclick"
if self.clicked:
self.image, self.rect = load_image(self.clicked_image_source, -1)
self.rect.midtop = self.location_coordinates
else:
self.image, self.rect = load_image(self.original_image_source, -1)
self.rect.midtop = self.location_coordinates
def set_clicked(self):
self.clicked = 1
def set_unclicked(self):
self.clicked = 0
- 主方法代码如下:
def main():
# Initialise screen
pygame.init()
screen = pygame.display.set_mode((1000, 600))
pygame.display.set_caption('States of Matter')
pygame.mouse.set_visible(0)
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((250, 250, 250))
mouse = Mouse()
start_button = Button("start_button_original.jpg", "start_button_clicked.jpg", (background.get_width()/2,background.get_height()/3))
all_sprites = pygame.sprite.RenderPlain((mouse, start_button))
clock = pygame.time.Clock()
while 1:
clock.tick(60)
for event in pygame.event.get():
if event.type == QUIT:
return
elif event.type == KEYDOWN and event.key == K_ESCAPE:
return
elif event.type == MOUSEBUTTONDOWN:
if mouse.click(start_button):
start_button.set_clicked()
elif event.type == MOUSEBUTTONUP:
mouse.unclick()
start_button.set_unclicked()
all_sprites.update()
screen.blit(background, (0, 0))
all_sprites.draw(screen)
pygame.display.flip()
if __name__ == '__main__': main()
2. 解决方案
为了解决上述问题,可以对图像加载代码进行修改,以确保图像在更新后能够正常显示。
具体修改如下:
def load_image_fixed(name, colorkey=None):
fullname = os.path.join('data', name)
image = pygame.image.load(fullname)
image = image.convert_alpha()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
return image, image.get_rect()
在将图像加载到内存后,使用 convert_alpha() 将图像转换为具有透明通道的图像,这样就可以避免在更新图像时出现显示错误。
此外,还可以修改按钮的 update() 方法,以确保图像在更新后能够正确显示。
修改后的代码如下:
def update(self):
"update on click or unclick"
if self.clicked:
self.image, self.rect = load_image_fixed(self.clicked_image_source, -1)
self.rect.midtop = self.location_coordinates
else:
self.image, self.rect = load_image_fixed(self.original_image_source, -1)
self.rect.midtop = self.location_coordinates
通过这些修改,图像在更新后能够正常显示,问题得到解决。