Search code examples
pythonimagepygamecollision-detection

Collision not working Pygame


I'm making a game with pygame, Space Invaders, and now I'm doing the collisions between the shoot of the eneimies and the player (those are images), but it doesn't work all time and I'd like to know why, and what's the solution. Thanks for attention! Here's the code:

# -*- coding: cp1252 -*-
import sys
import random 
import pygame
import time

print pygame.init()
x_player, y_player = 650, 440
screen = pygame.display.set_mode((700, 500))
pygame.display.set_caption("Space Invaders v1.0.0")
invaders = pygame.image.load(
"C:\\Users\\bernardo\\Documents\\IFC\\Programação\\SpaceInvaders-                      my_own\\space-invaders.jpeg").convert_alpha()
player = pygame.image.load(
"C:\\Users\\bernardo\\Documents\\IFC\\Programação\\SpaceInvaders-my_own\\28006.png").convert_alpha()
mother_ship = pygame.image.load(
"C:\\Users\\bernardo\\Documents\\IFC\\Programação\\SpaceInvaders-my_own\\mother_ship.png").convert_alpha()
lifes = pygame.image.load(
"C:\\Users\\bernardo\\Documents\\IFC\\Programação\\SpaceInvaders-my_own\\28007.png").convert_alpha()
shoot_enemie = pygame.image.load(
"C:\\Users\\bernardo\\Documents\\IFC\\Programação\\SpaceInvaders-my_own\\shots_and_bombs2.png").convert_alpha()
shoot = pygame.image.load(
"C:\\Users\\bernardo\\Documents\\IFC\\Programação\\SpaceInvaders-my_own\\shots_and_bombs2.png").convert_alpha()
pygame.font.init()
clock = pygame.time.Clock()
move_x = 0
x_invaders, y_invaders = 60, 60
lifes_list = [lifes, lifes, lifes]
x_mother = 0
invaders_matrix = [[invaders] * 11] * 5
existe_nave = False
start = True
tru = False
tru3= True
x_shoot = x_player
y_shoot = 0

tru2 = True
shoot_enemie1, shoot_enemie2, shoot_enemie3 = shoot_enemie, shoot_enemie,     shoot_enemie
shoot_list = [shoot_enemie1, shoot_enemie2, shoot_enemie]
tiros = {
"se1" : [0, 0],
"se2" : [0, 0],
"se3" : [0, 0]
}
cont = 0
while True:
invaders_matrix = [[invaders] * 11] * 5
if len(lifes_list) > 0:
    clock.tick(40)
    screen.fill((0, 0, 0))  
    screen.blit(player, ((x_player / 2), y_player))

    if not tru:
        invaders = pygame.image.load(
                "C:\\Users\\bernardo\\Documents\\IFC\\Programação\\SpaceInvaders-my_own\\space-    invader-motif.png"
            ).convert_alpha()
        tru = True
    else:
        invaders = pygame.image.load(
                 "C:\\Users\\bernardo\\Documents\\IFC\\Programação\\SpaceInvaders-my_own\\space-invaders.jpeg"
            ).convert_alpha()
        tru = False

    x_invaders, y_invaders = 105, 125
    for invader in range(len(invaders_matrix)):
        for invad in range(len(invaders_matrix[invader])):
            screen.blit(invaders_matrix[invader][invad], (x_invaders, y_invaders))
            x_invaders += 45
        x_invaders = 105
        y_invaders += 30

    if tru2:
        for i in tiros.keys():
            tiros[i][0] += tiros[i][0] + random.randint(0, 10) * 45 + 105
            tiros[i][1] += tiros[i][1] + random.randint(0, 4) * 45 + 125
        tru2 = False
    elif tiros["se1"][1] >= 600 and tiros["se2"][1] >= 600 and tiros["se3"][1] >= 600:
        tiros["se1"][1], tiros["se2"][1], tiros["se3"][1], \
        tiros["se1"][0], tiros["se2"][0], tiros["se3"][0] = 0, 0, 0, 0, 0, 0
        for i in tiros.keys():
            tiros[i][0] += tiros[i][0] + random.randint(0, 10) * 45 + 105
            tiros[i][1] += tiros[i][1] + random.randint(0, 4) * 45 + 125
    for i in shoot_list:
        for j in tiros.keys():
            screen.blit(i, (tiros[j][0], tiros[j][1]))
    for i in tiros.keys():
        tiros[i][1] += 4


    if existe_nave and (x_mother < 700):
        screen.blit(mother_ship, [x_mother, 35])
        x_mother += 4.5
        screen.blit(mother_ship, [x_mother, 35])
    elif random.randint(0, 800) == 0:
        existe_nave = True
        x_mother = 0

    width_for_lifes = 680
    for icon_lifes in lifes_list:
        width_for_lifes -= 50
        screen.blit(icon_lifes, (width_for_lifes, 15))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                move_x -= 10
            if event.key == pygame.K_RIGHT:
                move_x += 10
            if tru3:
                if event.key == pygame.K_SPACE:
                    y_shoot = y_player - player.get_height()
                    x_shoot = x_player / 2 + 20
                    tru3 = False
            elif not tru3:
                if y_shoot <= 0 and event.key == pygame.K_SPACE:
                    y_shoot = y_player - player.get_height()
                    x_shoot = x_player / 2 + 20
        if event.type == pygame.KEYUP and (event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT):
            move_x = 0

    if y_shoot > -50:
        screen.blit(shoot, (x_shoot, y_shoot))
        y_shoot -= 10

    if x_player >= 1280:
        x_player = 1280
    if x_player <= 25:
        x_player = 25
    x_player += move_x

    font = pygame.font.Font(None, 36)
    text = font.render("Lifes", 1, (0, 255, 85))
    screen.blit(text, (450, 15))

    font = pygame.font.Font(None, 36)
    text = font.render("Score", 1, (0, 255, 85))
    screen.blit(text, (20, 15))
    #Here is the problem
    player_rect = pygame.Rect(x_player, y_player, player.get_height(), player.get_width())
    shoot_enemie1_rect = pygame.Rect(tiros["se1"][0], tiros["se1"][1], shoot_enemie1.get_height(),
                                     shoot_enemie1.get_width())
    shoot_enemie2_rect = pygame.Rect(tiros["se2"][0], tiros["se2"][1], shoot_enemie2.get_height(),
                                     shoot_enemie2.get_width())
    shoot_enemie3_rect = pygame.Rect(tiros["se3"][0], tiros["se3"][1], shoot_enemie3.get_height(),
                                     shoot_enemie3.get_width())

    if player_rect.colliderect(shoot_enemie1_rect) or player_rect.colliderect(shoot_enemie2_rect) or \
        player_rect.colliderect(shoot_enemie3_rect):
        print True
print player_rect
pygame.display.update()

Solution

  • Here is a collision detection code that will sense if one rectangle collides with another rectangle, if the enemy's shot hits the player:

    if player x < shot x + player width and player x + shot width > shot x and player y < shot y + player height and shot height + player_y > shot y:
    

    It works by sensing if any of the edges of the bullet are touching any edges of the character. I hope this helps.