|
|
self.max_lifetime = 2000 # 子弹存在的最长时间(毫秒)
def update(self):
# 移动子弹
self.x += math.cos(self.angle) * self.speed
self.y += math.sin(self.angle) * self.speed
# 检查子弹是否超出屏幕或过期
current_time = pygame.time.get_ticks()
if (self.x < -50 or self.x > SCREEN_WIDTH + 50 or
self.y < -50 or self.y > SCREEN_HEIGHT + 50 or
current_time - self.creation_time > self.max_lifetime):
return False
return True
def draw(self, surface):
color = (255, 150, 0) if self.enemy_bullet else BULLET_COLOR
pygame.draw.circle(surface, color, (int(self.x), int(self.y)), self.radius)
# 绘制子弹轨迹
for i in range(1, 4):
trail_x = self.x - math.cos(self.angle) * i * 3
trail_y = self.y - math.sin(self.angle) * i * 3
pygame.draw.circle(surface, (*color[:3], 150 - i*50), (int(trail_x), int(trail_y)), self.radius - i)
class Particle:
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
self.size = random.randint(2, 6)
self.speed_x = random.uniform(-3, 3)
self.speed_y = random.uniform(-3, 3)
self.lifetime = random.randint(20, 40)
def update(self):
self.x += self.speed_x
self.y += self.speed_y
self.lifetime -= 1
self.size = max(0, self.size - 0.1)
return self.lifetime > 0
def draw(self, surface):
pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), int(self.size))
def draw_hud(surface, player, wave, enemies_left):
# 绘制分数
score_text = font.render(f"分数: {player.score}", True, TEXT_COLOR)
surface.blit(score_text, (10, 10))
# 绘制击杀数
kills_text = font.render(f"击杀: {player.kills}", True, TEXT_COLOR)
surface.blit(kills_text, (10, 50))
# 绘制波数
wave_text = font.render(f"波数: {wave}", True, TEXT_COLOR)
surface.blit(wave_text, (SCREEN_WIDTH - wave_text.get_width() - 10, 10))
# 绘制剩余敌人
enemies_text = font.render(f"敌人: {enemies_left}", True, TEXT_COLOR)
surface.blit(enemies_text, (SCREEN_WIDTH - enemies_text.get_width() - 10, 50))
# 绘制弹药状态
ammo_text = font.render(f"弹药: {player.ammo}/{player.max_ammo}", True, TEXT_COLOR)
surface.blit(ammo_text, (SCREEN_WIDTH // 2 - ammo_text.get_width() // 2, SCREEN_HEIGHT - 40))
# 绘制装弹指示器
if player.reload_time > 0:
reload_text = font.render("装弹中...", True, (255, 150, 50))
surface.blit(reload_text, (SCREEN_WIDTH // 2 - reload_text.get_width() // 2, SCREEN_HEIGHT - 80))
def draw_game_over(surface, player):
overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
overlay.fill((0, 0, 0, 180))
surface.blit(overlay, (0, 0))
game_over_text = font.render("游戏结束!", True, (220, 100, 100))
score_text = font.render(f"最终分数: {player.score}", True, TEXT_COLOR)
kills_text = font.render(f"总击杀数: {player.kills}", True, TEXT_COLOR)
restart_text = font.render("按R键重新开始", True, TEXT_COLOR)
surface.blit(game_over_text, (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2, SCREEN_HEIGHT // 2 - 80))
surface.blit(score_text, (SCREEN_WIDTH // 2 - score_text.get_width() // 2, SCREEN_HEIGHT // 2 - 20))
surface.blit(kills_text, (SCREEN_WIDTH // 2 - kills_text.get_width() // 2, SCREEN_HEIGHT // 2 + 40))
surface.blit(restart_text, (SCREEN_WIDTH // 2 - restart_text.get_width() // 2, SCREEN_HEIGHT // 2 + 100))
def main():
player = Player()
bullets = []
enemy_bullets = []
enemies = []
particles = []
game_over = False
wave = 1
enemies_per_wave = 5
spawn_timer = 0
spawn_delay = 1000 # 1秒
# 生成第一波敌人
for _ in range(enemies_per_wave):
enemies.append(Enemy())
while True:
# 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if not game_over:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # 左键射击
bullet = player.shoot(pygame.mouse.get_pos())
if bullet:
bullets.append(bullet)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r: # 装弹
player.reload()
# 玩家控制
keys = pygame.key.get_pressed()
dx, dy = 0, 0
if keys[pygame.K_a] or keys[pygame.K_LEFT]:
dx -= 1
if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
dx += 1
if keys[pygame.K_w] or keys[pygame.K_UP]:
dy -= 1
if keys[pygame.K_s] or keys[pygame.K_DOWN]:
dy += 1
# 更新玩家
if not game_over:
player.move(dx, dy)
player.update()
# 生成敌人
spawn_timer += clock.get_time()
if spawn_timer >= spawn_delay and len(enemies) < enemies_per_wave:
spawn_timer = 0
enemies.append(Enemy())
# 更新敌人
for enemy in enemies[:]:
# 更新敌人并获取其发射的子弹
enemy_bullet = enemy.update(player)
if enemy_bullet:
enemy_bullets.append(enemy_bullet)
# 检查玩家子弹与敌人的碰撞
for bullet in bullets[:]:
distance = math.sqrt((bullet.x - enemy.x)**2 + (bullet.y - enemy.y)**2)
if distance < enemy.radius + bullet.radius:
enemy.health -= 10
enemy_hit_sound.play()
# 创建粒子效果
for _ in range(10):
particles.append(Particle(enemy.x, enemy.y, ENEMY_COLOR))
bullets.remove(bullet)
if enemy.health <= 0:
enemies.remove(enemy)
player.score += 100
player.kills += 1
# 创建更多粒子效果
for _ in range(20):
particles.append(Particle(enemy.x, enemy.y, ENEMY_COLOR))
break
# 更新玩家子弹
for bullet in bullets[:]:
if not bullet.update():
bullets.remove(bullet)
# 更新敌人子弹
for bullet in enemy_bullets[:]:
if not bullet.update():
enemy_bullets.remove(bullet)
# 检查敌人子弹与玩家的碰撞
distance = math.sqrt((bullet.x - player.x)**2 + (bullet.y - player.y)**2)
if distance < player.radius + bullet.radius:
player.health -= 10
enemy_bullets.remove(bullet)
# 创建粒子效果
for _ in range(10):
particles.append(Particle(player.x, player.y, PLAYER_COLOR))
if player.health <= 0:
game_over = True
# 更新粒子
for particle in particles[:]:
if not particle.update():
particles.remove(particle)
# 检查波数完成
if len(enemies) == 0 and spawn_timer > spawn_delay:
wave += 1
enemies_per_wave = 5 + wave * 2
spawn_timer = 0
# 生成新一波敌人
for _ in range(enemies_per_wave):
enemies.append(Enemy())
# 恢复玩家生命值
player.health = min(player.max_health, player.health + 20)
# 重新开始游戏
if game_over and keys[pygame.K_r]:
player = Player()
bullets = []
enemy_bullets = []
enemies = []
particles = []
game_over = False
wave = 1
enemies_per_wave = 5
# 生成第一波敌人
for _ in range(enemies_per_wave):
enemies.append(Enemy())
# 绘制
screen.fill(BACKGROUND)
# 绘制背景网格
for x in range(0, SCREEN_WIDTH, 40):
pygame.draw.line(screen, (30, 40, 60), (x, 0), (x, SCREEN_HEIGHT), 1)
for y in range(0, SCREEN_HEIGHT, 40):
pygame.draw.line(screen, (30, 40, 60), (0, y), (SCREEN_WIDTH, y), 1)
# 绘制玩家
player.draw(screen)
# 绘制敌人
for enemy in enemies:
enemy.draw(screen)
# 绘制子弹
for bullet in bullets:
bullet.draw(screen)
# 绘制敌人子弹
for bullet in enemy_bullets:
bullet.draw(screen)
# 绘制粒子
for particle in particles:
particle.draw(screen)
# 绘制HUD
draw_hud(screen, player, wave, len(enemies))
# 绘制游戏结束画面
if game_over:
draw_game_over(screen, player)
pygame.display.flip()
clock.tick(FPS)
if __name__ == "__main__":
main()
|
|