我已经制作了 开始菜单 和 菜单屏幕 。开始屏幕只有一个Button Sprite
。单击后,它会创建校正动画,然后按预期进入菜单屏幕。但是,此菜单屏幕有两个Button Sprites
。似乎我在组中首先添加的Button Sprite
是可点击的,但另一个则不是。我不确定为什么会出现这种奇怪的行为。
在这段代码中我注意到它变得混乱:
elif event.type == MOUSEBUTTONDOWN:
#HERE IS THE ISSUE
print("size of all_sprites after clicking: " + str(len(all_sprites)))
print(" info on all_sprites: " + str(all_sprites))
for but in all_sprites:
print(" sprite info: " + str(but))
if isinstance(but, (Button)) and mouse.click(but):
but.set_clicked()
print(" clicked: " + str(but))
迭代Sprites
组并调用此方法时:
mouse.click(but)
它仅适用于添加的第一个Button
。当我尝试点击其他Button
时,它永远不会返回True
。我不确定为什么。
以下是相关对象:
#seperate this into an object class
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 = util.load_image('cursor.png',-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:
pygame.mixer.Sound("data/high_tone_sword.wav").play()
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
#seperate this into an object/menu class
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 = util.load_image(original_image_source, None)
self.rect.midtop = location_coordinates
def update(self):
"update on click or unclick"
if self.clicked:
self.image, self.rect = util.load_image(self.clicked_image_source, None)
self.rect.midtop = self.location_coordinates
else:
self.image, self.rect = util.load_image(self.original_image_source, None)
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)
#music!!!
pygame.mixer.music.load("music/Glorious Morning 2.mp3")
pygame.mixer.music.play(-1, 53.0)
background = pygame.Surface(screen.get_size(), pygame.SRCALPHA, 32)
background = background.convert()
background.fill((250, 250, 250))
elements_background = util.load_image("4-elements-background.jpg")
if pygame.font:
font = pygame.font.Font(None, 180)
font.set_italic(True)
text = font.render("States of Matter", 1, (20, 125, 120))
textpos = text.get_rect(centerx=elements_background[0].get_width()/2, centery=elements_background[0].get_height()/4)
elements_background[0].blit(text, textpos)
background.blit(elements_background[0],(-450, -200))
screen.blit(background, (0, 0))
pygame.display.flip()
flamethrower = Animation('animation/Flames/flamethrower_/flamethrower_', 29, (-50,0))
bolt_tsela = Animation('animation/voltage_0/bolt_tesla/bolt_tesla_', 10, (600, 200))
mouse = Mouse()
start_button = Button("start_button_original.jpg", "start_button_clicked.jpg", (background.get_width()/2, 12.5*background.get_height()/17))
#all_sprites = pygame.sprite.RenderPlain((flamethrower, bolt_tsela, mouse, start_button)) #arbitary order
all_sprites = pygame.sprite.OrderedUpdates((flamethrower, bolt_tsela, start_button, mouse)) #order based on how they are added!
clock = pygame.time.Clock()
battle_button = Button("battle_menu_button_original.jpg", "battle_menu_button_clicked.jpg", (background.get_width()/2,4.5*background.get_height()/17))
options_button = Button("options_menu_button_original.jpg", "options_menu_button_clicked.jpg", (background.get_width()/2, 10.5*background.get_height()/17))
menu_control = MenuControl()
menu_control.set_in_start_screen(True)
#game driver
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:
#HERE IS THE ISSUE
print("size of all_sprites after clicking: " + str(len(all_sprites)))
print(" info on all_sprites: " + str(all_sprites))
for but in all_sprites:
print(" sprite info: " + str(but))
if isinstance(but, (Button)) and mouse.click(but):
but.set_clicked()
print(" clicked: " + str(but))
elif event.type == MOUSEBUTTONUP:
mouse.unclick()
if menu_control.bools["in_start_screen"] and start_button.clicked:
#enter main manu
menu_control.set_in_main_menu(True)
start_button.set_unclicked()
all_sprites.empty()
all_sprites.add(battle_button, options_button, mouse)
print("size of all_sprites after enting main menu: " + str(len(all_sprites)))
elif menu_control.bools["in_start_screen"]:
start_button.set_unclicked()
if menu_control.bools["in_main_menu"] and battle_button.clicked:
battle_button.set_unclicked()
if menu_control.bools["in_main_menu"] and options_button.clicked:
options_button.set_unclicked()
all_sprites.update()
#redraw everything
screen.blit(background, (0, 0))
all_sprites.draw(screen)
pygame.display.flip()
if __name__ == '__main__': main()
答案 0 :(得分:1)
这是因为您在MOUSE_UP
事件上重置了鼠标上的单击状态。
在检查第一个按钮时设置变量clicking
,条件not self.clicking
其他按钮永远不会实现。
编辑:
我建议将此方法拆分为为鼠标设置clicking
变量的部分,以及另一个检查碰撞的部分。它们是两个独立的行动。现在,如果您不添加任何按钮,鼠标将永远不会处于clicking
状态。我不认为那是你的意图。
答案 1 :(得分:0)
对于发生的每个MOUSEBUTTONDOWN
事件,mouse.click()
中的每个Button
实例都会调用all_sprites
方法。 click()
方法仅在尚未设置时设置self.clicking = 1
。这意味着,当在第一个按钮之后的all_sprites
中再次调用按钮时,它会看到self.clicking
已经设置并且没有做任何事情。
希望这很清楚。
也许你想要这些[未经测试]的东西 - 这只会在self.clicking
循环中设置鼠标的for
属性一次(假设两个按钮不重叠):
def click(self, target):
"returns true if the hand collides with the target"
hitbox = self.rect.inflate(-5, -5)
if hitbox.colliderect(target.rect):
self.clicking = 1
return True