Reputation: 69
Wonder if anyone could help. I am making a very simple pygame game. A number of balls fall from the top and can hit a player or be caught. A ball will disappear after a certain number of bounces
I want to be able to control the number of balls on screen at once. I can record when a ball 'dies' or is caught but not sure how to count the number present on screen.
I apologies if the code example is insufficient. I have created a ball sprite class which handles individual ball position and animation and a level class which handles creating and populated the ball sprite group and then has a method which calls the ball animation method for each ball in the group. Obviously this level method runs in the main 'while True' loop to allow the animations to play out.
Here is the level class:
class Level():
def __init__(self, tot_balls = 20, max_onscreen = 5):
self.tot_balls = tot_balls
self.max_onscreen = max_onscreen
self.ball_group = pygame.sprite.Group()
self.current_onscreen = 0
for _ in range (self.tot_balls):
ball = Ball(random.randint(0, 800), random.randint(-50,50), random.randint(-1,1))
self.ball_group.add(ball)
def launch_balls(self):
#while self.current_onscreen < self.max_onscreen:
for ball in self.ball_group:
ball.ball_animation()
if ball.killed:
self.current_onscreen -= 1
and the ball class:
class Ball(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y, x_move=0):
super().__init__()
self.image = pygame.image.load('new_ball.png')
self.rect = self.image.get_rect()
self.rect.center = [pos_x, pos_y]
self.bounces = 0
self.gravity = 0
self.x_move = x_move
self.killed = False
self.present = 1
def ball_animation(self):
self.gravity +=1
self.rect.centery += self.gravity
self.rect.centerx += self.x_move
#print(f'Gravity is {self.gravity}. Bottom is {self.rect.bottom}')
if self.rect.bottom >= 300 and self.bounces > 4:
self.kill()
self.present = 0
self.killed = True
elif self.rect.bottom > 300:
self.rect.bottom = 300
self.bounces +=1
self.gravity *= -1
At the moment, all the ball are launched and animate all at once. I will try to put a timer in, but I really want to limit the number of balls on screen at once (you can see the commented out condition for when the current_onscreen < max_balls, but when I had python print the current onscreen it was enormous as the loop runs at 60fps. I was wondering if there is a way to count the 'launch' of a sprite only once?
Upvotes: 1
Views: 422
Reputation: 211125
One option is to use a timer event. Use pygame.time.set_timer()
to repeatedly create a USEREVENT
in the event queue. The time has to be set in milliseconds.
For a timer event you need to define a unique user events 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. Receive the event in the event loop:
timer_interval = 1000 # 1.0 seconds
timer_event_id = pygame.USEREVENT + 1
pygame.time.set_timer(timer_event_id, timer_interval)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == timer_event_id:
level.add_one_new_ball()
class Level():
def __init__(self, tot_balls = 20, max_onscreen = 5):
self.tot_balls = tot_balls
self.max_onscreen = max_onscreen
self.ball_group = pygame.sprite.Group()
self.current_onscreen = 0
def add_one_new_ball(self):
if len(self.ball_group) < self.tot_balls:
ball = Ball(random.randint(0, 800), random.randint(-50,50), random.randint(-1,1))
self.ball_group.add(ball)
See also Spawning multiple instances of the same object concurrently in python
Upvotes: 1