问题描述
我正在制作一个简单的游戏,其中有一个您可以射击的敌人,并且您可以在一定程度上从左向右移动。这样做之后,我想当敌人的生命值 > 70 时,你必须躲避一波子弹。我看到它有 3 个问题,一个它有残像,它不是一颗子弹从它下来,就像把它一直画下来一样。两个我显示了文本,如果点击它应该将该文本更改为 You Lost,但这是行不通的。即使我输入了三个代码,它也应该在 70 生命值时触发 >+ 70 生命值,它会产生子弹并且它们停留在顶部,然后当我尝试射击时它们会下降。对不起,如果这很多,但我不知道如何解决它。这是我的代码:
import pygame
import time
pygame.font.init()
WIDTH,HEIGHT = 900,500
WIN = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("Boss fight")
FPS = 60
WHITE = (255,255,255)
BLACK = (0,0)
BLUE = (0,255)
RED = (255,0)
FLOOR = pygame.Rect(0,400,900,100)
SPEED = 1
BULLET_SPEED = 1
player = pygame.Rect(50,350,50,50)
numJumps = []
MAXBULLETS = 2
BOSS = pygame.Rect(700,300,100,100)
FONT = pygame.font.SysFont('comicsans',30)
BOSSHEALTH = 100
winText = ""
RESTART = pygame.USEREVENT + 1
LOST = pygame.USEREVENT + 2
def draw_window(playerBullets,rainBullets):
WIN.fill(WHITE)
pygame.draw.rect(WIN,BLACK,FLOOR)
pygame.draw.rect(WIN,BLUE,player)
pygame.draw.rect(WIN,RED,BOSS)
boss_health = FONT.render("BOSS HEALTH: " + str(BOSSHEALTH),1,BLACK)
WIN.blit(boss_health,(450,50))
won = FONT.render(winText,BLACK)
WIN.blit(won,(100,50))
for bullet in playerBullets:
pygame.draw.rect(WIN,bullet)
for b in rainBullets:
pygame.draw.rect(WIN,b)
pygame.display.update()
def movement(p):
keys_helds = pygame.key.get_pressed()
if keys_helds[pygame.K_a] and p.x + SPEED > 0:
p.x -= SPEED
if keys_helds[pygame.K_d] and p.x < 400 + p.width:
p.x += SPEED
def p_bullet_movement(playerBullets,boss,raining,player,rainBullets):
for bullet in playerBullets:
bullet.x += BULLET_SPEED
if boss.colliderect(bullet):
global BOSSHEALTH
BOSSHEALTH-= 10
playerBullets.remove(bullet)
if BOSSHEALTH <= 70:
global winText
winText = "Bullet Rain!"
raining = True
for b in rainBullets:
b.y += 1
if player.colliderect(b):
pygame.event.post(pygame.event.Event(LOST))
rainBullets.remove(b)
if b.y + BULLET_SPEED > HEIGHT:
rainBullets.remove(b)
bullet1 = pygame.Rect(20,40,25)
bullet2 = pygame.Rect(170,25)
bullet3 = pygame.Rect(370,25)
bullet4 = pygame.Rect(570,25)
rainBullets.append(bullet1)
rainBullets.append(bullet2)
rainBullets.append(bullet3)
rainBullets.append(bullet4)
if BOSSHEALTH == 0:
winText = "You Won!"
def main():
playerBullets = []
raining = False
rainBullets = []
clock = pygame.time.Clock()
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and not(raining):
bullet = pygame.Rect(player.x,player.y,25)
playerBullets.append(bullet)
if event.type == LOST:
global winText
wintext = "You Lost!"
draw_window(playerBullets,rainBullets)
movement(player)
p_bullet_movement(playerBullets,BOSS,rainBullets)
clock.tick(FPS)
if __name__ == '__main__':
main()
解决方法
它有一个残像,它不是一颗子弹从它下来就像一直画下来一样。
那是因为您每帧为每个 playerBullets 创建了 4 个新子弹。
我显示了两个文本,如果点击它应该将该文本更改为 You Lost,但这是行不通的。
那是因为您在此处设置了 wintext
,而不是 winText
:
if event.type == LOST:
global winText
wintext = "You Lost!"
即使我输入了三个代码,它也应该在 70 生命值时触发 >+ 70 生命值......
不,您检查 70:
...
if BOSSHEALTH <= 70:
...
它会产生子弹并且它们停留在顶部然后当我尝试射击时它们会下降。
看看你在这里缩进代码的方式:
def p_bullet_movement(playerBullets,boss,raining,player,rainBullets):
for bullet in playerBullets:
bullet.x += BULLET_SPEED
if boss.colliderect(bullet):
global BOSSHEALTH
BOSSHEALTH-= 10
playerBullets.remove(bullet)
if BOSSHEALTH <= 70:
global winText
winText = "Bullet Rain!"
raining = True
for b in rainBullets:
b.y += 1
...
如果 rainBullets
,则为 bullet
中的每个 playerBullets
移动 BOSSHEALTH <= 70
中的每个对象。
因此,如果 BOSSHEALTH <= 70
不为真或 playerBullets
中没有对象,则永远不会到达 for b in rainBullets:
行。
由于在主循环中调用了 p_bullet_movement
,因此您需要添加某种条件来限制添加到列表中的子弹数量。由于现在可以添加的子弹数量是无限的,因此它会继续每帧添加子弹,这就是您在图像后调用的。
一种解决方法是仅在列表为空时添加项目符号。
if not rainBullets:
rainBullets.append(bullet1)
rainBullets.append(bullet2)
rainBullets.append(bullet3)
rainBullets.append(bullet4)