1

Hi sorry for the many questions but again I know python but am trying to learn pygame. In the game I'm making im trying to make it so when a block/image touches the sprite it goes back to the top of the screen. I have looked at many tutorials but can't seem to figure it our in a way that would work good. Any advice? Heres the code thanks!!!:

import pygame
import sys
from random import randint
import os

x = 250
y = 30

os.environ["SDL_VIDEO_WINDOW_POS"] = "%d,%d" % (x, y)

width = 1024
height = 768

icon1 = pygame.image.load("Firstpygamegame/santa-claus.png")
pygame.display.set_icon(icon1)

screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Gift Catcher")
background_image = pygame.image.load("Firstpygamegame/wintervillage.png")

sprite1 = pygame.image.load("Firstpygamegame/santabag2.png")
spriterect = sprite1.get_rect()
speed = 2.5
# 442 or 467
spriterect.x = 442
icon2 = pygame.image.load("Firstpygamegame/present1.png")
icon3 = pygame.image.load("Firstpygamegame/present2.png")
icon4 = pygame.image.load("Firstpygamegame/present3.png")
icon5 = pygame.image.load("Firstpygamegame/present4.png")

cubes = [[
    randint(1, 1000),  # X coordinate
    randint(-1500, -350)]  # Y coordinate, -Y is above screen  (top of screen is zero)
    for x in range(2)]  # 20 cubes

cubes1 = [[
    randint(1, 1000),  # X coordinate
    randint(-1500, -150)]  # Y coordinate, -Y is above screen  (top of screen is zero)
    for x in range(2)]  # 20 cubes

cubes2 = [[
    randint(1, 1000),  # X coordinate
    randint(-1500, -550)]  # Y coordinate, -Y is above screen  (top of screen is zero)
    for x in range(2)]  # 20 cubes

cubes3 = [[
    randint(1, 1000),  # X coordinate
    randint(-1500, -450)]  # Y coordinate, -Y is above screen  (top of screen is zero)
    for x in range(2)]  # 20 cubes

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            pygame.quit()
            sys.exit()

    keys = pygame.key.get_pressed()
    spriterect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
    spriterect.y = 600

    screen.blit(background_image, (0, 0))
    screen.blit(sprite1, spriterect)

    for cb in cubes:
        cb[1] += .25  # cube moves down 2 pixels
        screen.blit(icon2, cb)  # draw cube
        if cb[1] > 800:  # if cube passed bottom of screen
            cb[1] = -100  # move to above screen
            cb[0] = randint(1, 1000)

    for cb in cubes1:
        cb[1] += .25  # cube moves down 2 pixels
        screen.blit(icon3, cb)  # draw cube
        if cb[1] > 800:  # if cube passed bottom of screen
            cb[1] = -100  # move to above screen
            cb[0] = randint(1, 1000)  # random X position

    for cb in cubes2:
        cb[1] += .25  # cube moves down 2 pixels
        screen.blit(icon4, cb)  # draw cube
        if cb[1] > 800:  # if cube passed bottom of screen
            cb[1] = -100  # move to above screen
            cb[0] = randint(1, 1000)  # random X position

    for cb in cubes3:
        cb[1] += .25  # cube moves down 2 pixels
        screen.blit(icon5, cb)  # draw cube
        if cb[1] > 800:  # if cube passed bottom of screen
            cb[1] = -100  # move to above screen
            cb[0] = randint(1, 1000)  # random X position

    pygame.display.flip()
  • pygame has `pygame.Rect()` to keep object position and size - and it has methods to check collisions between two Rect or Rect and point. So you should use Rect with all cubes – furas Dec 12 '20 at 02:15

1 Answers1

1

Use a pygame.Rect object and colliderect() to find a collision between a rectangle and an object.
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. The position of the rectangle can be specified by a keyword argument:

while running:
    # [...]

    for cb in cubes:
        cb[1] += .25  # cube moves down 2 pixels
        screen.blit(icon2, cb)  # draw cube

        icon_rect = icon2.get_rect(topleft = cb)
        if cb[1] > 800 or icon_rect.colliderect(spriterect):  
            cb[1] = -100  # move to above screen
            cb[0] = randint(1, 1000)

    # [...]

However, you can simplify your code:

icon_list = [icon2, icon3, icon4, icon5]

cube_lists = [[[
    randrange(screen.get_width() - icon.get_width()),
    randint(-1500, -350)] 
    for x in range(2)]
    for icon in icon_list]

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

    keys = pygame.key.get_pressed()
    spriterect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
    spriterect.y = 600

    screen.blit(background_image, (0, 0))
    screen.blit(sprite1, spriterect)

    for icon, cubes in zip(icon_list, cube_lists):
        for cb in cubes:
            cb[1] += .25  # cube moves down 2 pixels
            screen.blit(icon, cb)  # draw cube

            icon_rect = icon.get_rect(topleft = cb)
            if cb[1] > screen.get_height() or icon_rect.colliderect(spriterect):  
                cb[:] = randrange(screen.get_width() - icon.get_width()), -800

    pygame.display.flip()

pygame.quit()
sys.exit()

Please note, the application loop terminates if running is False. There is no point in setting running = False and to call pygame.quit() and sys.exit() in the event loop. Let the loop run to the end and call pygame.quit() and sys.exit() after the event loop.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174