I am creating a game where the player moves around a grid and dodges rocks, but my code for detecting collision doesn't seem to work.
import pygame from pygame.locals import * import random pygame.init() xSize = 500 ySize = 500 win = pygame.display.set_mode((xSize, ySize), RESIZABLE) pygame.display.set_caption('Grid Game: Featuring Sad Blue Circle') grid = pygame.image.load('gr.png').convert() clock = pygame.time.Clock() rockWait = 1000 rock_spawn_ev = pygame.USEREVENT class player(object): def __init__(self): self.right = [pygame.image.load('right_%s.png' % frame) for frame in range(1, 9)] self.x = 109 self.y = 109 self.frameCount = 0 self.rect = pygame.Rect(self.x, self.y, 32, 32) #rect for collision def draw(self, win): if self.frameCount + 1 >= 40: self.frameCount = 0 win.blit(self.right[self.frameCount//5], (self.x, self.y)) self.frameCount +=1 self.rect = pygame.Rect(self.x, self.y, 32, 32) #update rect position class rock(object): def __init__(self, vel): self.rock = pygame.image.load('rock.png') self.vel = vel self.ran = random.randint(0, 3) self.ran2 = random.randint(1, 10) * 50 - 41 if self.ran > 1: self.x = 550 self.y = 550 else: self.x = -50 self.y = -50 rocks.append(self) self.rect = pygame.Rect(self.x, self.y, 32, 32) #rect for collision def draw(self, win): if self.ran == 0: #top to bottom self.y += self.vel win.blit(self.rock, (self.ran2, self.y)) if self.ran == 2: #bottom to top self.y -= self.vel win.blit(self.rock, (self.ran2, self.y)) if self.ran == 1: #left to right self.x += self.vel win.blit(self.rock, (self.x, self.ran2)) if self.ran == 3: #right to left self.x -= self.vel win.blit(self.rock, (self.x, self.ran2)) self.rect = pygame.Rect(self.x, self.y, 32, 32) #update rect position def rgw(): win.blit (grid, (0,0)) player.draw(win) for rock in rocks: rock.draw(win) colliding = player.rect.colliderect(rock.rect) if colliding: print('collide') #nothing happens, even when touching rock pygame.display.update() pygame.time.set_timer(rock_spawn_ev, rockWait) player = player() rocks = [] run = True while run: clock.tick(60) events = pygame.event.get() for event in events: if event.type == pygame.QUIT: run = False if event.type == rock_spawn_ev: rock(6) if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP and player.y > 9: player.y -= 50 elif event.key == pygame.K_DOWN and player.y < ySize - 41: player.y += 50 elif event.key == pygame.K_LEFT and player.x > 9: player.x -= 50 elif event.key == pygame.K_RIGHT and player.x < xSize - 41: player.x += 50 rgw() pygame.quit() I think that colliding = player.rect.colliderect(rock.rect) should return True when touching a rock, but "collide" never gets printed, in this for loop:
for rock in rocks: rock.draw(win) colliding = player.rect.colliderect(rock.rect) if colliding: print('collide') #nothing happens, even when touching rock I know that the for loop itself works, because the rocks are being drawn
class player(object): def __init__(self): self.x = 109 self.y = 109 self.rect = pygame.Rect(self.x, self.y, 32, 32) #rect for collision def draw(self, win): self.rect = pygame.Rect(self.x, self.y, 32, 32) #update rect position class rock(object): def __init__(self): rocks.append(self) self.rect = pygame.Rect(self.x, self.y, 32, 32) #rect for collision def draw(self, win): self.rect = pygame.Rect(self.x, self.y, 32, 32) #update rect position player = player() rocks = [] def rgw(): win.blit (grid, (0,0)) player.draw(win) for rock in rocks: rock.draw(win) colliding = player.rect.colliderect(rock.rect) if colliding: print('collide') #nothing happens, even when touching rock pygame.display.update()
self.rect = self.image.get_rect(). If the rect has an incorrect size, this could cause your issue. Maybe try drawing the collision rects too themselves (just the outline) when you paint the sprites.