I'm struggling to work out how collisions work in pygame. I understand it's something to do with pygame.rect.colliderect, and I'm probably pretty close, but I'd appreciate someone who knows a bit more than me having a look! :-)
Here's a simple program I've written to steer a tiny green square onto a larger red square, and I'm trying to implement collision detection when the two meet, but at this stage everything works except collisions.
Thanks in advance!!
pygame.init()
import random #import random
size = (700,500) # set up the screen
screen = pygame.display.set_mode((size))
BLACK = (0,0,0) #define colours
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255, 0, 0)
class player(): #assign a player class
def __init__(self):
self.xpos = 450
self.ypos = 250
self.rect = pygame.Rect(self.xpos,self.ypos,5,5)
self.xvel = 0
self.yvel = 0
self.colour = GREEN
def update(self): #define a function to update the payer
#self.xpos +=self.xvel Ignore this bit. I implemented velocity, but it quickly flew off the screen
#self.ypos +=self.yvel
if player.rect.colliderect(obstacle.rect): #<--------- this is the bit I think might be wrong?
print("collision!")
def draw(self): #define a function to draw the player
pygame.draw.rect(screen, self.colour,[self.xpos,self.ypos,5,5])
class obstacle(): #define an obstacle class
def __init__ (self):
self.xpos = random.uniform(0,700)
self.ypos = random.uniform(0,500)
self.rect = pygame.Rect(self.xpos,self.ypos,20,20)
self.colour = RED
def draw(self): #define a function to draw the obstacle
pygame.draw.rect(screen, self.colour,[self.xpos,self.ypos, 20,20])
player = player() #run an instance of the player class
obstacle = obstacle() #run an instance of the obstacle class
clock = pygame.time.Clock()
while True: #game loop
for event in pygame.event.get(): #quit
if event.type == pygame.QUIT:
pygame.display.quit()
#-----Game logic
keys = pygame.key.get_pressed() #check for key presses and do whatever
if keys[pygame.K_LEFT]:
player.xpos -= 1
if keys[pygame.K_RIGHT]:
player.xpos += 1
if keys[pygame.K_UP]:
player.ypos -= 1
if keys[pygame.K_DOWN]:
player.ypos += 1
player.update() #Update the player - obstacle shouldn't need updating
#-----Drawing code
screen.fill(BLACK) #draw screen black
obstacle.draw() #draw the obstacle from the function
player.draw() #draw the player from the function
pygame.display.flip() #update
clock.tick(60)'''
The problem is you are not updating the position of your player's rectangle, which what colliderect looks at when detecting a collision. You were drawing the rectangle as you changed xpos
and ypox
but the coordinates for your rectangle rect.x
and rect.y
were not being updated accordingly. I changed the lines
def draw(self): #define a function to draw the player
pygame.draw.rect(screen, self.colour,[self.xpos,self.ypos,5,5])
to
def draw(self): #define a function to draw the player
pygame.draw.rect(screen, self.colour,[self.rect.x,self.rect.y,5,5])
and
if keys[pygame.K_LEFT]:
player.xpos -= 1
if keys[pygame.K_RIGHT]:
player.xpos += 1
if keys[pygame.K_UP]:
player.ypos -= 1
if keys[pygame.K_DOWN]:
player.ypos += 1
to
if keys[pygame.K_LEFT]:
player.rect.x -= 1
if keys[pygame.K_RIGHT]:
player.rect.x += 1
if keys[pygame.K_UP]:
player.rect.y -= 1
if keys[pygame.K_DOWN]:
player.rect.y += 1
so that the player's rectangle coordinates would be updated.
In these cases always print out what is not working, ie player.rect and obstacle.rect. You will see that you are not updating player.rect, which is always
<rect(150, 150, 5, 5)>
Since it does not overlap with obstacle.rect, which is always
<rect(34, 204, 20, 20)>
the collision is not detected.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.