My player attacks by throwing their weapon at the enemies. This is currently done by using a singular sword that gets thrown, then teleports back to the player to be thrown again. I want to change this so that I have a class called sword which I can call when the player wants to throw a weapon. However, I have no idea how to do collision between to sprite groups. Heres an example of how my collision currently works (Its easier to just show the whole enemy class)
class Bat(pygame.sprite.Sprite):
def __init__(self, bat_x, bat_y, bat_image, bat_health, bat_immune, const, dash_counter, dash, dash_time, fly_count, fly_time): #There is an indent in the actual code, but stack overflow removed it in copying and pasting
pygame.sprite.Sprite.__init__(self)
self.bat_health = bat_health
self.bat_immune = bat_immune
self.const = const
self.dash_counter = dash_counter
self.dash = dash
self.dash_time = dash_time
self.fly_count = fly_count
self.fly_time = fly_time
self.image = bat_image
self.rect = self.image.get_rect()
self.mask = pygame.mask.from_surface(self.image)
self.rect.topleft = (bat_x, bat_y)
self.bat_x = bat_x
self.bat_y = bat_y
def fly(self):
global dash_time
global dash
global const
x = player_rect.centerx - self.rect.centerx
y = player_rect.centery - self.rect.centery
if x == 0:
x = 0.1
if y == 0:
y = 0.1
self.dash_counter = random.randint(0, 120)
if self.dash_counter == 30:
if self.dash == False:
self.dash_time = pygame.time.get_ticks() ##def self in __init__
self.dash = True
self.const = 5.5
if pygame.time.get_ticks() - self.dash_time > 1500:
self.dash = False
self.const = 3
norm = (x**2 + y**2)**0.5
self.bat_x += self.const * x / norm
self.bat_y += self.const * y / norm
if self.const * y / norm > 0:
if self.fly_count == 0:
self.image = bat_front1
self.fly_time = pygame.time.get_ticks()
self.fly_count = 1
if self.fly_count == 1:
if pygame.time.get_ticks() - self.fly_time > 600:
self.image = bat_front2
if pygame.time.get_ticks() - self.fly_time > 1200:
self.fly_count = 0
if self.const * y / norm < 0:
if self.fly_count == 0:
self.image = bat_back1
self.fly_time = pygame.time.get_ticks()
self.fly_count = 1
if self.fly_count == 1:
if pygame.time.get_ticks() - self.fly_time > 600:
self.image = bat_back2
if pygame.time.get_ticks() - self.fly_time > 1200:
self.fly_count = 0
def update(self): ##RELEVANT##
global player_immune
global player_health
global immune_time
global player_hitsound
global enemy_hitsound
global dmg_multiplier
self.rect.topleft = (self.bat_x, self.bat_y)
bat_immune = False
bat_health = 5
offsetP2B = (int(x - self.bat_x), int(y - self.bat_y)) #Player to Bat
resultP2B = self.mask.overlap(player_mask, offsetP2B)
if resultP2B:
if player_immune == False:
if invincibility_potion_activ == False:
player_health -= 1
player_hitsound.play()
immune_time = pygame.time.get_ticks()
player_immune = True
offsetS2B = (int(fx - self.bat_x), int(fy - self.bat_y)) #Sword to Bat
resultS2B = self.mask.overlap(sword_mask, offsetS2B)
if resultS2B:
if self.bat_immune == False:
if fire == True:
self.bat_health -= 1 * dmg_multiplier
enemy_hitsound.play()
self.bat_time = pygame.time.get_ticks()
self.bat_immune = True
if self.bat_health <= 0:
self.kill()
if self.bat_immune == True:
if pygame.time.get_ticks() - self.bat_time > 100:
self.bat_immune = False
self.fly()
all_bats = pygame.sprite.Group()
This works perfectly, but I want my weapon to be like the enemies, a sprite group so I can have multiple on the screen at one time, but then how would I do the collision?? I honestly have no clue how to work around this problem!
I believe pygame.sprite.groupcollide() is what you are looking for? "Find all sprites that collide between two groups."
You could also use pygame.sprite.spritecollideany() if you wanted to go through them one sword at time.