1

I am trying to make it so when my player sprite collides with an enemy, the player is killed. However, my player only dies if the enemy happens to spawn at the same point as the player and not when the player moves about and touches another sprite on purpose.

Here is my code:


import math
from random import randint
import pygame
from pygame.math import Vector2

pygame.init()

screen = pygame.display.set_mode((600, 600))
screen_width = 600
screen_height = 600
black = (0, 0, 0)
pygame.display.set_caption("gang")
clock = pygame.time.Clock()


class Player(pygame.sprite.Sprite):

    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((50, 30), pygame.SRCALPHA)
        pygame.draw.polygon(self.image, pygame.Color('steelblue2'), [(0, 0), (50, 15), (0, 30)])
        self.original_image = self.image
        self.rect = self.image.get_rect(center=pos)
        self.pos = Vector2(pos)
        self.velocityx = Vector2(6, 0)
        self.velocityy = Vector2(0, 6)

    def update(self):
        self.rect.center = (int(self.pos.x), int(self.pos.y))
        clamp_rect = self.rect.clamp(screen.get_rect())
        if clamp_rect != self.rect:
            self.rect = clamp_rect
            self.pos.x, self.pos.y = self.rect.center
        self.rotate()

    def rotate(self):
        direction = pygame.mouse.get_pos() - self.pos
        radius, angle = direction.as_polar()
        self.image = pygame.transform.rotate(self.original_image, -angle)
        self.rect = self.image.get_rect(center=self.rect.center)


class Enemy(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((50, 50))
        self.image.fill((randint(0, 255), randint(0, 255), randint(0, 255)))
        self.rect = self.image.get_rect(center=pos)
        self.pos = Vector2(pos)
        self.velocity = Vector2(1, 0)

    def update(self):
        self.pos += self.velocity
        self.rect.center = self.pos


class Projectile(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((9, 15), pygame.SRCALPHA)
        pygame.draw.circle(self.image, (0, 0, 0), (30, 50), 14)
        self.rect = self.image.get_rect(center=pos)
        self.pos = Vector2(pos)
        self.velocityx = Vector2(9, 0)
        self.velocityy = Vector2(0, 9)

    def update(self):
        self.pos += self.velocityx
        self.rect.center = self.pos


def draw_window():
    screen.fill((30, 30, 30))
    all_sprites.update()
    all_sprites.draw(screen)
    bullets.update()
    bullets.draw(screen)
    pygame.display.update()


def xor(a, b):
    if bool(a) != bool(b):
        return True
    else:
        return False


def game_end():
    pygame.font.init()
    text = pygame.font.Font('freesansbold.ttf', 32)
    text_surface = text.render('Game Over', False, (255, 255, 255))
    text_rect = text_surface.get_rect()
    text_rect.center = (86, 86)
    screen.blit(text_surface, (172, 172))
    pygame.display.update()


player = Player((300, 300))
projectile = Projectile((150, 150))
bullets = pygame.sprite.Group(projectile)
enemies_list = pygame.sprite.Group()
all_sprites = pygame.sprite.Group(player, projectile)


def collision():
    score = 0

    for i in range(5):
        enemy = Enemy((randint(0, 600), randint(0, 600)))
        enemies_list.add(enemy)
        all_sprites.add(enemy)

        collide_list = pygame.sprite.spritecollide(player, enemies_list, True)
        for enemy in collide_list:
            all_sprites.remove(player)


collision()


def main():
    screen_rect = screen.get_rect()

    run = True
    while run:
        clock.tick(60)

        keys = pygame.key.get_pressed()

        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                run = False

        if keys[pygame.K_SPACE]:
            if len(bullets) < 5:
                projectile.pos += projectile.velocityx
        if xor(keys[pygame.K_a], keys[pygame.K_LEFT]):
            player.pos -= player.velocityx
        elif xor(keys[pygame.K_d], keys[pygame.K_RIGHT]):
            player.pos += player.velocityx
        elif xor(keys[pygame.K_w], keys[pygame.K_UP]):
            player.pos -= player.velocityy
        elif xor(keys[pygame.K_s], keys[pygame.K_DOWN]):
            player.pos += player.velocityy

        player.rect.clamp_ip(screen_rect)

        draw_window()


main()

How can I make it so that a collision is detected and hence my player is removed from the game whilst the two sprites are moving?

domefist
  • 79
  • 3

1 Answers1

1

You have to check if the player collides with an enemy in the main loop:

e.g.

run = True
hit_count = 0
while run:

    # [...]

    player.rect.clamp_ip(screen_rect)

    collidelist = pygame.sprite.spritecollide(player, enemies_list, False)
    if collidelist:
        hit_count += 1
        print("hit", hit_count)

    draw_window()

If you want to fins initial enemy positions, which are not "on" the player, you've to check for collision of a new enemy and the player before you add it to enemies_list respectively all_sprites:

e.g.

def collision():
    score = 0

    while len(enemies_list) < 5:#
        enemy = Enemy((randint(0, 600), randint(0, 600)))
        if not pygame.sprite.collide_rect(enemy, player):
            enemies_list.add(enemy)
            all_sprites.add(enemy)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174