Python Forum
[PyGame] Problem with collision of player and enemy - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: Game Development (https://python-forum.io/forum-11.html)
+--- Thread: [PyGame] Problem with collision of player and enemy (/thread-41256.html)



Problem with collision of player and enemy - Nekotrooper - Dec-08-2023

The game ends even though player did not touch the enemy in this code.
I do believe there is a problem with collision or with the image size of player and enemy, can anybody help me with this?

---

import pygame
import random
import sys
from pygame.locals import *

pygame.init()

screen_width = 1280  
screen_height = 720  
screen = pygame.display.set_mode((screen_width, screen_height))

clock = pygame.time.Clock()
player = pygame.image.load("C:/Users/USER/Downloads/Player.png")
player_size = player.get_rect().size
player_width = player_size[0]
player_height = player_size[1]
player = pygame.transform.scale(player, (int(player_width * 0.5), int(player_height * 0.5)))
player_x_pos = (screen_width / 2) - (player_width / 2)
player_y_pos = (screen_height / 2) - (player_height / 2)

to_x = 0
to_y = 0

font = pygame.font.SysFont('Sans', 30)
start_time = 0
second = 0

def game_restart(_second):
    restart_screen = pygame.display.set_mode((screen_width, screen_height))

    pygame.font.init()
    game_restart_font = pygame.font.SysFont('Sans', 30, True, True)
    game_restart_message = 'Game Over.'
    game_restart_object = game_restart_font.render(game_restart_message, True, (0, 0, 0))

    game_time_message = str(_second) + 's'
    game_time_object = game_restart_font.render(game_time_message, True, (255, 0, 0))

    running = True

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    running = True
        restart_screen.fill((255, 255, 255))
        restart_screen.blit(game_restart_object, (screen_width / 2, screen_height / 2))
        restart_screen.blit(game_time_object, (screen_width / 2, screen_height / 1.8))

        pygame.display.update()

# enemy
enemy_list = list()
class enemy_class:
    enemy_image = pygame.image.load("C:/Users/USER/Downloads/Enemy.png")
    enemy_size = enemy_image.get_rect().size
    enemy_width = enemy_size[0]
    enemy_height = enemy_size[1]
    enemy_image = pygame.transform.scale(enemy_image, (int(enemy_width * 0.5), int(enemy_height * 0.5)))
    enemy_x_pos = 0
    enemy_y_pos = 0
    enemy_speed = 0
    enemy_spawnPoint = None
    enemy_rad = 0

    def __init__(self):
        self.enemy_speed = random.choice([0.5, 1, 1.5, 2])
        self.enemy_spawnPoint = random.choice(['UP', 'DOWN', 'LEFT', 'RIGHT'])
        if self.enemy_spawnPoint == 'LEFT':
            self.enemy_x_pos = -self.enemy_width
            self.enemy_y_pos = random.randint(0, screen_height - self.enemy_height)
            self.enemy_rad = random.choice([(1, 3), (1, 2), (2, 2), (2, 1), (3, 1), (3, 0), (1, -3), (1, -2), (2, -2), (2, -1), (3, -1)])
        elif self.enemy_spawnPoint == 'RIGHT':
            self.enemy_x_pos = screen_width
            self.enemy_y_pos = random.randint(0, screen_height - self.enemy_height)
            self.enemy_rad = random.choice([(-1, 3), (-1, 2), (-2, 2), (-2, 1), (-3, 1), (-3, 0), (-1, -3), (-1, -2), (-2, -2), (-2, -1), (-3, -1)])
        elif self.enemy_spawnPoint == 'UP':
            self.enemy_x_pos = random.randint(0, screen_width - self.enemy_width)
            self.enemy_y_pos = -self.enemy_height
            self.enemy_rad = random.choice([(3, 1), (2, 1), (2, 2), (1, 2), (1, 3), (0, 3), (-3, 1), (-2, 1), (-2, 2), (-1, 2), (-1, 3)])
        elif self.enemy_spawnPoint == 'DOWN':
            self.enemy_x_pos = random.randint(0, screen_width - self.enemy_width)
            self.enemy_y_pos = screen_height
            self.enemy_rad = random.choice([(3, -1), (2, -1), (2, -2), (1, -2), (1, -3), (0, -3), (-3, -1), (-2, -1), (-2, -2), (-1, -2), (-1, -3)])

    def enemy_move(self):
        self.enemy_x_pos += self.enemy_speed * self.enemy_rad[0]
        self.enemy_y_pos += self.enemy_speed * self.enemy_rad[1]

    def boundary_UP(self):
        if self.enemy_y_pos < -self.enemy_height:
            return True

    def boundary_DOWN(self):
        if self.enemy_y_pos > screen_height:
            return True

    def boundary_LEFT(self):
        if self.enemy_x_pos < -self.enemy_width:
            return True

    def boundary_RIGHT(self):
        if self.enemy_x_pos > screen_width:
            return True

    def enemy_coll(self):
        self.enemy_rect = self.enemy_image.get_rect()
        self.enemy_rect.left = self.enemy_x_pos
        self.enemy_rect.top = self.enemy_y_pos

running = True

while running:
    clock.tick(30)

    screen.fill((255, 255, 255))

    time_since_enter = pygame.time.get_ticks() - start_time
    if time_since_enter > 1000:
        start_time = pygame.time.get_ticks()
        second += 1

    game_time_message = font.render(str(second) + 's', True, (255, 0, 0))
    screen.blit(game_time_message, (screen_width - game_time_message.get_width(), 0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                to_x -= 7
            elif event.key == pygame.K_RIGHT:
                to_x += 7
            elif event.key == pygame.K_UP:
                to_y -= 7
            elif event.key == pygame.K_DOWN:
                to_y += 7

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0

    player_x_pos += to_x
    player_y_pos += to_y

    if player_x_pos < 0:
        player_x_pos = 0
    elif player_x_pos > screen_width - player_width:
        player_x_pos = screen_width - player_width

    if player_y_pos < 0:
        player_y_pos = 0
    elif player_y_pos > screen_height - player_height:
        player_y_pos = screen_height - player_height

    enemy_list.append(enemy_class())


    # collision
    player_rect = player.get_rect()
    player_rect.left = player_x_pos
    player_rect.top = player_y_pos

    for i in enemy_list:
        i.enemy_coll()
        if player_rect.colliderect(i.enemy_rect):
            game_restart(second)



   
    screen.blit(player, (player_x_pos, player_y_pos))

    for i in enemy_list:
        i.enemy_move()
        screen.blit(i.enemy_image, (i.enemy_x_pos, i.enemy_y_pos))

    pygame.display.update()

pygame.quit()



RE: Problem with collision of player and enemy - deanhystad - Dec-08-2023

Your images are much larger than the painted part of the image. Crop the image to remove as much surround empty space as possible and your results will be better.

If you still don't like the collision detection, treat your images as circles and compute the distance between centers.