Home > OS >  Pygame Collision Detection With Sprites
Pygame Collision Detection With Sprites

Time:12-03

I have 2 sprites who can move independently by WASD and arrow keys. I would like to try and do collision detection where if one touches the other it doesn't go through eachother. I've attempted that with my while loop but it does it indefinitely and the sprites become stuck to eachother and the game crashes. I've tried just using if but it doesn't do much. Apologies for bad formatting

My Code:

displayWidth = 500
displayHeight = 500
display = pygame.display.set_mode((displayWidth,displayHeight))
clock = pygame.time.Clock()


class Player(pygame.sprite.Sprite):
 def __init__(self,image,x,y):
  super().__init__()
  self.image = image
  self.rect = self.image.get_rect()
  self.rect.x = x
  self.rect.y = y
 def move(self, keyPress,kup,kdown,kleft,kright):
  if keyPress[kup]:
   self.rect.move_ip(0,-5)
  if keyPress[kdown]:
   self.rect.move_ip(0,5)
  if keyPress[kleft]:
   self.rect.move_ip(-5,0)
  if keyPress[kright]:
   self.rect.move_ip(5,0)
  if self.rect.left < 0:
   self.rect.left = 0
  if self.rect.right > displayWidth:
   self.rect.right = displayWidth
  if self.rect.top < 0:
   self.rect.top = 0
  if self.rect.bottom > displayHeight:
  self.rect.bottom = displayHeight
 pygame.display.update()

pygame.init()

pygame.display.set_caption("Collision Detection")

sprite1 = Player(pygame.image.load("Images/down.png"),0,0)
enemy1 = Player(pygame.image.load("Images/up.png"),100,100)
player_list = pygame.sprite.Group()
enemy_list = pygame.sprite.Group()
player_list.add(sprite1)
enemy_list.add(enemy1)



gameRunning = True
 while gameRunning == True:
  for event in pygame.event.get():
   if event.type == pygame.QUIT:
    gameRunning = False
 display.fill([0,0,0])
 keyPress = pygame.key.get_pressed()
 playerPositionX = sprite1.rect.x
 playerPositionY = sprite1.rect.y
 enemyPositionX = enemy1.rect.x
 enemyPositionY = enemy1.rect.y
 while pygame.sprite.collide_rect(sprite1,enemy1):
  sprite1.rect.x = playerPositionX
  sprite1.rect.y = playerPositionY
  enemy1.rect.x = enemyPositionX
  enemy1.rect.y = enemyPositionY
 player_list.draw(display)
 enemy_list.draw(display)
 sprite1.move(keyPress,K_UP,K_DOWN,K_LEFT,K_RIGHT)
 enemy1.move(keyPress,K_w,K_s,K_a,K_d)
 pygame.display.flip()
 clock.tick(60)
pygame.quit()

CodePudding user response:

You could try to set the position of the player and sprite to be 0 with an IF statement. Check to see if the position of the player is greater than the position of the enemy or visa versa. If it is, set the players x to be 0 (Make sure you do this in the update loop as it won't work properly!)

E.g for stopping the player:

if player.x > enemy.x:
   player.x = 0

CodePudding user response:

The order matters. You have to do the collision test after moving the sprits. copy the rectangles of the sprites before moving and restore the rectangles when a collision is detected:

gameRunning = True
while gameRunning == True:
    # [...]
    
    player_rect = sprite1.rect.copy()
    enemy_rect = enemy1.rect.copy()

    keyPress = pygame.key.get_pressed()
    sprite1.move(keyPress,K_UP, K_DOWN, K_LEFT, K_RIGHT)
    enemy1.move(keyPress, K_w, K_s, K_a, K_d)

    if pygame.sprite.collide_rect(sprite1, enemy1):
        sprite1.rect = player_rect
        enemy1.rect = enemy_rect

    # [...]

I recommend to simplify the code. Especially the Player class:

mport pygame
from pygame.locals import *

pygame.init()
displayWidth = 500
displayHeight = 500
display = pygame.display.set_mode((displayWidth,displayHeight))
pygame.display.set_caption("Collision Detection")
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self,image,x,y):
        super().__init__()
        self.image = image
        self.rect = self.image.get_rect(topleft = (x, y))
    def move(self, keyPress, kup, kdown, kleft, kright):
        self.rect.x  = (keyPress[kright] - keyPress[kleft]) * 5
        self.rect.y  = (keyPress[kdown] - keyPress[kup]) * 5
        self.rect.clamp_ip(display.get_rect())

sprite1 = Player(pygame.image.load("Images/down.png"), 0, 0)
enemy1 = Player(pygame.image.load("Images/up.png"), 100, 100)
player_list = pygame.sprite.Group([sprite1])
enemy_list = pygame.sprite.Group([enemy1])

gameRunning = True
while gameRunning == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameRunning = False
    
    player_rect = sprite1.rect.copy()
    enemy_rect = enemy1.rect.copy()

    keyPress = pygame.key.get_pressed()
    sprite1.move(keyPress,K_UP, K_DOWN, K_LEFT, K_RIGHT)
    enemy1.move(keyPress, K_w, K_s, K_a, K_d)

    if pygame.sprite.collide_rect(sprite1, enemy1):
        sprite1.rect = player_rect
        enemy1.rect = enemy_rect

    display.fill((0, 0, 0))
    player_list.draw(display)
    enemy_list.draw(display)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
  • Related