I am a beginner in Python learning to build a simple game in Pygame where the player(monkey) tries to catch as many bananas as possible falling from the top of the screen.
My problem is how to get the bananas to spawn and fall individually every x time/seconds. Either they all spawn at once or if I use time.sleep, pauses the bananas midair. Even used threading after getting completely lost.
The relevant components of my code are as follows:
catch_game
import sys
import pygame
from pygame.sprite import Group
from settings import Settings
# from background import Background
from monkey import Monkey
from banana import Banana
import functions
def run_game():
pygame.init()
settings = Settings()
screen = pygame.display.set_mode((settings.screen_width, settings.screen_height))
pygame.display.set_caption('Monkey Catch')
monkey = Monkey(screen, settings)
# background = Background((0, 0), screen)
bananas = Group()
functions.create_banana(screen, settings, bananas)
while True:
monkey.movement()
functions.check_events(monkey)
functions.update_screen(screen, settings, monkey, bananas)
functions.update_banana(monkey, bananas)
run_game()
banana
import pygame
from pygame.sprite import Sprite
from random import randint
class Banana(Sprite):
def __init__(self, screen, settings):
super(Banana, self).__init__()
self.screen = screen
self.settings = settings
self.image = pygame.image.load('E:\PycharmProjects\catch\images/banana.png')
self.rect = self.image.get_rect()
self.screen_rect = self.screen.get_rect()
self.y = self.screen_rect.top
self.y = float(self.rect.y)
self.x = randint(0, 1150)
self.speed = settings.banana_fallspeed
def update(self):
'''Banana falls down'''
self.y += self.settings.banana_fallspeed
self.rect.y = self.y
self.rect.x = self.x
def blit(self):
self.screen.blit(self.image, self.rect)
functions
import pygame
import sys
from banana import Banana
import threading
import time
def update_screen(screen, settings, monkey, bananas):
screen.fill([255, 255, 255])
# background.blit()
monkey.blit()
for banana in bananas:
banana.update()
bananas.draw(screen)
pygame.display.flip()
def keydown_events(event, monkey):
if event.key == pygame.K_RIGHT:
monkey.moving_right = True
if event.key == pygame.K_LEFT:
monkey.moving_left = True
def keyup_events(event, monkey):
if event.key == pygame.K_RIGHT:
monkey.moving_right = False
if event.key == pygame.K_LEFT:
monkey.moving_left = False
def check_events(monkey):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
keydown_events(event, monkey)
if event.type == pygame.KEYUP:
keyup_events(event, monkey)
def create_banana(screen, settings, bananas):
banana = Banana(screen, settings)
bananas.add(banana)
def update_banana(monkey, bananas):
'''kill bananas, collisions with monkey'''
for banana in bananas.copy():
if banana.rect.bottom >= 720:
bananas.remove(banana)
collision = pygame.sprite.spritecollide(monkey, bananas, True)
if collision:
bananas.remove(banana)
# time.sleep(2)
# fall_interval = banana.threading.Timer(3, create_banana(screen, settings, bananas))
# fall_interval.start()
I recommend to use a timer event. Use pygame.time.set_timer()
to repeatedly create an USEREVENT
. e.g.:
banana_delay = 500 # 0.5 seconds
banana_event = pygame.USEREVENT + 1
pygame.time.set_timer(banana_event, banana_delay)
Note, in pygame customer events can be defined. Each event needs a unique id. The ids for the user events have to be between pygame.USEREVENT
(24) and pygame.NUMEVENTS
(32). In this case pygame.USEREVENT+1
is the event id for the timer event, which spawns the bullets.
Create a new banana when the event occurs in the event loop:
def check_events(screen, settings, bananas, monkey):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# [...]
if event.type == banana_event:
create_banana(screen, settings, bananas)
The timer event can be stopped by passing 0 to the time parameter.
If you want spawn the bananas by a random time spawn, then you have to change the timespan (in milliseconds) randomly. Use random.randint(a, b)
to generate random times:
if event.type == banana_event:
create_banana(screen, settings, bananas)
banana_delay = random.randint(500, 3000) # random from 0.5 to 3 seconds
pygame.time.set_timer(banana_event, banana_delay)