'I cant figure out why the ammo the enemy/player is shooting doesnt dissapear after they die pygame
I'm trying to make a bossfight in my game. The boss is a wasp that shoots projectiles at the player. While the player is fighting the boss, he gets extra ammo every once in a while.
The only problem is that I can't figure out how to reset everything and make the game continue normally after the bossfight. The bosses projectiles continue dropping down but from a different position than the one where the boss died.
I'm using two diffrent classes for the bossfight: Boss an Projectile. I have different classes for the player's projectiles and the enemy's projectiles. I will attach images of the game.
import pygame
from pygame.locals import *
from random import randint
from time import sleep
class Bee(pygame.sprite.Sprite):
def __init__(self, x, y, alive, speed, score):
pygame.sprite.Sprite.__init__(self)
self.alive = alive
self.speed = speed
self.score = score
self.image = beeImg
self.rect = self.image.get_rect(center = (x, y))
self.shootfreq = 1 *1000
self.last_shot = pygame.time.get_ticks()
self.ammo = 1
def update(self):
key_input = pygame.key.get_pressed()
if key_input[pygame.K_LEFT]:
self.rect.x -= self.speed
if self.rect.left < 20:
self.rect.x += self.speed
elif key_input[pygame.K_RIGHT]:
if self.rect.right > screen_width - 50:
self.rect.x -= self.speed
self.rect.x += self.speed
def shoot(self):
if self.ammo > 0:
newShot = PlayerProjectile(self.rect.x, self.rect.y, 8, beeSting)
self.ammo -= 1
playerprojectiles.add(newShot)
else:
print("no ammo")
class Honey(pygame.sprite.Sprite):
def __init__(self, x, y,speed):
pygame.sprite.Sprite.__init__(self)
self.speed = speed
self.image = honeyImg
self.image = pygame.transform.scale(honeyImg, (60,60))
self.rect = self.image.get_rect(center = (x, y))
def update(self):
self.rect.y += 5
if self.rect.y > screen_height:
self.kill()
class Boss(pygame.sprite.Sprite):
def __init__(self, hp, speed, projectile, image, x, y):
pygame.sprite.Sprite.__init__(self)
self.speed = speed
self.hp = hp
self.projectile = projectile
self.x = x
self.y = y
self.image = image
self.rect = self.image.get_rect(center = (x, y))
self.side = 1
self.shoot = False
self.lastshot = pygame.time.get_ticks()
self.shootfreq = 0.5 * 1000
def update(self):
if bossNow:
if self.rect.right == screen_width -20:
self.side = -1
self.image = pygame.transform.flip(self.image, True, False)
if self.rect.left == 20:
self.side = 1
self.image = pygame.transform.flip(self.image, True, False)
self.timern = pygame.time.get_ticks()
self.rect.x += self.speed * self.side
if self.rect.y > screen_height:
self.kill()
else:
self.kill()
class Projectile(pygame.sprite.Sprite):
def __init__(self, x, y,speed, image, pos):
pygame.sprite.Sprite.__init__(self)
self.speed = speed
self.image = image
self.image = pygame.transform.scale(self.image, (40,40))
self.rect = self.image.get_rect(center = (x+40, y+40))
self.pos = pos
def update(self):
if bossNow:
self.rect.y += self.speed
if self.rect.y > screen_height:
self.kill()
else:
self.kill()
class PlayerProjectile(pygame.sprite.Sprite):
def __init__(self, x, y,speed, image):
pygame.sprite.Sprite.__init__(self)
self.speed = speed
self.image = image
self.image = pygame.transform.scale(self.image, (30,30))
self.rect = self.image.get_rect(center = (x+75, y+75))
def update(self):
self.rect.y -= self.speed
if self.rect.y > screen_height:
self.kill()
class Area():
def __init__(self, x=0 , y=0, width=10, height=10, color=None, state=False):
self.rect = pygame.Rect(x,y,width,height)
self.fill_color = color
def collidepoint(self,xpos, ypos):
return self.rect.collidepoint(xpos,ypos)
def color(self, new_color):
self.fill_color = new_color
def fill(self):
pygame.draw.rect(screen, self.fill_color, self.rect)
def outline(self, frame_color, thickness):
pygame.draw.rect(screen, frame_color, self.rect, thickness)
def collidepoints(self,x,y):
return self.rect.collidepoint(x,y)
class Label(Area):
def set_text(self, text, fsize=12, text_color=(0,0,0)):
self.image = pygame.font.SysFont('Bauhaus 93', fsize).render(text, True, text_color)
def draw(self, shift_x= 0, shift_y=0):
self.fill()
screen.blit(self.image, (self.rect.x + shift_x, self.rect.y + shift_y))
def collidepoints(self,x,y):
return self.rect.collidepoint(x,y)
def changesize(self, newHeight, newWidth, x, y):
self.height = newHeight
self.width = newWidth
self.rect = pygame.Rect(x,y,self.width,self.height)
pygame.init()
#game variables
clock = pygame.time.Clock()
last_hun = pygame.time.get_ticks()
last_attack = pygame.time.get_ticks()
attack_freq = 1 * 1000
hun_frequency = 0.5 * 1000 #milliseconds
fps = 60
bossNow = False
honeySpeed = 6
screen_width = 720
screen_height = 484
YELLOW = (150, 174, 217)
DARK_BLUE = (74, 78, 105)
BLUE = (74, 78, 105)
GREEN = (0, 255, 0)
RED = (255, 0 , 0)
WHITE = (225,232,244)
lastplayerattack = pygame.time.get_ticks()
playerattackfreq = 1 * 1000
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Bee on the Run!')
bgImg = pygame.image.load("background.png")
beeImg = pygame.image.load("bee.png")
honeyImg = pygame.image.load("honey.png")
waspImg = pygame.image.load("wasp.png")
poisonTooth = pygame.image.load("poisonousTooth.png")
beeSting = pygame.image.load("beeStinger.png")
scoreboard = Label(10, 10, 80, 80, YELLOW, False)
scoreboard.outline(DARK_BLUE, 20)
scoreboard.color(BLUE)
scoreboard.fill()
player = Bee(screen_width/2-50, screen_height/2 +200, True, 8, 0)
honeyGroup = pygame.sprite.Group()
playerGroup = pygame.sprite.Group()
playerGroup.add(player)
WaspBoss = Boss(100, 5, "hello world", waspImg, 150, 80)
WaspBoss.image = pygame.transform.scale(WaspBoss.image,(130,130))
bossGroup = pygame.sprite.Group()
bossGroup.add(WaspBoss)
projectileGroup = pygame.sprite.Group()
playerprojectiles = pygame.sprite.Group()
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == KEYDOWN:
if event.key == K_UP:
player.shoot()
time_now = pygame.time.get_ticks()
if time_now - last_hun > hun_frequency:
newHoney = Honey(randint(50, screen_width - 50),0, honeySpeed)
honeyGroup.add(newHoney)
last_hun = time_now
if time_now - lastplayerattack > playerattackfreq:
player.ammo += 1
lastplayerattack = time_now
if bossNow:
if time_now - last_attack > attack_freq:
newProjectile = Projectile(WaspBoss.rect.x, WaspBoss.rect.y, 8, poisonTooth, 1)
projectileGroup.add(newProjectile)
last_attack = time_now
#draw pics
player.update()
if bossNow == False:
honeyGroup.update()
if bossNow:
bossGroup.update()
projectileGroup.update()
playerprojectiles.update()
hits = pygame.sprite.spritecollide(player, honeyGroup, False, pygame.sprite.collide_mask)
if hits:
print(f"touched")
hits[0].kill()
player.score += 1000
print(player.score)
hits2 = pygame.sprite.spritecollide(player, projectileGroup, False, pygame.sprite.collide_mask)
if hits2:
print(f"touched")
hits2[0].kill()
player.kill()
hits3 = pygame.sprite.spritecollide(WaspBoss, playerprojectiles, False, pygame.sprite.collide_mask)
bossHits = 0
if hits3:
print(f"touched")
hits3[0].kill()
WaspBoss.kill()
bossHits+1
if bossHits == 10:
bossNow = False
WaspBoss.kill()
#hits4 = pygame.sprite.spritecollide(projectileGroup, playerprojectiles, False, pygame.sprite.collide_mas
screen.blit(bgImg,(0,0))
playerGroup.draw(screen)
if bossNow == False:
honeyGroup.draw(screen)
elif bossNow:
bossGroup.draw(screen)
projectileGroup.draw(screen)
playerprojectiles.draw(screen)
if player.score >= 100:
bossNow = True
else:
bossNow = False
#scoreboard.outline(YELLOW, 20)
#scoreboard.fill()
if player.score < 100:
scoreboard.set_text(str(player.score), 60)
scoreboard.changesize(80, 80, 10,10)
elif player.score >= 100 and player.score < 1000:
scoreboard.set_text(str(player.score), 60)
scoreboard.changesize(80, 120, 10,10)
elif player.score >= 1000 and player.score <10000:
scoreboard.set_text(str(player.score), 60)
scoreboard.changesize(80, 160, 10,10)
elif player.score >= 10000 and player.score <100000:
scoreboard.set_text(str(player.score), 60)
scoreboard.changesize(80, 200, 10,10)
else:
scoreboard.set_text("99999", 60)
#scoreboard.draw()
pygame.display.update()
pygame.quit()
Solution 1:[1]
The problem is that the following block of code always resets BossNow to True, also after the boss is already defeated.
if player.score >= 100:
bossNow = True
else:
bossNow = False
So, you have to add something to prevent this from happening. I would use a BossDefeated variable for this.
In order to implement this, you have to make the following changes:
1: Initialise the BossDefeated variable to False, by adding the following line before the game loop:
BossDefeated=False
2: Make that the BossDefeated variable has an effect by changing the first block of code into this:
if player.score >= 100 and not BossDefeated:
bossNow = True
else:
bossNow = False
3: Set the BossDefeated variable being set to True when the boss is defeated, by adding the following line after every call of WaspBoss.kill:
BossNow=True
We also need to add the following line in the function definition of Boss.update, to get the change of BossDefeated into the global scope.
global BossDefeated
As you asked for it, here's the complete code:
import pygame
from pygame.locals import *
from random import randint
from time import sleep
class Bee(pygame.sprite.Sprite):
def __init__(self, x, y, alive, speed, score):
pygame.sprite.Sprite.__init__(self)
self.alive = alive
self.speed = speed
self.score = score
self.image = beeImg
self.rect = self.image.get_rect(center = (x, y))
self.shootfreq = 1 *1000
self.last_shot = pygame.time.get_ticks()
self.ammo = 1
def update(self):
key_input = pygame.key.get_pressed()
if key_input[pygame.K_LEFT]:
self.rect.x -= self.speed
if self.rect.left < 20:
self.rect.x += self.speed
elif key_input[pygame.K_RIGHT]:
if self.rect.right > screen_width - 50:
self.rect.x -= self.speed
self.rect.x += self.speed
def shoot(self):
if self.ammo > 0:
newShot = PlayerProjectile(self.rect.x, self.rect.y, 8, beeSting)
self.ammo -= 1
playerprojectiles.add(newShot)
else:
print("no ammo")
class Honey(pygame.sprite.Sprite):
def __init__(self, x, y,speed):
pygame.sprite.Sprite.__init__(self)
self.speed = speed
self.image = honeyImg
self.image = pygame.transform.scale(honeyImg, (60,60))
self.rect = self.image.get_rect(center = (x, y))
def update(self):
self.rect.y += 5
if self.rect.y > screen_height:
self.kill()
class Boss(pygame.sprite.Sprite):
def __init__(self, hp, speed, projectile, image, x, y):
pygame.sprite.Sprite.__init__(self)
self.speed = speed
self.hp = hp
self.projectile = projectile
self.x = x
self.y = y
self.image = image
self.rect = self.image.get_rect(center = (x, y))
self.side = 1
self.shoot = False
self.lastshot = pygame.time.get_ticks()
self.shootfreq = 0.5 * 1000
def update(self):
global BossDefeated
if bossNow:
if self.rect.right == screen_width -20:
self.side = -1
self.image = pygame.transform.flip(self.image, True, False)
if self.rect.left == 20:
self.side = 1
self.image = pygame.transform.flip(self.image, True, False)
self.timern = pygame.time.get_ticks()
self.rect.x += self.speed * self.side
if self.rect.y > screen_height:
self.kill()
BossDefeated=True
else:
self.kill()
BossDefeated=True
class Projectile(pygame.sprite.Sprite):
def __init__(self, x, y,speed, image, pos):
pygame.sprite.Sprite.__init__(self)
self.speed = speed
self.image = image
self.image = pygame.transform.scale(self.image, (40,40))
self.rect = self.image.get_rect(center = (x+40, y+40))
self.pos = pos
def update(self):
if bossNow:
self.rect.y += self.speed
if self.rect.y > screen_height:
self.kill()
else:
self.kill()
class PlayerProjectile(pygame.sprite.Sprite):
def __init__(self, x, y,speed, image):
pygame.sprite.Sprite.__init__(self)
self.speed = speed
self.image = image
self.image = pygame.transform.scale(self.image, (30,30))
self.rect = self.image.get_rect(center = (x+75, y+75))
def update(self):
self.rect.y -= self.speed
if self.rect.y > screen_height:
self.kill()
class Area():
def __init__(self, x=0 , y=0, width=10, height=10, color=None, state=False):
self.rect = pygame.Rect(x,y,width,height)
self.fill_color = color
def collidepoint(self,xpos, ypos):
return self.rect.collidepoint(xpos,ypos)
def color(self, new_color):
self.fill_color = new_color
def fill(self):
pygame.draw.rect(screen, self.fill_color, self.rect)
def outline(self, frame_color, thickness):
pygame.draw.rect(screen, frame_color, self.rect, thickness)
def collidepoints(self,x,y):
return self.rect.collidepoint(x,y)
class Label(Area):
def set_text(self, text, fsize=12, text_color=(0,0,0)):
self.image = pygame.font.SysFont('Bauhaus 93', fsize).render(text, True, text_color)
def draw(self, shift_x= 0, shift_y=0):
self.fill()
screen.blit(self.image, (self.rect.x + shift_x, self.rect.y + shift_y))
def collidepoints(self,x,y):
return self.rect.collidepoint(x,y)
def changesize(self, newHeight, newWidth, x, y):
self.height = newHeight
self.width = newWidth
self.rect = pygame.Rect(x,y,self.width,self.height)
pygame.init()
#game variables
clock = pygame.time.Clock()
last_hun = pygame.time.get_ticks()
last_attack = pygame.time.get_ticks()
attack_freq = 1 * 1000
hun_frequency = 0.5 * 1000 #milliseconds
fps = 60
bossNow = False
honeySpeed = 6
screen_width = 720
screen_height = 484
YELLOW = (150, 174, 217)
DARK_BLUE = (74, 78, 105)
BLUE = (74, 78, 105)
GREEN = (0, 255, 0)
RED = (255, 0 , 0)
WHITE = (225,232,244)
lastplayerattack = pygame.time.get_ticks()
playerattackfreq = 1 * 1000
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Bee on the Run!')
bgImg = pygame.image.load("background.png")
beeImg = pygame.image.load("bee.png")
honeyImg = pygame.image.load("honey.png")
waspImg = pygame.image.load("wasp.png")
poisonTooth = pygame.image.load("poisonousTooth.png")
beeSting = pygame.image.load("beeStinger.png")
scoreboard = Label(10, 10, 80, 80, YELLOW, False)
scoreboard.outline(DARK_BLUE, 20)
scoreboard.color(BLUE)
scoreboard.fill()
player = Bee(screen_width/2-50, screen_height/2 +200, True, 8, 0)
honeyGroup = pygame.sprite.Group()
playerGroup = pygame.sprite.Group()
playerGroup.add(player)
WaspBoss = Boss(100, 5, "hello world", waspImg, 150, 80)
WaspBoss.image = pygame.transform.scale(WaspBoss.image,(130,130))
bossGroup = pygame.sprite.Group()
bossGroup.add(WaspBoss)
projectileGroup = pygame.sprite.Group()
playerprojectiles = pygame.sprite.Group()
BossDefeated=False
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == KEYDOWN:
if event.key == K_UP:
player.shoot()
time_now = pygame.time.get_ticks()
if time_now - last_hun > hun_frequency:
newHoney = Honey(randint(50, screen_width - 50),0, honeySpeed)
honeyGroup.add(newHoney)
last_hun = time_now
if time_now - lastplayerattack > playerattackfreq:
player.ammo += 1
lastplayerattack = time_now
if bossNow:
if time_now - last_attack > attack_freq:
newProjectile = Projectile(WaspBoss.rect.x, WaspBoss.rect.y, 8, poisonTooth, 1)
projectileGroup.add(newProjectile)
last_attack = time_now
#draw pics
player.update()
if bossNow == False:
honeyGroup.update()
if bossNow:
bossGroup.update()
projectileGroup.update()
playerprojectiles.update()
hits = pygame.sprite.spritecollide(player, honeyGroup, False, pygame.sprite.collide_mask)
if hits:
print(f"touched")
hits[0].kill()
player.score += 1000
print(player.score)
hits2 = pygame.sprite.spritecollide(player, projectileGroup, False, pygame.sprite.collide_mask)
if hits2:
print(f"touched")
hits2[0].kill()
player.kill()
hits3 = pygame.sprite.spritecollide(WaspBoss, playerprojectiles, False, pygame.sprite.collide_mask)
bossHits = 0
if hits3:
print(f"touched")
hits3[0].kill()
WaspBoss.kill()
BossDefeated=True
bossHits+1
if bossHits == 10:
bossNow = False
WaspBoss.kill()
BossDefeated=True
#hits4 = pygame.sprite.spritecollide(projectileGroup, playerprojectiles, False, pygame.sprite.collide_mas
screen.blit(bgImg,(0,0))
playerGroup.draw(screen)
if bossNow == False:
honeyGroup.draw(screen)
elif bossNow:
bossGroup.draw(screen)
projectileGroup.draw(screen)
playerprojectiles.draw(screen)
if player.score >= 100 and not BossDefeated:
bossNow = True
else:
bossNow = False
#scoreboard.outline(YELLOW, 20)
#scoreboard.fill()
if player.score < 100:
scoreboard.set_text(str(player.score), 60)
scoreboard.changesize(80, 80, 10,10)
elif player.score >= 100 and player.score < 1000:
scoreboard.set_text(str(player.score), 60)
scoreboard.changesize(80, 120, 10,10)
elif player.score >= 1000 and player.score <10000:
scoreboard.set_text(str(player.score), 60)
scoreboard.changesize(80, 160, 10,10)
elif player.score >= 10000 and player.score <100000:
scoreboard.set_text(str(player.score), 60)
scoreboard.changesize(80, 200, 10,10)
else:
scoreboard.set_text("99999", 60)
#scoreboard.draw()
pygame.display.update()
pygame.quit()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |






