我想知道如何编写可以检测鼠标点击精灵的代码。例如:
if #Function that checks for mouse clicked on Sprite:
print ("You have opened a chest!")
答案 0 :(得分:25)
我假设你的游戏有一个主循环,所有精灵都在一个名为sprites
的列表中。
在主循环中,获取所有活动,并检查MOUSEBUTTONDOWN
或MOUSEBUTTONUP
事件。
while ... # your main loop
# get all events
ev = pygame.event.get()
# proceed events
for event in ev:
# handle MOUSEBUTTONUP
if event.type == pygame.MOUSEBUTTONUP:
pos = pygame.mouse.get_pos()
# get a list of all sprites that are under the mouse cursor
clicked_sprites = [s for s in sprites if s.rect.collidepoint(pos)]
# do something with the clicked sprites...
所以基本上你必须在mainloop的每次迭代中检查一个sprite的点击。您需要使用mouse.get_pos()和rect.collidepoint()。
Pygame不提供事件驱动编程,例如cocos2d确实如此。
另一种方法是检查鼠标光标的位置和按下按钮的状态,但这种方法存在一些问题。
if pygame.mouse.get_pressed()[0] and mysprite.rect.collidepoint(pygame.mouse.get_pos()):
print ("You have opened a chest!")
如果你处理了这种情况,你将不得不引入某种旗帜,因为否则这段代码将打印“你已经打开了一个箱子!”主循环的每次迭代。
handled = False
while ... // your loop
if pygame.mouse.get_pressed()[0] and mysprite.rect.collidepoint(pygame.mouse.get_pos()) and not handled:
print ("You have opened a chest!")
handled = pygame.mouse.get_pressed()[0]
当然你可以继承Sprite
并添加一个名为is_clicked
的方法,如下所示:
class MySprite(Sprite):
...
def is_clicked(self):
return pygame.mouse.get_pressed()[0] and self.rect.collidepoint(pygame.mouse.get_pos())
所以,最好使用第一种方法恕我直言。
答案 1 :(得分:6)
The pygame documentation for mouse events is here。您可以与pygame.mouse.get_pressed
(如果需要)合作使用pygame.mouse.get_pos
方法。但请通过主事件循环使用鼠标单击事件。事件循环更好的原因是“短暂点击”。您可能在普通计算机上没有注意到这些,但在触控板上使用点按式按键的计算机的点击周期过短。使用鼠标事件可以防止这种情况。
修改强>
要执行像素完美碰撞,请使用their docs for sprites上的pygame.sprite.collide_rect()
。
答案 2 :(得分:4)
我一直在寻找这个问题的相同答案,经过多次努力,这就是我想出的答案:
#Python 3.4.3 with Pygame
import pygame
pygame.init()
pygame.display.set_caption('Crash!')
window = pygame.display.set_mode((300, 300))
running = True
# Draw Once
Rectplace = pygame.draw.rect(window, (255, 0, 0),(100, 100, 100, 100))
pygame.display.update()
# Main Loop
while running:
# Mouse position and button clicking.
pos = pygame.mouse.get_pos()
pressed1, pressed2, pressed3 = pygame.mouse.get_pressed()
# Check if the rect collided with the mouse pos
# and if the left mouse button was pressed.
if Rectplace.collidepoint(pos) and pressed1:
print("You have opened a chest!")
# Quit pygame.
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
答案 3 :(得分:1)
单击鼠标按钮,MOUSEBUTTONDOWN
事件发生一次,释放鼠标按钮,MOUSEBUTTONUP
事件发生一次。 pygame.event.Event()
对象具有两个属性,这些属性提供有关鼠标事件的信息。 pos
是一个元组,用于存储单击的位置。 button
存储被单击的按钮。每个鼠标按钮都关联一个值。例如,鼠标左键,鼠标中键,鼠标右键,上滚轮和下滚轮的属性值分别为1、2、3、4、5。当按下多个键时,会发生多个鼠标按钮事件。进一步的说明可以在模块pygame.event
的文档中找到。
使用pygame.sprite.Sprite
对象的rect
属性和collidepoint
方法查看是否单击了 Sprite 。
将事件列表传递给update
的pygame.sprite.Group
方法,以便您可以在 Sprite 类中处理事件:
class SpriteObject(pygame.sprite.Sprite):
# [...]
def update(self, event_list):
for event in event_list:
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
# [...]
my_sprite = SpriteObject()
group = pygame.sprite.Group(my_sprite)
# [...]
run = True
while run:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
run = False
group.update(event_list)
# [...]
最小示例: repl.it/@Rabbid76/PyGame-MouseClick
import pygame
class SpriteObject(pygame.sprite.Sprite):
def __init__(self, x, y, color):
super().__init__()
self.original_image = pygame.Surface((50, 50), pygame.SRCALPHA)
pygame.draw.circle(self.original_image, color, (25, 25), 25)
self.click_image = pygame.Surface((50, 50), pygame.SRCALPHA)
pygame.draw.circle(self.click_image, color, (25, 25), 25)
pygame.draw.circle(self.click_image, (255, 255, 255), (25, 25), 25, 4)
self.image = self.original_image
self.rect = self.image.get_rect(center = (x, y))
self.clicked = False
def update(self, event_list):
for event in event_list:
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
self.clicked = not self.clicked
self.image = self.click_image if self.clicked else self.original_image
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
sprite_object = SpriteObject(*window.get_rect().center, (128, 128, 0))
group = pygame.sprite.Group([
SpriteObject(window.get_width() // 3, window.get_height() // 3, (128, 0, 0)),
SpriteObject(window.get_width() * 2 // 3, window.get_height() // 3, (0, 128, 0)),
SpriteObject(window.get_width() // 3, window.get_height() * 2 // 3, (0, 0, 128)),
SpriteObject(window.get_width() * 2// 3, window.get_height() * 2 // 3, (128, 128, 0)),
])
run = True
while run:
clock.tick(60)
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
run = False
group.update(event_list)
window.fill(0)
group.draw(window)
pygame.display.flip()
pygame.quit()
exit()
进一步查看Creating multiple sprites with different update()'s from the same sprite class in Pygame
可以通过pygame.mouse.get_pos()
确定鼠标的当前位置。返回值是一个元组,表示鼠标光标的x和y坐标。 pygame.mouse.get_pressed()
返回代表所有鼠标按钮状态(True
或False
的布尔值列表。只要按住按钮,按钮的状态就为True
。当按下多个按钮时,列表中的多个项目为True
。列表中的第1,第2和第3元素分别表示鼠标左键,鼠标中键和鼠标右键。
检测在pygame.sprite.Sprite
对象的Update
方法中评估鼠标状态:
class SpriteObject(pygame.sprite.Sprite):
# [...]
def update(self, event_list):
mouse_pos = pygame.mouse.get_pos()
mouse_buttons = pygame.mouse.get_pressed()
if self.rect.collidepoint(mouse_pos) and any(mouse_buttons):
# [...]
my_sprite = SpriteObject()
group = pygame.sprite.Group(my_sprite)
# [...]
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
group.update(event_list)
# [...]
最小示例: repl.it/@Rabbid76/PyGame-MouseHover
import pygame
class SpriteObject(pygame.sprite.Sprite):
def __init__(self, x, y, color):
super().__init__()
self.original_image = pygame.Surface((50, 50), pygame.SRCALPHA)
pygame.draw.circle(self.original_image, color, (25, 25), 25)
self.hover_image = pygame.Surface((50, 50), pygame.SRCALPHA)
pygame.draw.circle(self.hover_image, color, (25, 25), 25)
pygame.draw.circle(self.hover_image, (255, 255, 255), (25, 25), 25, 4)
self.image = self.original_image
self.rect = self.image.get_rect(center = (x, y))
self.hover = False
def update(self):
mouse_pos = pygame.mouse.get_pos()
mouse_buttons = pygame.mouse.get_pressed()
#self.hover = self.rect.collidepoint(mouse_pos)
self.hover = self.rect.collidepoint(mouse_pos) and any(mouse_buttons)
self.image = self.hover_image if self.hover else self.original_image
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
sprite_object = SpriteObject(*window.get_rect().center, (128, 128, 0))
group = pygame.sprite.Group([
SpriteObject(window.get_width() // 3, window.get_height() // 3, (128, 0, 0)),
SpriteObject(window.get_width() * 2 // 3, window.get_height() // 3, (0, 128, 0)),
SpriteObject(window.get_width() // 3, window.get_height() * 2 // 3, (0, 0, 128)),
SpriteObject(window.get_width() * 2// 3, window.get_height() * 2 // 3, (128, 128, 0)),
])
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
group.update()
window.fill(0)
group.draw(window)
pygame.display.flip()
pygame.quit()
exit()