julezzz
julezzz

Reputation: 55

Sprite collision (spritecollideany() ) not working?

I am new to coding and I am trying I have been unable to find out why my pygame spritecollideany() function is not doing anything. It is a platformer game and my player upon falling into the ground sprites does not do anything. I am not getting an error message and I think the syntax is correct but something in my code is not linking up. I'm sorry to post my all of my messy code but I don't know what the source of the problem is.

The code that isn't doing anything:

if pygame.sprite.spritecollideany(player, ground_sprites):
            print("COLLISION IS WORKING")

All of the code

import pygame, sys, random

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption("Pygame Platformer")
clock = pygame.time.Clock()

gravity = 0

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.x = x
        self.y = y
        self.image = pygame.image.load("marioLeft.png")
        self.rect = self.image.get_rect(midtop = (self.x, self.y))

    def Move(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
            self.x += 5
        if keys[pygame.K_LEFT]:
            self.x -= 5

    def Draw(self, surface):
        surface.blit(self.image, (self.x, self.y))

    def Collision(self):
        pass

class Ground(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height):
        super().__init__()
        self.x = x
        self.y = y
        self.width = width
        self.height = height

        self.image = pygame.Surface((width, height))
        self.rect = self.image.get_rect(midtop = (x, y))
        self.image.fill('White')

    def DrawGround():
        for entity in ground_sprites:
            screen.blit(entity.image, entity.rect)

#INSTANTIATION
player_group = pygame.sprite.Group()
player = Player(100, 250)
player_group.add(player)

ground_sprites = pygame.sprite.Group()
ground1 = Ground(100, 500, 200, 100)
ground2 = Ground(450, 400, 200, 100)
ground_sprites.add(ground1, ground2)

run = True
while run:
    clock.tick(60)
    screen.fill('Black')
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

    gravity += 1
    if gravity >= 20:
        gravity = 20
    player.y += gravity

    if pygame.sprite.spritecollideany(player, ground_sprites):
            print("COLLISION IS WORKING")

    Ground.DrawGround()
    player.Draw(screen)
    player.Move()
    player.Collision()

    pygame.display.update()

Upvotes: 3

Views: 154

Answers (1)

Rabbid76
Rabbid76

Reputation: 210978

pygame.sprite.spritecollideany (and all other collision detection functions) uses the rect attributes of the pygame.sprite.Sprite objects to detect the collision. So you need to update the position stored in the rect attribute when you move the sprite:

class Player(pygame.sprite.Sprite):
    # [...]

    def Move(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
            self.x += 5
        if keys[pygame.K_LEFT]:
            self.x -= 5
        self.rect.x = self.x               # <---

Actually, you don't need self.x and self.y at all. Use self.rect.x and self.rect.y instead:

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.image.load("marioLeft.png")
        self.rect = self.image.get_rect(midtop = (x, y))

    def Move(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
            self.rect.x += 5
        if keys[pygame.K_LEFT]:
            self.rect.x -= 5

    def Draw(self, surface):
        surface.blit(self.image, self.rect)

Upvotes: 3

Related Questions