简体   繁体   中英

How do I test for a collision in Pygame?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM