checking for mouse collison pygame.draw.circle()

时间:2018-07-25 04:33:36

标签: pygame python-3.6

I'm making a CheckButton Widget to be able to use in game menus. Wondering how I might be able to check if the mouse is colliding with the circle? Using the self.surface.get_rect() method doesn't seem to work. is there a way to calculate where the circle is based on its location in its surface object? I was just going to just draw a smaller black circle inside the circle when self.active == True then back to its default color if its False. should I be using Sprites for this?

class CheckButton():

"""add label?"""

def __init__(self, screen, pos,size=(10,10),color=GREY):

    self.screen = screen
    self.pos = pos
    self.size = size
    self.color = color

    self.active = False

    self.surface = pygame.surface.Surface(self.size)
    self.rect = self.surface.get_rect()
    self.center = (5,5)

def check_for_click(self):

    pos = pygame.mouse.get_pos()
    mouseClicked = pygame.mouse.get_pressed()
    if self.rect.collidepoint(pos) and mouseClicked == (1,0,0):
        self.active = True
        print(self.active)





def draw(self):

    self.surface.fill(BG_COLOR)
    pygame.draw.circle(self.surface,self.color, self.center,5, 0)
    self.screen.blit(self.surface, self.pos)

1 个答案:

答案 0 :(得分:2)

使用pygame时,请勿为对象赋予poscenter之类的属性(如果出于某种原因而不必这样做)。只需使用pygame的SpriteRect类,它们将为您处理所有这些事情。

这是一个正在运行的示例。请注意注释以获取进一步的解释:

import pygame
from math import hypot

pygame.init()
screen = pygame.display.set_mode((400, 400))

BG_COLOR=(55,0,200)

# note that pygame comes with a lot of colors already defined in THECOLORS
GREY=pygame.color.THECOLORS['grey']

# pygame's Group is great for sprite handling, but it does not offer a function for event handling
# so we create our own simple Group
class EventAwareGroup(pygame.sprite.Group):

    def handle(self, event):
        for spr in self.sprites():
            if hasattr(spr, 'handle'):
               spr.handle(event)

class CheckButton(pygame.sprite.Sprite):

    def __init__(self, pos, size=(10,10), color=(255,100,200)):
        super().__init__()
        self.image = pygame.surface.Surface(size)

        # we use a random color as colorkey, which means this color acts
        # as a substitute for 'transparent'; so we don't have to care about the
        # actual background
        self.image.set_colorkey((99,32,127))
        self.image.fill((99,32,127))

        self.rect = self.image.get_rect()

        # our image is a simple circle
        # note how we can use the attributes of Rect to easily find the center of our Surface
        pygame.draw.circle(self.image, color, self.rect.center, size[0]//2, 0)

        # when the checkbox is active, we want to show another image, so let's create it here
        # we want to do the drawing once, so we do it in the __init__ function
        self.toggle_image = self.image.copy()
        pygame.draw.circle(self.toggle_image, (0, 0, 0), self.rect.center, size[0]//3, 0)

        # now let's position our checkbox at 'pos'
        self.rect.center = pos
        self.active = False

    def handle(self, event):
        # since we want to toggle the active state of the checkbox when a mouse click occurs,
        # it's better to listen for the MOUSEBUTTONDOWN event
        if event.type == pygame.MOUSEBUTTONDOWN:
            # to check if the mouse click was actually in the circle, we simple calculate the distance
            d = hypot(event.pos[0] - self.rect.center[0], event.pos[1] - self.rect.center[1])
            if d <= self.rect.width/2 and event.button == 1:
                # now let's toggle the active flag and the images
                self.active = not self.active
                self.image, self.toggle_image = self.toggle_image, self.image

c = CheckButton([150, 100], [100, 100])
g = EventAwareGroup(c)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        g.handle(event)

    # note how simple and clean our main loop is
    # when we need other sprites, just add them to the g Group
    # no need to change the main loop for that
    screen.fill(BG_COLOR)
    g.update()
    g.draw(screen)

    pygame.display.update()