我不明白为什么 enemy/player 射击的弹药在他们死后不会消失 pygame
I cant figure out why the ammo the enemy/player is shooting doesnt dissapear after they die pygame
我正在尝试在我的游戏中进行 bossfight。 Boss 是一只向玩家发射弹丸的黄蜂。玩家在与boss战斗时,每隔一段时间就会获得额外的弹药。
唯一的问题是我不知道如何在bossfight后重置一切并让游戏正常继续。 Boss 弹丸继续掉落,但从与 Boss 死亡的位置不同的位置。
我在 bossfight 中使用了两个不同的 类:Boss
和 Projectile
。我对玩家的射弹和敌人的射弹有不同的类。我会附上游戏的图片。
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()
问题是以下代码块总是将 BossNow
重置为 True,即使在 boss 已经被打败之后也是如此。
if player.score >= 100:
bossNow = True
else:
bossNow = False
所以,你必须添加一些东西来防止这种情况发生。我会为此使用 BossDefeated
变量。
为了实现这一点,您必须进行以下更改:
1:通过在游戏循环之前添加以下行,将 BossDefeated
变量初始化为 False:
BossDefeated=False
2:通过将第一个代码块更改为以下内容,使 BossDefeated
变量生效:
if player.score >= 100 and not BossDefeated:
bossNow = True
else:
bossNow = False
3:在每次调用 WaspBoss.kill
后添加以下行,将打败 Boss 时设置的 BossDefeated
变量设置为 True:
BossNow=True
我们还需要在Boss.update
的函数定义中添加下面这行,以获取BossDefeated
的变化到全局范围内。
global BossDefeated
如您所愿,完整代码如下:
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()
我正在尝试在我的游戏中进行 bossfight。 Boss 是一只向玩家发射弹丸的黄蜂。玩家在与boss战斗时,每隔一段时间就会获得额外的弹药。
唯一的问题是我不知道如何在bossfight后重置一切并让游戏正常继续。 Boss 弹丸继续掉落,但从与 Boss 死亡的位置不同的位置。
我在 bossfight 中使用了两个不同的 类:Boss
和 Projectile
。我对玩家的射弹和敌人的射弹有不同的类。我会附上游戏的图片。
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()
问题是以下代码块总是将 BossNow
重置为 True,即使在 boss 已经被打败之后也是如此。
if player.score >= 100:
bossNow = True
else:
bossNow = False
所以,你必须添加一些东西来防止这种情况发生。我会为此使用 BossDefeated
变量。
为了实现这一点,您必须进行以下更改:
1:通过在游戏循环之前添加以下行,将 BossDefeated
变量初始化为 False:
BossDefeated=False
2:通过将第一个代码块更改为以下内容,使 BossDefeated
变量生效:
if player.score >= 100 and not BossDefeated:
bossNow = True
else:
bossNow = False
3:在每次调用 WaspBoss.kill
后添加以下行,将打败 Boss 时设置的 BossDefeated
变量设置为 True:
BossNow=True
我们还需要在Boss.update
的函数定义中添加下面这行,以获取BossDefeated
的变化到全局范围内。
global BossDefeated
如您所愿,完整代码如下:
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()