user8910724
user8910724

Reputation:

Pygame obstacles not being generated more than once

So right now I am learning pygame and I'm using sentdex's tutorials. On I believe his 6th pygame tutorial he showed us how to generate more than just one block. I added the code, but it didin't work. I don't understand why it didn't work? Could you please tell me what I'm doing wrong and how to fix it? Here's the code:

import pygame
import random

pygame.init()

white = (255,255,255)
black = (0,0,0)
red = (255,0,0)

window_width = 800
window_height = 600

gameDisplay = pygame.display.set_mode((window_width,window_height))
pygame.display.set_caption('MyFirstGame')

carImg = pygame.image.load("racecar.png")

clock = pygame.time.Clock()


def blocks(block_x, block_y, block_width, block_height, color):
    pygame.draw.rect(gameDisplay, color, [block_x, block_y, block_width, block_height])


def crash():
    print("YOUR GARBAGE! Press C to play again or Q to quit.")
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                pygame.quit
                quit()
                gameExit = True                
            if event.key == pygame.K_c:
                gameLoop()
                print("User has decided to play again")


def gameLoop():
    # Defining variables to draw and move car        
    car_x = 350
    car_y = 400
    car_x_change = 0

    car_w = 100
    car_h = 100

    # Defining variables to draw blocks

    block_x = random.randrange(0, window_width)
    block_y = -600
    block_speed = 7
    block_width = 100
    block_height = 100

    gameExit = False

    while not gameExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    car_x_change += -5
                if event.key == pygame.K_RIGHT:
                    car_x_change += 5
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    x_change = 0
                if event.key == pygame.K_RIGHT:
                    x_change = 0

        car_x += car_x_change
        gameDisplay.fill(white)
        # blocks((block_x,block_y,[block_width,block_height,black))
        blocks(block_x, block_y, block_width, block_height, black)
        block_y += block_speed

        gameDisplay.blit(carImg, (car_x,car_y))

        if car_x >= window_width:
                gameExit = True
                crash()
        if car_x <= 0:
                gameExit = True
                crash()
        if car_y > window_height:
            block_y = 0 - block_height
            block_x = random.randrange(0,window_width-block_width)

        pygame.display.update()
        clock.tick(30)


gameLoop()
pygame.quit
quit()

Upvotes: 1

Views: 90

Answers (1)

furas
furas

Reputation: 142878

One pair block_x, block_y can't be use to draw many blocks.

You have to create list with pairs (x,y) for all blocks which you want to draw. You have to use for loops to create blocks (pairs (x,y)), to move them, and to draw them.

BTW: running gameloop() inside crash() create recursion which is not prefered method.

My version with more information in comments # changed

import pygame
import random

# changed: better organized code

# --- constants --- (UPPERCASE_NAMES)

WHITE = (255,255,255)
BLACK = (0,0,0)
RED = (255,0,0)

WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600

# --- functions --- (lowercase_names)

def blocks(points, width, height, color):
    # changed: use `for` to draw all blocks
    for x, y in points:
        pygame.draw.rect(display, color, [x, y, width, height])

def crash():
    print("YOUR GARBAGE! Press C to play again or Q to quit.")

    # changed: return `True/False` insted of executing gameloop() 
    # because it was not good idea

    while True:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    return True # True = quit
                if event.key == pygame.K_c:
                    print("User has decided to play again")
                    return False # false = continue

def gameloop():

    # --- objects ---

    car_image = pygame.image.load("racecar.png")

    # Defining variables to draw and move car        
    car_x = 350
    car_y = 400
    car_x_change = 0

    car_w = 100
    car_h = 100

    # BTW: you could use `pygame.Rect` to keep position and size 
    # car_rect = car_image.get_rect(x=350, y=450)

    # Defining variables to draw blocks

    block_speed = 7
    block_width = 100
    block_height = 100

    # changed: create list with points x,y

    pairs = []
    for _ in range(10):
        x = random.randrange(0, WINDOW_WIDTH)
        y = -block_height
        pairs.append( (x, y) )

    # --- mainloop ---

    clock = pygame.time.Clock()

    gameExit = False

    while not gameExit:

        # --- events ---

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    car_x_change -= 5
                elif event.key == pygame.K_RIGHT:
                    car_x_change += 5
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    car_x_change += 5 # changed: wrong variable, use +=
                elif event.key == pygame.K_RIGHT:
                    car_x_change -= 5 # changed: wrong variable, use -=

        # --- updates ---

        # changed: all moves before draws

        # move car              
        car_x += car_x_change

        # changed: one `if` for both crashes (`car_x`)

        if car_x < 0 or car_x >= WINDOW_WIDTH:
                # changed: use value from crash to set gameExit 
                # and to move car to start position
                gameExit = crash()
                if not gameExit:
                    car_x = 350
                    car_y = 400

        # changed: use `for` to move all points 
        # and to check if they need new random place
        # move blocks
        moved_pairs = []
        for x, y in pairs:
            y += block_speed
            if y > WINDOW_HEIGHT:
                 y = -block_height
                 x = random.randrange(0, WINDOW_WIDTH - block_width)     
            moved_pairs.append( (x, y) )
        pairs = moved_pairs

        # --- draws ---

        # changed: all draws after moves

        display.fill(WHITE)

        blocks(pairs, block_width, block_height, BLACK)

        display.blit(car_image, (car_x, car_y))

        pygame.display.update()

        # --- FPS ---

        clock.tick(30)

# --- main ---

pygame.init()

display = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('MyFirstGame')

gameloop()

pygame.quit() # changed: forgot ()

Upvotes: 1

Related Questions