Skip to content
Advertisement

How to make entities take damage with color collision in pygame?

How do I make entities take damage with colors? I made a game with enemies shooting blue lasers and I want the player to take damage. And the player shoots a red laser. Upon detecting colors, I want a certain statement to be true. That would lower an entity’s health by one. If color collision is a thing, it can be very useful for making many different games. Here is my code:

# importing packages
import pygame
import random
import time
import sys

# Initializing Pygame
pygame.init()

# Setting a display caption
pygame.display.set_caption("Space Invaders")

spaceship = pygame.image.load("spaceship2.png")
blue_enemy = pygame.image.load("blue_enemy.png")
green_enemy = pygame.image.load("green_enemy.png")
orange_enemy = pygame.image.load("orange_enemy.png")
pink_enemy = pygame.image.load("pink_enemy.png")
yellow_enemy = pygame.image.load("yellow_enemy.png")

# Creating a font
pygame.font.init()
font = pygame.font.SysFont("consolas", 30)
large_font = pygame.font.SysFont("consolas", 60)
small_font = pygame.font.SysFont("consolas", 20)

# Setting a display width and height and then creating it
display_width = 700
display_height = 500
display_size = [display_width, display_height]
game_display = pygame.display.set_mode(display_size)
intro_display = pygame.display.set_mode(display_size)


# Creating a way to add text to the screen
def message(sentence, color, x, y, font_type, display):
    sentence = font_type.render(str.encode(sentence), True, color)
    display.blit(sentence, [x, y])


def main():
    global white
    global black
    global clock

    # Spaceship coordinates
    spaceship_x = 300
    spaceship_y = 375
    spaceship_x_change = 0
    blue_enemy_health = 5
    green_enemy_health = 5
    orange_enemy_health = 5
    pink_enemy_health = 5
    yellow_enemy_health = 5

    # Clock making

    # Initializing pygame
    pygame.init()

    # Creating colors
    red = (0, 0, 0)
    blue = (0, 0, 255)

    # clock stuff
    clock = pygame.time.Clock()
    time_elapsed_since_last_action = 0
    time_elapsed_since_last_action2 = 0
    time_elapsed_since_last_action3 = 0

    # Creating a loop to keep program running
    while True:
        laser_rect = pygame.Rect(spaceship_x + 69, 70, 4, 310)
        # --- Event Processing and controls
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    spaceship_x_change = 10
                elif event.key == pygame.K_LEFT:
                    spaceship_x_change = -10
                elif event.key == pygame.K_r:
                    red = (255, 0, 0)
                elif time_elapsed_since_last_action2 > 250:
                    pygame.draw.rect(game_display, red, laser_rect)
                    time_elapsed_since_last_action2 = 0
            elif event.type == pygame.KEYUP:
                spaceship_x_change = 0
                red = (0, 0, 0)

        spaceship_x += spaceship_x_change

        # Preventing the ship from going off the screen
        if spaceship_x > display_width - 140:
            spaceship_x -= 10
        if spaceship_x < 1:
            spaceship_x += 10

        # Setting Display color
        game_display.fill(black)

        laser_coords = [70, 209, 348, 505, 630]

        random_x_coord = random.choice(laser_coords)

        dt = clock.tick()

        time_elapsed_since_last_action += dt

        if time_elapsed_since_last_action > 500:
            pygame.draw.rect(game_display, blue, [random_x_coord, 85, 6, 305])
            time_elapsed_since_last_action = 0

        time_elapsed_since_last_action2 += dt

        # Creating a spaceship, lasers, and enemies
        game_display.blit(spaceship, (spaceship_x, spaceship_y))
        message(str(blue_enemy_health), white, 65, 10, font, game_display)
        game_display.blit(blue_enemy, (20, 25))
        message(str(green_enemy_health), white, 203, 10, font, game_display)
        game_display.blit(green_enemy, (160, 25))
        message(str(orange_enemy_health), white, 341, 10, font, game_display)
        game_display.blit(orange_enemy, (300, 25))
        message(str(pink_enemy_health), white, 496, 10, font, game_display)
        game_display.blit(pink_enemy, (440, 25))
        message(str(yellow_enemy_health), white, 623, 10, font, game_display)
        game_display.blit(yellow_enemy, (580, 25))

        health = 10

        message("Spaceship durability: " + str(health), white, 20, 480, small_font, game_display)

        # Updating Screen so changes take places
        pygame.display.update()

        # Setting FPS
        FPS = pygame.time.Clock()
        FPS.tick(60)


