Reputation: 11
I'm trying to make the ladybug sprite shoot out the egg sprite whenever a condition is true
In this case that condition would be when the ladybug sprite hits the leaf sprites
I've managed to make that sort of happen but I'm unable to have it repeat it self It is only shooting once, I've tried a few different ways to make it work but I have been unsuccessful.
import pygame
import sys
import random
pygame.init()
res = (1000, 600)
pygame.display.set_caption("placeholder")
screen = pygame.display.set_mode(res)
worldbg = pygame.image.load("worldbg.png").convert_alpha()
clock = pygame.time.Clock()
class Egg(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.x = random.randint(1, 1000)
self.y = random.randint(1, 600)
self.x_speed = 0.2
self.y_speed = 0.2
self.x_direction = 1
self.y_direction = 1
self.frame = 0
super().__init__()
self.sprites = []
self.is_animating = False
self.sprites.append(pygame.image.load("egg.png"))
self.sprites.append(pygame.image.load("egg.png"))
self.sprites.append(pygame.image.load("egg.png"))
self.sprites.append(pygame.image.load("egg.png"))
self.current_sprite = 0
self.image = self.sprites[self.current_sprite]
self.rect = self.image.get_rect()
self.rect.center = [x, y]
def animate(self):
self.is_animating = True
def kill(self):
pygame.sprite.Sprite.kill(self)
def update(self):
if self.is_animating:
self.current_sprite += 0.20
if self.current_sprite >= len(self.sprites):
self.current_sprite = 0
self.is_animating = False
self.image = self.sprites[int(self.current_sprite)]
# this makes the bullet act like a heatsinking missile
if self.x < player.rect.x + 40:
self.x_direction = 8
self.x_direction = 4
elif self.x > player.rect.x + 40:
self.x_direction = -8
self.x_direction = -4
if self.y > player.rect.y + 40:
self.y_direction = -8
self.y_direction = -4
elif self.y < player.rect.y + 40:
self.y_direction = 8
self.y_direction = 4
self.x_speed = random.randint(1, 2) * self.x_direction
self.y_speed = random.randint(1, 2) * self.y_direction
self.x += self.x_speed
self.y += self.y_speed
self.rect.x = self.x
self.rect.y = self.y
self.rect.clamp_ip(screen.get_rect())
eggmis = False
lvl4 = True
lvl4sr = 0
ladybug = Ladybug(0, 0)
ladybug_sprites = pygame.sprite.Group()
ladybug_sprites.add(ladybug)
ladybug.rect.x = 0
ladybug.rect.y = 0
ladybug.list = pygame.sprite.Group()
ladybug.list.add(ladybug)
egg = Egg(0, 0)
egg_sprites = pygame.sprite.Group()
egg_sprites.add(egg)
egg.rect.x = 0
egg.rect.y = 0
egg.list = pygame.sprite.Group()
egg.list.add(egg)
# while loop starts here but I'll skip that
if lvl4sr >= 12:
lvl4 = True
if lvl4 is True:
chl = pygame.sprite.spritecollide(ladybug, leaf_sprites, False, pygame.sprite.collide_circle_ratio(0.2))
if chl:
playerhp -= 20
eggmis = True
if eggmis is True:
ehp = pygame.sprite.collide_circle(egg, player)
if ehp is True:
pygame.sprite.Sprite.kill(egg)
egg_sprites.draw(screen)
egg_sprites.update()
lvl4sr -= 6
this makes the bullet fires one time once the condition is reached then doesn't work
Upvotes: 1
Views: 40
Reputation: 14906
Here's one typical approach for implementing this "create & animate a transient object" type problem:
egg_list = [] # all eggs are held in this list/spritegroup/whatever
### main loop
# Update all entities:
for egg in egg_list:
egg.update() # move every egg by their (dx, dy)
# Handle collisions
for egg in egg_list: # collide every egg
if ( egg.collideswith( player ) ):
# remove egg from egg_list # the egg is 'used up'
# do some stuff to player
# Paint the screen
background.draw( window )
player.draw( window )
for egg in egg_list: # paint every egg to the window
egg.draw( window )
Note that we never handle a specific egg
arbitrarily. It's always handling whatever egg
is found in egg_list
. It doesn't matter if egg_list
is a Sprite Group, list, dictionary, whatever - the same program flow is used. The take-away point is that don't care how many eggs are in the list, we process all of them, in turn, the same way.
The benefit of this approach, is that now all egg handling is done as a batch. So now when an egg
object is created, it will automatically be moved, painted, animated etc.
So when your LadyBug
object collides with a Leaf
object, we can just add a new egg
to the egg_list
.
if ( ladybug.collideswith( leaf ) ):
egg_list.append( Egg( ladybug.x, ladybug.y, ... ) ) # create an egg
Your code is not handling the updating of egg
objects as a batch, and it is not creating a new egg
when the ladybird
collides with the leaf
.
Obviously the Sprite Group automates a lot of this for you, in particular the updating, colliding and drawing. But you need the supporting code to properly use those functions. Maybe you had all this, but didn't add it to the question.
Upvotes: 1