一、前言
一个一点人工都没有,全靠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()
1086

被折叠的 条评论
为什么被折叠?