black = (0, 0, 0)
white = (255, 255, 255)
gray = (100, 100, 100)

while True:
    intro_display.fill(black)
    pygame.event.poll()
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    message("Space Bugs", white, 180, 150, large_font, intro_display)
    if 150 + 100 > mouse[0] > 150 and 350 + 50 > mouse[1] > 350:
        pygame.draw.rect(game_display, gray, [150, 350, 100, 50])
        if click[0] == 1:
            break
    else:
        pygame.draw.rect(game_display, white, [150, 350, 100, 50])

    if 450 + 100 > mouse[0] > 450 and 350 + 50 > mouse[1] > 350:
        pygame.draw.rect(game_display, gray, [450, 350, 100, 50])
        if click[0] == 1:
            pygame.quit()
            quit()
    else:
        pygame.draw.rect(game_display, white, [450, 350, 100, 50])

    message("Start", black, 155, 360, font, intro_display)
    message("Quit", black, 465, 360, font, intro_display)

    # Go ahead and update the screen with what we've drawn.
    pygame.display.update()

    # Wrap-up
    # Limit to 60 frames per second
    clock = pygame.time.Clock()
    clock.tick(60)

# Executing the function
if __name__ == "__main__":
    main()

Advertisement

Answer

No, there is no such a “thing” as a “color collision”. What color have the images? Are they uniformly colored? Most likely the pictures are only different in some details. A collision which checks for a uniform color is completely useless. A collision that also looks for a uniform color is almost useless.

If you detect a collision, you know the laser and the enemy. Hence, you know the color with which you represent them. All you have to do is do an additional check after the collision is detected.


Use pygame.sprite.Sprite to implement the objects. Add an attribute that indicates the color of the object:

class ColoredSprite(pygame.sprite.Sprite):
    def __init__(self, x, y, image, color):
        super().__init__()
        self.image = image
        self.rect = self.image.get_rect(center = (x, y)
        slef.color = color 

Manage the spites in pygame.sprite.Groups and use spritecollide to detect the collisions. Check the color attributes when a collision is detected

collide_list = sprite.spritecollide(sprite_group, False):
for other_sprite in collide_list:

    if sprite.color == 'red' and other_sprite.color == 'blue':
        # [...] 

    elif sprite.color == 'blue' and other_sprite.color == 'red':
        # [...] 

It is even possible to implement your own collision detection method and use it in combination with spritecollide by setting the optional collided argument:

def color_collision(sprite1, sprite2):
    if sprite1.rect.colliderect(sprite2.rect):
        return ((sprite1.color == 'red' and sprite2.color == 'blue') or
                (sprite1.color == 'blue' and sprite2.color == 'red')) 
    return false

collide_list = sprite.spritecollide(sprite_group, False, color_collision):
for other_sprite in collide_list:
    # [...]

Minimal example:

import pygame

pygame.init()
window = pygame.display.set_mode((250, 250))

sprite1 = pygame.sprite.Sprite()
sprite1.image = pygame.Surface((75, 75))
sprite1.image.fill('red')
sprite1.rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(75, 75)
sprite1.color = 'red'
sprite2 = pygame.sprite.Sprite()
sprite2.image = pygame.Surface((75, 75))
sprite2.image.fill('blue')
sprite2.rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(75, 75)
sprite2.color = 'blue'

all_group = pygame.sprite.Group([sprite2, sprite1])

def color_collision(sprite1, sprite2):
    if sprite1.rect.colliderect(sprite2.rect):
        return ((sprite1.color == 'red' and sprite2.color == 'blue') or
                (sprite1.color == 'blue' and sprite2.color == 'red')) 
    return False

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

    sprite1.rect.center = pygame.mouse.get_pos()
    collide = pygame.sprite.spritecollide(sprite1, all_group, False, color_collision)
    
    window.fill(0)
    all_group.draw(window)
    for s in collide:
        pygame.draw.rect(window, (255, 255, 255), s.rect, 5, 1)
    pygame.display.flip()

pygame.quit()
exit()
Advertisement