In my game the player can drop a bomb anywhere on the screen by pressing space. After 3 seconds the bomb image is replaced by an explosion image. I want to reduce 5 health from my player if he collides with the explosion image. I have tried several methods however, because of some looping mistake(which I can't figure out) the player keeps losing health while he is on the explosion. I want to just reduce 5 health once i.e if his health is 100 and he is on the explosion it should just reduce to 95 and not keep going down. I'm attaching my full code below. Thank you for your help.
import pygame
import random
import math
pygame.font.init()
width = 900
height = 600
screen = pygame.display.set_mode([width, height])
walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
char = pygame.image.load('standing.png')
bomb_pic = pygame.transform.scale(pygame.image.load('bomb.png'), (20, 20))
bomb_explosion = pygame.transform.scale(pygame.image.load('explosion1.png'), (40, 40))
pics = [bomb_pic, bomb_explosion]
shop = pygame.transform.scale(pygame.image.load("shop.png"), (60, 60))
boss = pygame.image.load("enemyboss.png")
player = [walkLeft, walkRight, char]
enemy_Left = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'),
pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'),
pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png')]
boss = pygame.image.load('pixel_monster.png')
position = [60, 60]
x = 50 # same as position
y = 50 # same as position
width = 40
height = 60
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
down = False
up = False
walkCount = 0
run_once = False
enemy_vel = 2
enemy_list = []
clock = pygame.time.Clock()
FPS = 60
font = pygame.font.Font('freesansbold.ttf', 32)
items_font = pygame.font.Font('freesansbold.ttf', 16)
font_small = pygame.font.Font('freesansbold.ttf', 18)
bombs = []
explosions = []
bag = {'bomb': 0}
# print(bag["bomb"])
health = 100
got_hit = []
class Button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 20)
text = font.render(self.text, 1, (0, 0, 0))
win.blit(text, (
self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def shop_run():
shop_bomb = Button((0, 200, 0), 820, 150, 60, 20, text="Bomb_b")
bright_green = (0, 255, 0)
green = (0, 200, 0)
shop_bomb.draw(screen)
def redrawGameWindow():
global walkCount
global font
global font_small
global bag
global items_font
global enemy_list
global pics
global position
global health
global run_once
global explosions
global got_hit
current_time = pygame.time.get_ticks()
dx = []
dy = []
dist = []
screen.fill([166, 166, 166])
pygame.draw.rect(screen, (220, 0, 0), (700, 500, 100, 100))
for five_enemies in range(5):
random_enemy_location_y = random.randrange(50, 500)
random_enemy_location_x = random.randrange(700, 840)
enemy_list.append([random_enemy_location_x, random_enemy_location_y])
for enemies in range(5):
screen.blit(enemy_Left[enemies], enemy_list[enemies])
dx.append(position[0] - enemy_list[enemies][0])
dy.append(position[1] - enemy_list[enemies][1])
dist.append(math.hypot(dx[enemies], dy[enemies]))
dx[enemies], dy[enemies] = dx[enemies] / dist[enemies], dy[enemies] / dist[enemies]
enemy_list[enemies][0] += dx[enemies] * 2
enemy_list[enemies][1] += dy[enemies] * 2
# for i in range(len(enemy_list)):
# for j in range(i + 1, len(enemy_list)):
# if enemy_list[i][0] - enemy_list[j][0] < 60:
# enemy_list[i][0] += 10
# elif enemy_list[i][1] - enemy_list[j][1]< 60:
# enemy_list[i][1] += 10
pygame.draw.rect(screen, (70, 0, 220), (0, 170, 100, 300)) # main base
pygame.draw.rect(screen, (220, 0, 0), (50, 200, 5, 250))
pygame.draw.rect(screen, (0, 220, 0), (50, 200, 5, 250))
screen.blit(font.render("B", True, (0, 0, 0)), (10, 200 + 40))
screen.blit(font.render("A", True, (0, 0, 0)), (10, 235 + 40))
screen.blit(font.render("S", True, (0, 0, 0)), (10, 270 + 40))
screen.blit(font.render("E", True, (0, 0, 0)), (10, 305 + 40))
pygame.draw.rect(screen, (220, 0, 0), (position[0] - 3, position[1], 50, 5))
pygame.draw.rect(screen, (0, 220, 0), (position[0] - 3, position[1], 50, 5))
pygame.draw.rect(screen, (0, 0, 0), (800, 0, 100, 600))
if x + char.get_width() < 60 and y + char.get_height() < 60:
shop_run()
screen.blit(shop, (0, 0))
screen.blit(font_small.render("Shop", True, (0, 0, 0)), (5, 5))
screen.blit(font.render("Menu", True, (255, 255, 255)), (805, 10))
screen.blit(items_font.render("Bombs: " + str(bag["bomb"]), True, (255, 255, 255)), (805, 550))
# screen.blit(bomb_explosion, (450, 300))
# screen.blit(boss, (450, 300))
if walkCount + 1 >= 27:
walkCount = 0
if left:
screen.blit(player[0][walkCount // 3], (x, y))
walkCount += 1
elif right:
screen.blit(player[1][walkCount // 3], (x, y))
walkCount += 1
elif down:
screen.blit(player[2], (x, y))
walkcount = 0
elif up:
screen.blit(player[2], (x, y))
walkcount = 0
else:
screen.blit(player[2], (x, y))
walkCount = 0
for i in reversed(range(len(bombs))):
pos, end_time = bombs[i]
if current_time > end_time:
bombs.pop(i)
else:
screen.blit(pics[0], pos)
for j in reversed(range(len(explosions))):
pos = explosions[j][0]
end_time_2 = explosions[j][1]
if current_time > end_time_2:
explosions.pop(j)
elif current_time > (end_time_2 - 2000):
screen.blit(pics[1], pos)
else:
continue
pygame.display.update()
def main():
run = True
pygame.display.set_caption("bomb-mania")
global x
global y
global width
global height
global vel
global isJump
global jumpCount
global left
global right
global down
global up
global walkCount
global bomb_pic
global font
global bombs
global explosions
global position
global got_hit
global pos2list
while run:
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if x + char.get_width() < 60 and y + char.get_height() < 60:
buy = pygame.key.get_pressed()
if buy[pygame.K_b]:
bag["bomb"] += 1
# print(bag["bomb"])
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and bag["bomb"] >= 1:
current_time_2 = pygame.time.get_ticks()
pos = x + char.get_width() / 2, y + char.get_height() - 20
pos2 = ((x + char.get_width() / 2) - 10), (y + char.get_height() - 30)
end_time = current_time + 3000 # 3000 milliseconds = 3 seconds
end_time_2 = current_time_2 + 5000
explosions.append((pos2, end_time_2))
# print(explosions[-1][0][0])
got_hit.append(False)
bombs.append((pos, end_time))
bag["bomb"] -= 1
redrawGameWindow()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel - 15:
x -= vel
position[0] -= vel
left = True
right = False
down = False
up = False
# print(position)
elif keys[pygame.K_RIGHT] and x < 800 - vel - width:
x += vel
position[0] += vel
left = False
right = True
down = False
up = False
# print(position)
elif keys[pygame.K_DOWN] and y < 600 - height:
y += vel
position[1] += vel
left = False
right = False
down = True
up = False
# print(position)
elif keys[pygame.K_UP] and y > vel - 15:
y -= vel
position[1] -= vel
left = False
right = False
down = False
up = True
# print(position)
else:
left = False
right = False
down = False
up = False
walkCount = 0
clock.tick(FPS)
pygame.display.flip()
main()