How do I make something respawn upon collision pygame

Viewed 55

I have been making a simple collecter game with enemies but I have no idea how to make the collectible spawn in a random position upon being collided with. Just like in many coin collecter games when the player collides with the coin, it spawns in a different spot and there is a scoring system I have tried too many times but it has failed. Please help! Here is my code:

#import some libraries
import sys
import random
import pygame
from pygame import mixer


pygame.init()
mixer.init()
pygame.font.init()
width = 1440
height = 810
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('test')
collectible_img = pygame.image.load('img/collectible.png')
pygame.display.set_icon(collectible_img)
white = (255, 255, 255)
intro = pygame.mixer.Sound('sfx/intro.ogg')
gameplay = pygame.mixer.Sound('sfx/gameplay.ogg')
coll_audio = pygame.mixer.Sound('sfx/cool.ogg')
screen_rect = screen.get_rect()
score = 0
txt = pygame.font.SysFont("Britannic Bold", 40)
class Player(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('img/player.png')
        self.rect = self.image.get_rect()
        self.x = 300
        self.y = 640
        self.speed = 10

    def keyboard(self, keys):
        if keys[pygame.K_UP]:
            self.y -= self.speed
        if keys[pygame.K_DOWN]:
            self.y += self.speed
        if keys[pygame.K_RIGHT]:
            self.x += self.speed
        elif keys[pygame.K_LEFT]:
            self.x -= self.speed
    def update(self):
        self.rect.topleft = self.x, self.y


class Collectible(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('img/collectible.png')
        self.rect = self.image.get_rect()
        self.x = 200
        self.y = 100

    def update(self):
        self.rect.topleft = self.x, self.y
class Enemy(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('img/enemy.png')
        self.rect = self.image.get_rect()
        self.movementx = random.randrange(10, 50)
        self.movementy = random.randrange(10, 50)
        self.x = 900
        self.y = 500
    def update(self):
        self.rect.topleft = self.x, self.y
def play_screen(end_it, cutscence):
    while (end_it == False):
        screen.fill(white)
        intro.play(0)
        bg = pygame.image.load('img/splashscreen.png')
        font = pygame.font.SysFont("Britannic Bold", 40)
        label = font.render("test", 1, (255, 0, 0))
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                end_it = True
                intro.stop()
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
                gameplay.stop()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                    gameplay.stop()
                    intro.stop()
        screen.blit(bg, (0, 0))
        pygame.display.flip()
    while (cutscence == False): 
        coll_audio.play(0)
        test2 = pygame.image.load('img/player.png')
        screen.fill((0, 0, 0))
        text = font.render("Click to continue", 1, (255, 255, 255))
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                cutscence = True
                coll_audio.stop()
                gameplay.play(0)
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
        screen.blit(text, (50, 50))
        screen.blit(test2, (500, 500))
        pygame.display.flip()

def play_again():
    player = Player()
    collectible = Collectible()
    enemy = Enemy()
    all_sprites = pygame.sprite.Group(player, collectible, enemy)
    collectibles = pygame.sprite.Group(collectible)
    enemies = pygame.sprite.Group(enemy)
    pos = pygame.mouse.get_pos()
    global score
    clock = pygame.time.Clock()
    running = True
    end_it = False
    game = False
    cutscence = False
    end_screen = False
    exit_screen = False
    while running:
        while (exit_screen == True):
            font = pygame.font.SysFont("Britannic Bold", 40)
            exit_img = pygame.image.load('img/death.png')
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    exit_screen = False
                    gameplay.play()
                    play_again()
                if event.type == pygame.QUIT:
                    exit_screen = False
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        exit_screen = False
                        pygame.quit()
                        sys.exit()
            screen.blit(exit_img, (0, 0))
            pygame.display.flip()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    running = False
                    sys.exit()
        keys = pygame.key.get_pressed()
        player.keyboard(keys)
        all_sprites.update()
        global collided_collectibles
        collided_collectibles = pygame.sprite.spritecollide(player, collectibles, True)
        for collided_collectible in collided_collectibles:
            print('Collision.')
            score += 1
        collided_enemies = pygame.sprite.spritecollide(player, enemies, False)
        for collided_enemy in collided_enemies:
            exit_screen = True
            score *= 0
            gameplay.stop()
        screen.fill((255, 255, 255))
        score_counter = txt.render("Score: " + str(score), 1, (0, 0, 0))
        screen.blit(score_counter, (0, 0))
        all_sprites.draw(screen)
        pygame.display.flip()
        clock.tick(30)

play_screen(False, False)
play_again()
pygame.quit()
sys.exit()
1 Answers

I think the problem is that you hardcorded the spawn coordinates of your class Collectible. You could make a little function which generates a random number in range of width and height of your screen and pass it as argument when creating a new instance of the class.

Function for random spawn coordinates:

import random
def spawn_random():
    spawn_x = random.randint(0, 1440)
    spawn_y = random.randint(0,810)
    return spawn_x, spawn_y # returns a tuple, e.g (200, 400)

Your class needs some little changes:

class Collectible(pygame.sprite.Sprite):
    def __init__(self, xy_spawn):
        super().__init__()
        self.image = pygame.image.load('img/collectible.png')
        self.x, self.y = xy_spawn
        self.rect = self.image.get_rect(topleft=(self.x, self.y))

When creating an instance for the first time collectible = Collectible((200,100) you can use your start coordinates where you like to spawn it to start with. After that, everytime the collectible should be spawned again (after collision or any other event) you call it like this:

collectible = Collectible(spawn_random())
Related