pythonpgzero

Fuel cans not showing up


I'm programming a game in Python 3.7 using the module Pygame zero. The name of the game is "Road rage". I'm trying to make fuel cans showing up on he road to collect them, but for some reason they're not showing up. I've tried to print out how many fuel cans there are in the console and it isn't even getting the actors created. It isn't comming up any error messages, it's just not creating the fuel cans.

# Setting the window on center of the screen

import pygame
WIDTH = 720
HEIGHT = 710
pygame.display.set_mode((WIDTH, HEIGHT))

# Importing
from pgzrun import go
from random import choice
WIDTH = 720
HEIGHT = 710

# Variables
TITLE = 'Road Rage'
mode = 'menu'
CAR_IMAGES = ['blue_car', 'pink_car', 'red_car']
road = Actor('road', (WIDTH - 70, HEIGHT), anchor=('right', 'bottom'))
player = Actor('main_car', (WIDTH / 2, HEIGHT))
random_cars = [Actor('red_car', (choice([WIDTH / 2 - 200, WIDTH / 2, WIDTH / 2 + 200]), -250))]
delay = 0.01
fuel_level = 1000
fuel_cans = [Actor('fuel_bag', (choice([WIDTH/2-200, WIDTH/2, WIDTH/2+200]), -250))]


def draw():
    global delay
    if mode is 'game':
        screen.fill((31, 201, 0))
        road.draw()
        player.draw()
        for car in random_cars:
            car.draw()
        for fuel_bag in fuel_cans:
            fuel_bag.draw()
        screen.draw.text(str(fuel_level), (20, 20))
    elif mode is 'menu':
        screen.fill((4, 173, 238))
        player.draw()
        if player.y > WIDTH / 2:
            clock.schedule(up_one_px, delay)

        screen.draw.text('ROAD RAGE', center=(WIDTH / 2, 40), fontsize=100, fontname='font')
        screen.draw.text('EXPLORE THE TRUE ROAD RAGE AND DRIVE YOUR CAR AROUND THE CITY', center=(WIDTH / 2, 88), fontsize=16, fontname='font')
        screen.draw.text('PRESS SPACE TO START THE GAME!',
                         center=(WIDTH / 2, 150), fontsize=35, fontname='font')
        delay += 0.01

def update():
    global fuel_level, mode


    if mode is 'menu' and player.y < HEIGHT / 2:
        player.y = HEIGHT / 2
    if mode is 'game':
        fuel_level -= 1
        if fuel_level <= 0:
            mode = 'game over'
        for bag in fuel_cans:
            for car in random_cars:
                while bag.colliderect(car):
                    bag.x = choice([WIDTH/2-200, WIDTH/2, WIDTH/2+200])
        update_road()
        update_random_cars()
        player.y = HEIGHT / 2 + 200


def up_one_px():
    player.y -= 7


def update_road():
    road.y += 10
    if road.y >= HEIGHT + 600:
        road.y = HEIGHT


def new_random_car():
    random_cars.append(Actor(choice(CAR_IMAGES), (choice([WIDTH / 2 - 200, WIDTH / 2, WIDTH / 2 + 200]), -250)))


def new_fuel_bag():
    fuel_cans.append(Actor('fuel_bag', (choice([WIDTH/2-200, WIDTH/2, WIDTH/2+200]), -250)))

def update_random_cars():
    global mode
    if random_cars[-1].y >= 400:
        new_random_car()
    for car in random_cars:
        car.y += 10
        if car.colliderect(player) or fuel_level <= 0:
            mode = 'game over'
        elif car.y > WIDTH + 250:
            random_cars.remove(car)


def update_fuel_cans():
    global fuel_level
    if fuel_cans[-1].y >= 400:
        new_fuel_bag()
    for fuel_bag in fuel_cans:
        fuel_bag.y += 10
        if fuel_bag.colliderect(player):
            fuel_level += 200
        elif fuel_bag.y < WIDTH + 250:
            fuel_cans.remove(fuel_bag)


def on_key_down(key):
    global mode
    if mode is 'game':
        if key == keys.LEFT:
            if player.x == WIDTH / 2 or player.x == WIDTH / 2 + 200:
                player.x -= 200
        elif key == keys.RIGHT:
            if player.x == WIDTH / 2 - 200 or player.x == WIDTH / 2:
                player.x += 200
    elif mode is 'menu':
        if key is keys.SPACE:
            mode = 'game'

go()

Solution

  • You missed to call update_fuel_cans. Call update_fuel_cans in update:

    def update():
        global fuel_level, mode
    
        if mode is 'menu' and player.y < HEIGHT / 2:
            player.y = HEIGHT / 2
        if mode is 'game':
            fuel_level -= 1
            if fuel_level <= 0:
                mode = 'game over'
            for bag in fuel_cans:
                for car in random_cars:
                    while bag.colliderect(car):
                        bag.x = choice([WIDTH/2-200, WIDTH/2, WIDTH/2+200])
            update_road()
            update_random_cars()
            update_fuel_cans()                   # <--- this is missing
            player.y = HEIGHT / 2 + 200
    

    The problem is the condition that causes the file bag to be removed:

    elif fuel_bag.y < WIDTH + 250:
       fuel_cans.remove(fuel_bag)
    

    The condition is always true. Therefore the bags are removed immediately.

    Likely it is ought to be:

    elif fuel_bag.y >= WIDTH:
        fuel_cans.remove(fuel_bag)
    

    If the player collects all the fuel bags, you will not create any new fuel bag at all. I suggest to create a fuel bag when fuel_cans list is empty:

    def update_fuel_cans():
        global fuel_level
    
        if len(fuel_cans) < 1 or fuel_cans[-1].y >= 400:
            new_fuel_bag()
    
        for fuel_bag in fuel_cans[:]:
            fuel_bag.y += 10
            if fuel_bag.colliderect(player):
                fuel_level += 200
                fuel_cans.remove(fuel_bag)
            elif fuel_bag.y >= WIDTH:
                fuel_cans.remove(fuel_bag)