在我的游戏中,玩家可以通过按空格在屏幕上的任何地方投掷炸弹。 3秒后炸弹图像被爆炸图像取代。 如果我的玩家与爆炸图像相撞,我想减少他5点生命值。 我试过几种方法,但是,由于一些循环错误(我不知道),玩家在爆炸时不断失去健康。 我只想减少5点生命值一次,也就是说,如果他的生命值是100,他在爆炸,应该只减少到95,而不是继续下降。 我在下面附上我的完整代码。 谢谢你的帮助。
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()
首先不要在制造炸弹的时候加上爆炸:
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 + 2000 <--- DELETE
# explosions.append((pos2, end_time_2)) <--- DELETE
got_hit.append(False)
bombs.append((pos, end_time))
bag["bomb"] -= 1
当炸弹阈值超过时制造爆炸。 向元组添加一个额外的布尔属性,它指示plyer是否被炸弹伤害((pos2,end_time2,False)
):
for i in reversed(range(len(bombs))):
pos, end_time = bombs[i]
if current_time > end_time:
end_time_2 = end_time + 5000
pos2 = (pos[0] - 10, pos[1] - 30
explosions.append((pos2, end_time_2, False))
bombs.pop(i)
else:
screen.blit(pics[0], pos)
为炸弹和玩家创建一个pygame.rect
,并评估plyer是否与炸弹发生碰撞。 如果夹具与爆炸相撞,则更改元组中的伤害指示器。 pygame.rect
对象可以通过pygame.surface.get_rect
创建。 位置可以通过关键字参数设置(例如player_rect=player[0][0].get_rect(topleft=(x,y))
):
for j in reversed(range(len(explosions))):
pos, end_time_2, hurt = explosions[j]
if current_time > end_time_2:
explosions.pop(j)
else:
screen.blit(pics[1], pos)
if not hurt:
explosion_rect = pics[1].get_rect(topleft = pos)
player_rect = player[0][0].get_rect(topleft = (x, y))
if player_rect.colliderect(explosion_rect):
explosions[j] = (pos, end_time_2, True)
health -= 5