For every object you should create two items
pygame.Surface with image
pygame.Rect to keep position and size
and you should use collidepoint with pygame.Rect but you use with pygame.Surface
So it should
at start
mole = ... image ...
mole_rect = mole.get_rect()
later change position like
mole_rect.x = new_x
mole_rect.y = new_y
# or
mole_rect.centerx = new_x
mole_rect.centery = new_y
# etc.
and finally check collision
mole_rect.collidepoint(event.pos)
And display as
screen.blit(mole, mole_rect)
Full working example.
If you click mole (white rectangle) then it moves to random position.
import pygame
import random
# --- constants --- (PEP8: UPPER_CASE_NAMES)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
# --- main ---
pygame.init()
screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT) )
# create image with white rectangle
mole_image = pygame.Surface((50, 50))
mole_image.fill(WHITE)
# get `Rect` with size of image and set its position in center of screen
mole_rect = mole_image.get_rect()
mole_rect.center = screen.get_rect().center
# --- mainloop ---
clock = pygame.time.Clock()
running = True
while running:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYUP:
if event.key == pygame.K_ESCAPE:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if mole_rect.collidepoint(event.pos):
mole_rect.centerx = random.randrange(25, SCREEN_WIDTH-25)
mole_rect.centery = random.randrange(25, SCREEN_HEIGHT-25)
# --- draws ---
screen.fill(BLACK)
screen.blit(mole_image, mole_rect)
pygame.display.flip()
# --- FPS ---
ms = clock.tick(FPS)
fps = clock.get_fps()
pygame.display.set_caption('FPS: {:.1f} | milliseconds: {}'.format(fps, ms))
# --- end ---
pygame.quit()
PEP 8 -- Style Guide for Python Code
EDIT:
The same using class pygame.sprite.Sprite
import pygame
import random
# --- constants --- (PEP8: UPPER_CASE_NAMES)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
# --- classes --- (PEP8: CamelCaseNames)
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((50, 50))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def set_random_position(self):
self.rect.centerx = random.randrange(25, SCREEN_WIDTH-25)
self.rect.centery = random.randrange(25, SCREEN_HEIGHT-25)
def draw(self, surface):
surface.blit(self.image, self.rect)
def collide_point(self, pos):
return self.rect.collidepoint(pos)
# --- main ---
pygame.init()
screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT) )
screen_rect = screen.get_rect()
mole = Player(screen_rect.centerx, screen_rect.centery)
# --- mainloop ---
clock = pygame.time.Clock()
running = True
while running:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYUP:
if event.key == pygame.K_ESCAPE:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if mole.collide_point(event.pos):
mole.set_random_position()
# --- draws ---
screen.fill(BLACK)
mole.draw(screen)
pygame.display.flip()
# --- FPS ---
ms = clock.tick(FPS)
fps = clock.get_fps()
pygame.display.set_caption('FPS: {:.1f} | milliseconds: {}'.format(fps, ms))
# --- end ---
pygame.quit()
The same with many moles - but some code could be done with pygame.sprite.Group
import pygame
import random
# --- constants --- (PEP8: UPPER_CASE_NAMES)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
# --- classes --- (PEP8: CamelCaseNames)
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, color):
super().__init__()
self.color = color
self.image = pygame.Surface((50, 50))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def set_random_position(self):
self.rect.centerx = random.randrange(25, SCREEN_WIDTH-25)
self.rect.centery = random.randrange(25, SCREEN_HEIGHT-25)
def draw(self, surface):
surface.blit(self.image, self.rect)
def collide_point(self, pos):
return self.rect.collidepoint(pos)
# --- main ---
pygame.init()
screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT) )
screen_rect = screen.get_rect()
moles = []
for color in [WHITE, RED, GREEN, BLUE]:
mole = Player(screen_rect.centerx, screen_rect.centery, color)
mole.set_random_position()
moles.append(mole)
# --- mainloop ---
clock = pygame.time.Clock()
running = True
while running:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYUP:
if event.key == pygame.K_ESCAPE:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
for mole in moles:
if mole.collide_point(event.pos):
mole.set_random_position()
# --- draws ---
screen.fill(BLACK)
for mole in moles:
mole.draw(screen)
pygame.display.flip()
# --- FPS ---
ms = clock.tick(FPS)
fps = clock.get_fps()
pygame.display.set_caption('FPS: {:.1f} | milliseconds: {}'.format(fps, ms))
# --- end ---
pygame.quit()