一、前言
一个一点人工都没有,全靠Deepseek生成的游戏是什么样子的呢?
答:
二、游戏介绍
1. 游戏核心机制
玩家控制:WASD移动,鼠标瞄准射击
怪物系统:
黄色怪物:3点生命,速度慢,受伤会缩小
蓝色怪物:1点生命,速度快
红色怪物:2点生命,速度中等
死亡效果:怪物死亡时产生对应颜色的爆炸碎片
2. 道具系统
四种道具箱从天而降:
三连发(蓝色)
扇形散射(紫色)
射速加快(青色)
子弹变大(橙色)
击中道具箱获得对应能力,持续10秒
3. 视觉效果
怪物血量条显示
粒子爆炸效果
击中道具箱的闪烁效果
网格背景和游戏UI
4. 游戏进度
波数系统:每消灭10个怪物进入下一波
难度递增:怪物生成速度加快
计分系统:不同怪物不同分数
5.操作说明:
WASD:移动玩家
鼠标左键:射击
ESC:退出游戏
R:重新开始游戏
三、完整代码
import pygame import sys import math import random from pygame.locals import * # 初始化pygame和字体 pygame.init() # 设置中文字体 try: # 尝试使用系统字体 font = pygame.font.Font("C:/Windows/Fonts/simhei.ttf", 24) # 黑体 small_font = pygame.font.Font("C:/Windows/Fonts/simhei.ttf", 18) except: # 如果找不到,使用默认字体并打印提示 print("警告: 找不到中文字体,请确保文件路径正确") font = pygame.font.SysFont(None, 24) small_font = pygame.font.SysFont(None, 18) # 游戏窗口设置 SCREEN_WIDTH = 1000 SCREEN_HEIGHT = 700 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("怪物防御战") clock = pygame.time.Clock() # 颜色定义 WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 50, 50) GREEN = (50, 255, 50) BLUE = (50, 100, 255) YELLOW = (255, 255, 50) PURPLE = (200, 50, 200) CYAN = (0, 200, 200) ORANGE = (255, 150, 0) GRAY = (150, 150, 150) class Player: def __init__(self): self.x = SCREEN_WIDTH // 2 self.y = SCREEN_HEIGHT // 2 self.radius = 20 self.color = GREEN self.speed = 5 self.shoot_cooldown = 0 self.base_shoot_delay = 15 self.shoot_delay = self.base_shoot_delay self.bullet_speed = 8 self.bullet_size = 5 self.bullet_color = WHITE self.shoot_mode = "single" # single, triple, spread self.powerup_timer = 0 self.score = 0 self.lives = 3 def update(self): # 玩家移动 keys = pygame.key.get_pressed() if keys[K_w] and self.y > self.radius: self.y -= self.speed if keys[K_s] and self.y < SCREEN_HEIGHT - self.radius: self.y += self.speed if keys[K_a] and self.x > self.radius: self.x -= self.speed if keys[K_d] and self.x < SCREEN_WIDTH - self.radius: self.x += self.speed # 更新射击冷却 if self.shoot_cooldown > 0: self.shoot_cooldown -= 1 # 更新道具效果时间 if self.powerup_timer > 0: self.powerup_timer -= 1 if self.powerup_timer == 0: self.reset_powerup() def shoot(self, bullet_manager): if self.shoot_cooldown > 0: return mouse_x, mouse_y = pygame.mouse.get_pos() dx = mouse_x - self.x dy = mouse_y - self.y distance = max(0.1, math.sqrt(dx * dx + dy * dy)) base_angle = math.atan2(dy, dx) if self.shoot_mode == "single": bullet_manager.add_bullet(self.x, self.y, base_angle, self.bullet_speed, self.bullet_size, self.bullet_color) elif self.shoot_mode == "triple": for i in range(3): angle = base_angle - 0.2 + (i * 0.2) bullet_manager.add_bullet(self.x, self.y, angle, self.bullet_speed, self.bullet_size, self.bullet_color) elif self.shoot_mode == "spread": for i in range(5): angle = base_angle - 0.4 + (i * 0.2) bullet_manager.add_bullet(self.x, self.y, angle, self.bullet_speed, self.bullet_size, self.bullet_color) self.shoot_cooldown = self.shoot_delay def apply_powerup(self, powerup_type): if powerup_type == "triple": self.shoot_mode = "triple" self.powerup_timer = 600 # 10秒 elif powerup_type == "spread": self.shoot_mode = "spread" self.powerup_timer = 600 elif powerup_type == "fast_shoot": self.shoot_delay = self.base_shoot_delay // 2 self.powerup_timer = 600 elif powerup_type == "big_bullet": self.bullet_size = 10 self.powerup_timer = 600 def reset_powerup(self): self.shoot_mode = "single" self.shoot_delay = self.base_shoot_delay self.bullet_size = 5 def draw(self, surface): # 绘制玩家 pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius) pygame.draw.circle(surface, WHITE, (int(self.x), int(self.y)), self.radius, 2) # 绘制玩家朝向指示器 mouse_x, mouse_y = pygame.mouse.get_pos() angle = math.atan2(mouse_y - self.y, mouse_x - self.x) end_x = self.x + math.cos(angle) * (self.radius + 10) end_y = self.y + math.sin(angle) * (self.radius + 10) pygame.draw.line(surface, RED, (self.x, self.y), (end_x, end_y), 3) class Bullet: def __init__(self, x, y, angle, speed, size, color): self.x = x self.y = y self.angle = angle self.speed = speed self.size = size self.color = color self.radius = size self.rect = pygame.Rect(x - size, y - size, size * 2, size * 2) def update(self): self.x += math.cos(self.angle) * self.speed self.y += math.sin(self.angle) * self.speed self.rect.center = (int(self.x), int(self.y)) def draw(self, surface): pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius) def is_out_of_screen(self): return (self.x < -self.radius or self.x > SCREEN_WIDTH + self.radius or self.y < -self.radius or self.y > SCREEN_HEIGHT + self.radius) class BulletManager: def __init__(self): self.bullets = [] def add_bullet(self, x, y, angle, speed, size, color): bullet = Bullet(x, y, angle, speed, size, color) self.bullets.append(bullet) def update(self): # 更新所有子弹并移除超出屏幕的 bullets_to_remove = [] for bullet in self.bullets: bullet.update() if bullet.is_out_of_screen(): bullets_to_remove.append(bullet) for bullet in bullets_to_remove: self.bullets.remove(bullet) def draw(self, surface): for bullet in self.bullets: bullet.draw(surface) def clear(self): self.bullets.clear() class Monster: def __init__(self, monster_type): self.type = monster_type # "yellow", "blue", "red" # 根据类型设置属性 if monster_type == "yellow": # 血量厚,移速慢 self.color = YELLOW self.max_health = 3 self.health = 3 self.speed = 1.0 self.radius = 30 self.score_value = 50 elif monster_type == "blue": # 速度快,血量少 self.color = BLUE self.max_health = 1 self.health = 1 self.speed = 3.5 self.radius = 20 self.score_value = 20 else: # "red" 综合属性 self.color = RED self.max_health = 2 self.health = 2 self.speed = 2.0 self.radius = 25 self.score_value = 30 # 随机在屏幕边缘生成 side = random.randint(0, 3) if side == 0: # 上边 self.x = random.randint(0, SCREEN_WIDTH) self.y = -self.radius elif side == 1: # 右边 self.x = SCREEN_WIDTH + self.radius self.y = random.randint(0, SCREEN_HEIGHT) elif side == 2: # 下边 self.x = random.randint(0, SCREEN_WIDTH) self.y = SCREEN_HEIGHT + self.radius else: # 左边 self.x = -self.radius self.y = random.randint(0, SCREEN_HEIGHT) self.rect = pygame.Rect(self.x - self.radius, self.y - self.radius, self.radius * 2, self.radius * 2) self.particles = [] def update(self, player_x, player_y): # 计算朝向玩家的方向 dx = player_x - self.x dy = player_y - self.y distance = max(0.1, math.sqrt(dx * dx + dy * dy)) # 归一化并移动 self.x += (dx / distance) * self.speed self.y += (dy / distance) * self.speed self.rect.center = (int(self.x), int(self.y)) def take_damage(self): self.health -= 1 if self.type == "yellow" and self.health > 0: # 黄色怪物受伤时缩小 self.radius = max(10, int(self.radius * 0.7)) self.rect = pygame.Rect(self.x - self.radius, self.y - self.radius, self.radius * 2, self.radius * 2) return self.health <= 0 def create_death_particles(self): particles = [] num_particles = 15 if self.type == "yellow" else 10 for _ in range(num_particles): angle = random.uniform(0, math.pi * 2) speed = random.uniform(2, 5) size = random.randint(3, 8) life = random.randint(30, 60) particle = { 'x': self.x, 'y': self.y, 'vx': math.cos(angle) * speed, 'vy': math.sin(angle) * speed, 'size': size, 'color': self.color, 'life': life, 'max_life': life } particles.append(particle) return particles def draw(self, surface): # 绘制怪物 pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius) # 绘制血量条(如果血量大于1) if self.max_health > 1: bar_width = self.radius * 1.5 bar_height = 5 bar_x = self.x - bar_width // 2 bar_y = self.y - self.radius - 10 # 背景条 pygame.draw.rect(surface, GRAY, (bar_x, bar_y, bar_width, bar_height)) # 血量条 health_width = int((self.health / self.max_health) * bar_width) health_color = GREEN if self.health > self.max_health * 0.5 else ORANGE if self.health > self.max_health * 0.25 else RED pygame.draw.rect(surface, health_color, (bar_x, bar_y, health_width, bar_height)) class PowerupBox: def __init__(self): self.x = random.randint(50, SCREEN_WIDTH - 50) self.y = -30 self.width = 40 self.height = 40 self.speed = 2 self.types = ["triple", "spread", "fast_shoot", "big_bullet"] self.type = random.choice(self.types) self.colors = { "triple": BLUE, "spread": PURPLE, "fast_shoot": CYAN, "big_bullet": ORANGE } self.color = self.colors[self.type] self.rect = pygame.Rect(self.x, self.y, self.width, self.height) self.hit_effect = 0 def update(self): self.y += self.speed self.rect.y = self.y if self.hit_effect > 0: self.hit_effect -= 1 return self.y > SCREEN_HEIGHT def hit(self): self.hit_effect = 10 # 闪烁10帧 def draw(self, surface): # 绘制物品箱 pygame.draw.rect(surface, self.color, self.rect, border_radius=8) pygame.draw.rect(surface, WHITE, self.rect, 3, border_radius=8) # 绘制类型图标 if self.type == "triple": # 三个点 for i in range(3): pygame.draw.circle(surface, WHITE, (int(self.x + self.width // 2 - 8 + i * 8), int(self.y + self.height // 2)), 4) elif self.type == "spread": # 扇形 center_x = self.x + self.width // 2 center_y = self.y + self.height // 2 pygame.draw.circle(surface, WHITE, (center_x, center_y), 8, 2) for angle in [-30, 0, 30]: rad = math.radians(angle) end_x = center_x + math.cos(rad) * 12 end_y = center_y + math.sin(rad) * 12 pygame.draw.line(surface, WHITE, (center_x, center_y), (end_x, end_y), 2) elif self.type == "fast_shoot": # 闪电符号 points = [ (self.x + self.width // 2, self.y + 10), (self.x + self.width // 2 - 5, self.y + self.height // 2), (self.x + self.width // 2 + 5, self.y + self.height // 2), (self.x + self.width // 2, self.y + self.height - 10) ] pygame.draw.lines(surface, WHITE, False, points, 3) elif self.type == "big_bullet": # 大子弹 center_x = self.x + self.width // 2 center_y = self.y + self.height // 2 pygame.draw.circle(surface, WHITE, (center_x, center_y), 10) # 击中特效 if self.hit_effect > 0: pygame.draw.rect(surface, WHITE, self.rect, 5, border_radius=8) class ParticleSystem: def __init__(self): self.particles = [] def add_particles(self, particles): self.particles.extend(particles) def update(self): particles_to_remove = [] for particle in self.particles: particle['x'] += particle['vx'] particle['y'] += particle['vy'] particle['vy'] += 0.1 # 重力效果 particle['life'] -= 1 # 根据生命值调整大小 if particle['life'] > 0: particle['size'] = max(1, particle['size'] * (particle['life'] / particle['max_life'])) else: particles_to_remove.append(particle) for particle in particles_to_remove: self.particles.remove(particle) def draw(self, surface): for particle in self.particles: alpha = int(255 * (particle['life'] / particle['max_life'])) color_with_alpha = (*particle['color'], alpha) # 创建一个临时surface来绘制带透明度的粒子 particle_surface = pygame.Surface((particle['size'] * 2, particle['size'] * 2), pygame.SRCALPHA) pygame.draw.circle(particle_surface, color_with_alpha, (particle['size'], particle['size']), particle['size']) surface.blit(particle_surface, (int(particle['x'] - particle['size']), int(particle['y'] - particle['size']))) class Game: def __init__(self): self.player = Player() self.bullet_manager = BulletManager() self.monsters = [] self.powerups = [] self.particle_system = ParticleSystem() self.monster_spawn_timer = 0 self.powerup_spawn_timer = 0 self.game_over = False self.wave = 1 self.monsters_killed = 0 self.monster_spawn_delay = 90 # 初始怪物生成间隔 self.powerup_spawn_delay = 600 # 道具生成间隔 def handle_events(self): for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == KEYDOWN: if event.key == K_ESCAPE: pygame.quit() sys.exit() elif event.key == K_r and self.game_over: self.__init__() # 重新开始游戏 elif event.type == MOUSEBUTTONDOWN: if event.button == 1: # 左键 self.player.shoot(self.bullet_manager) def update(self): if self.game_over: return # 更新玩家 self.player.update() # 自动射击(按住鼠标) if pygame.mouse.get_pressed()[0]: self.player.shoot(self.bullet_manager) # 更新子弹 self.bullet_manager.update() # 生成怪物 self.monster_spawn_timer += 1 if self.monster_spawn_timer >= self.monster_spawn_delay: monster_type = random.choice(["yellow", "blue", "red"]) monster = Monster(monster_type) self.monsters.append(monster) self.monster_spawn_timer = 0 # 随着波数增加,生成速度加快 self.monster_spawn_delay = max(30, 90 - self.wave * 5) # 生成道具 self.powerup_spawn_timer += 1 if self.powerup_spawn_timer >= self.powerup_spawn_delay: powerup = PowerupBox() self.powerups.append(powerup) self.powerup_spawn_timer = 0 # 更新怪物 monsters_to_remove = [] for monster in self.monsters: monster.update(self.player.x, self.player.y) # 检查怪物是否碰到玩家 dx = monster.x - self.player.x dy = monster.y - self.player.y distance = math.sqrt(dx * dx + dy * dy) if distance < monster.radius + self.player.radius: self.player.lives -= 1 monsters_to_remove.append(monster) self.particle_system.add_particles(monster.create_death_particles()) if self.player.lives <= 0: self.game_over = True # 更新道具 powerups_to_remove = [] for powerup in self.powerups: if powerup.update(): # 如果超出屏幕 powerups_to_remove.append(powerup) # 检测子弹和怪物碰撞 for bullet in self.bullet_manager.bullets[:]: bullet_rect = bullet.rect for monster in self.monsters[:]: if bullet_rect.colliderect(monster.rect): if monster.take_damage(): # 怪物死亡 self.player.score += monster.score_value self.monsters_killed += 1 monsters_to_remove.append(monster) # 添加死亡粒子效果 self.particle_system.add_particles(monster.create_death_particles()) # 移除子弹 if bullet in self.bullet_manager.bullets: self.bullet_manager.bullets.remove(bullet) break # 检测子弹和道具碰撞 for bullet in self.bullet_manager.bullets[:]: for powerup in self.powerups[:]: if bullet.rect.colliderect(powerup.rect): powerup.hit() self.player.apply_powerup(powerup.type) powerups_to_remove.append(powerup) # 移除子弹 if bullet in self.bullet_manager.bullets: self.bullet_manager.bullets.remove(bullet) break # 移除已处理的怪物和道具 for monster in monsters_to_remove: if monster in self.monsters: self.monsters.remove(monster) for powerup in powerups_to_remove: if powerup in self.powerups: self.powerups.remove(powerup) # 更新粒子系统 self.particle_system.update() # 更新波数 if self.monsters_killed >= 10 * self.wave: self.wave += 1 self.monsters_killed = 0 def draw(self): screen.fill((20, 20, 40)) # 深蓝色背景 # 绘制网格背景 for x in range(0, SCREEN_WIDTH, 50): pygame.draw.line(screen, (30, 30, 50), (x, 0), (x, SCREEN_HEIGHT), 1) for y in range(0, SCREEN_HEIGHT, 50): pygame.draw.line(screen, (30, 30, 50), (0, y), (SCREEN_WIDTH, y), 1) # 绘制粒子 self.particle_system.draw(screen) # 绘制道具 for powerup in self.powerups: powerup.draw(screen) # 绘制怪物 for monster in self.monsters: monster.draw(screen) # 绘制子弹 self.bullet_manager.draw(screen) # 绘制玩家 self.player.draw(screen) # 绘制UI self.draw_ui() # 游戏结束画面 if self.game_over: self.draw_game_over() pygame.display.flip() def draw_ui(self): # 分数 score_text = font.render(f"分数: {self.player.score}", True, WHITE) screen.blit(score_text, (10, 10)) # 生命值 lives_text = font.render(f"生命: {self.player.lives}", True, WHITE) screen.blit(lives_text, (10, 40)) # 波数 wave_text = font.render(f"波数: {self.wave}", True, WHITE) screen.blit(wave_text, (10, 70)) # 当前能力 mode_text = small_font.render(f"射击模式: {self.player.shoot_mode}", True, WHITE) screen.blit(mode_text, (10, 100)) # 道具剩余时间 if self.player.powerup_timer > 0: timer_text = small_font.render(f"能力剩余: {self.player.powerup_timer // 60}秒", True, YELLOW) screen.blit(timer_text, (10, 130)) # 怪物数量 monster_count_text = small_font.render(f"怪物数量: {len(self.monsters)}", True, WHITE) screen.blit(monster_count_text, (10, 160)) # 帮助文本 help_text = small_font.render("WASD移动, 鼠标瞄准射击, ESC退出, R重新开始", True, GRAY) screen.blit(help_text, (SCREEN_WIDTH // 2 - help_text.get_width() // 2, SCREEN_HEIGHT - 30)) # 绘制怪物图例 legend_y = SCREEN_HEIGHT - 150 pygame.draw.rect(screen, YELLOW, (SCREEN_WIDTH - 200, legend_y, 15, 15)) yellow_text = small_font.render("黄色: 血厚(3枪), 移速慢", True, WHITE) screen.blit(yellow_text, (SCREEN_WIDTH - 180, legend_y - 3)) pygame.draw.rect(screen, BLUE, (SCREEN_WIDTH - 200, legend_y + 30, 15, 15)) blue_text = small_font.render("蓝色: 血少(1枪), 移速快", True, WHITE) screen.blit(blue_text, (SCREEN_WIDTH - 180, legend_y + 27)) pygame.draw.rect(screen, RED, (SCREEN_WIDTH - 200, legend_y + 60, 15, 15)) red_text = small_font.render("红色: 中等(2枪), 移速中等", True, WHITE) screen.blit(red_text, (SCREEN_WIDTH - 180, legend_y + 57)) def draw_game_over(self): # 半透明覆盖层 overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA) overlay.fill((0, 0, 0, 180)) screen.blit(overlay, (0, 0)) # 游戏结束文本 game_over_text = font.render("游戏结束!", True, RED) screen.blit(game_over_text, (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2, SCREEN_HEIGHT // 2 - 50)) final_score_text = font.render(f"最终分数: {self.player.score}", True, WHITE) screen.blit(final_score_text, (SCREEN_WIDTH // 2 - final_score_text.get_width() // 2, SCREEN_HEIGHT // 2)) final_wave_text = font.render(f"到达波数: {self.wave}", True, WHITE) screen.blit(final_wave_text, (SCREEN_WIDTH // 2 - final_wave_text.get_width() // 2, SCREEN_HEIGHT // 2 + 40)) restart_text = font.render("按 R 键重新开始", True, GREEN) screen.blit(restart_text, (SCREEN_WIDTH // 2 - restart_text.get_width() // 2, SCREEN_HEIGHT // 2 + 90)) def main(): game = Game() while True: game.handle_events() game.update() game.draw() clock.tick(60) if __name__ == "__main__": main()