When I trie to detect a collision between the two rectangles with hit = pygame.sprite.groupcollide(enemy_sprites, player_sprites, 1, 1)
it only prints "HIT" once when I start the program
also I tried to detect the collision with hit = pygame.sprite.spritecollide(player_sprites, enemy_sprites, 1)
but there was this error:
Traceback (most recent call last):
File "D:/Python/PyCharm/test/src/Main/test.py", line 104, in
hit = pygame.sprite.spritecollide(player_sprites, enemy_sprites, 1)
File "D:\\Programme\\python\\lib\\site-packages\\pygame\\sprite.py", line 1523, in spritecollide ''''spritecollide = sprite.rect.colliderect AttributeError: 'Group' object has no attribute 'rect'
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
# def colours
self.GREEN = (0, 255, 255)
self.BLACK = (0, 0, 0)
self.playerx = x
self.playery = y
self.playerW = width
self.playerH = height
self.vel = 5
self.player_image = pygame.Surface((self.playerW, self.playerH))
self.player_image.fill(self.GREEN)
self.rect = self.player_image.get_rect()
def handleKeys(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
if self.playery >= self.vel:
self.playery -= self.vel
elif keys[pygame.K_DOWN]:
if self.playery + 50 <= screenH - self.vel:
self.playery += self.vel
elif keys[pygame.K_LEFT]:
if self.playerx >= self.vel:
self.playerx -= self.vel
elif keys[pygame.K_RIGHT]:
if self.playerx + 50 <= screenW - self.vel:
self.playerx += self.vel
else:
pass
def drawPlayer(self, surface):
player_sprites.update()
surface.fill(self.BLACK)
surface.blit(self.player_image, (self.playerx, self.playery))
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.enemyX = x
self.enemyY = y
self.enemyW = width
self.enemyH = height
self.RED = (255, 0, 0)
self.enemy_image = pygame.Surface((self.enemyW, self.enemyH))
self.enemy_image.fill(self.RED)
self.rect = self.enemy_image.get_rect()
def drawEnemy(self, surface):
enemy_sprites.update()
surface.blit(self.enemy_image, (self.enemyX, self.enemyY))
# def some variables
pygame.init()
clock = pygame.time.Clock()
screenW = 500
screenH = 500
playerx = 200
playery = 200
wn = pygame.display.set_mode((screenW, screenH))
pygame.display.set_caption("Test program")
# player
player_sprites = pygame.sprite.Group()
player = Player(100, 100, 50, 50)
player_sprites.add(player)
# enemy
enemy_sprites = pygame.sprite.Group()
enemy = Enemy(200, 200, 50, 50)
enemy_sprites.add(enemy)
# main loop
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
hit = pygame.sprite.groupcollide(enemy_sprites, player_sprites, 1, 1)
if hit:
print("HIT")
hit = False
player.handleKeys()
player.drawPlayer(wn)
enemy.drawEnemy(wn)
pygame.display.flip()
pygame.quit()
pygame.sprite.groupcollide
compares the .rect
properties in the pygame.sprite.Sprite
objects in the group.
Further note, that if the the 2nd and 3rd parameter of pygame.sprite.groupcollide()
are not False
, then the sprites are "killed" and removed from the groups in case of a collision.
You can avoid this by passing False
:
hit = pygame.sprite.groupcollide(enemy_sprites, player_sprites, False, False)
You've to update the .rect
properties when the position is initialized or changed:
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
# [...]
self.player_image = pygame.Surface((self.playerW, self.playerH))
self.player_image.fill(self.GREEN)
self.rect = self.player_image.get_rect()
self.rect.topleft = (self.playerx, self.playery) # <--- init .rect.topleft
def handleKeys(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
# [...]
self.rect.topleft = (self.playerx, self.playery) # <---- update .rect.topleft
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
# [...]
self.enemy_image = pygame.Surface((self.enemyW, self.enemyH))
self.enemy_image.fill(self.RED)
self.rect = self.enemy_image.get_rect()
self.rect.topleft = (self.enemyX, self.enemyY) # <--- init .rect.topleft
Alternatively you can remove self.playerx
, self.playery
, self.enemyX
and self.enemyY
use self.rect.x
respectively seld.rect.y
instead. See pygame.Rect
.
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.