import pygame
import random
import sys
# 初始化pygame
pygame.init()
pygame.mixer.init() # 音频初始化(增强氛围)
# 游戏常量
WIDTH, HEIGHT = 1000, 600
PLAYER_SIZE = 30
MONSTER_SIZE = 40
LIGHT_SIZE = 20
FPS = 60 # 游戏流畅度
# 颜色定义(贴合黑暗主题)
DARK_GRAY = (20, 20, 25) # 背景色
PALE_BLUE = (120, 180, 255) # 角色色(微弱发光感)
BLOOD_RED = (180, 30, 40) # 怪物色
GOLD_YELLOW = (255, 220, 80)# 光源色
# 窗口与时钟设置
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("黑暗幻灭")
clock = pygame.time.Clock()
# 加载音效(增强沉浸感,可自行替换路径)
try:
collect_sound = pygame.mixer.Sound("collect.wav") # 收集光源音效
game_over_sound = pygame.mixer.Sound("game_over.wav")# 游戏结束音效
except:
collect_sound = None # 无音效文件时跳过
game_over_sound = None
def draw_light(surface, center, radius):
"""绘制光源渐变效果(核心氛围功能)"""
# 创建透明表面绘制光源
light_surface = pygame.Surface((radius*2, radius*2), pygame.SRCALPHA)
# 绘制多层渐变光圈
for r in range(radius, 0, -5):
alpha = int(255 * (r / radius)) # 外层光圈透明度更低
pygame.draw.circle(light_surface, (*GOLD_YELLOW, alpha), (radius, radius), r)
# 将光源贴到游戏窗口
surface.blit(light_surface, (center[0]-radius, center[1]-radius))
class Player:
"""玩家类(操控核心)"""
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT // 2
self.speed = 5
self.light_radius = 80 # 玩家自身携带的光源范围
self.score = 0
def draw(self, surface):
# 绘制玩家本体
pygame.draw.circle(surface, PALE_BLUE, (self.x, self.y), PLAYER_SIZE)
# 绘制玩家的光源
draw_light(surface, (self.x, self.y), self.light_radius)
def move(self, keys):
# 键盘控制移动(WSAD或方向键)
if (keys[pygame.K_w] or keys[pygame.K_UP]) and self.y > PLAYER_SIZE:
self.y -= self.speed
if (keys[pygame.K_s] or keys[pygame.K_DOWN]) and self.y < HEIGHT - PLAYER_SIZE:
self.y += self.speed
if (keys[pygame.K_a] or keys[pygame.K_LEFT]) and self.x > PLAYER_SIZE:
self.x -= self.speed
if (keys[pygame.K_d] or keys[pygame.K_RIGHT]) and self.x < WIDTH - PLAYER_SIZE:
self.x += self.speed
class Monster:
"""怪物类(障碍核心)"""
def __init__(self):
# 随机生成在屏幕边缘(避免初始就靠近玩家)
if random.choice([True, False]):
self.x = random.choice([-MONSTER_SIZE, WIDTH + MONSTER_SIZE])
self.y = random.randint(0, HEIGHT)
else:
self.x = random.randint(0, WIDTH)
self.y = random.choice([-MONSTER_SIZE, HEIGHT + MONSTER_SIZE])
self.speed = random.uniform(1.5, 3) # 怪物速度随机(增加难度)
def draw(self, surface):
pygame.draw.circle(surface, BLOOD_RED, (int(self.x), int(self.y)), MONSTER_SIZE)
def chase(self, player):
"""怪物追踪玩家逻辑"""
if self.x < player.x:
self.x += self.speed
else:
self.x -= self.speed
if self.y < player.y:
self.y += self.speed
else:
self.y -= self.speed
class LightSource:
"""光源道具类(收集目标)"""
def __init__(self):
self.x = random.randint(LIGHT_SIZE, WIDTH - LIGHT_SIZE)
self.y = random.randint(LIGHT_SIZE, HEIGHT - LIGHT_SIZE)
self.radius = 50 # 光源自身发光范围
def draw(self, surface):
# 绘制光源本体
pygame.draw.circle(surface, GOLD_YELLOW, (self.x, self.y), LIGHT_SIZE)
# 绘制光源的发光效果
draw_light(surface, (self.x, self.y), self.radius)
def show_game_over(score):
"""显示游戏结束界面"""
if game_over_sound:
game_over_sound.play()
font_large = pygame.font.SysFont("Arial", 60, bold=True)
font_small = pygame.font.SysFont("Arial", 30)
over_text = font_large.render("黑暗吞噬了你", True, BLOOD_RED)
score_text = font_small.render(f"最终光源数:{score}", True, PALE_BLUE)
restart_text = font_small.render("按 R 重新开始 / 按 Q 退出", True, PALE_BLUE)
# 绘制半透明黑底(突出文字)
pygame.draw.rect(screen, (*DARK_GRAY, 200), (WIDTH//4, HEIGHT//3, WIDTH//2, HEIGHT//3))
screen.blit(over_text, (WIDTH//4 + 20, HEIGHT//3 + 20))
screen.blit(score_text, (WIDTH//4 + 50, HEIGHT//2 - 30))
screen.blit(restart_text, (WIDTH//4 + 30, HEIGHT//2 + 20))
pygame.display.update()
# 等待玩家操作
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
main() # 重新开始
if event.key == pygame.K_q:
pygame.quit()
sys.exit()
def main():
"""游戏主逻辑"""
player = Player()
monsters = [Monster() for _ in range(3)] # 初始3只怪物
lights = [LightSource() for _ in range(5)] # 初始5个光源
spawn_timer = 0 # 怪物生成计时器(难度递增)
while True:
# 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 玩家移动
keys = pygame.key.get_pressed()
player.move(keys)
# 怪物追踪与生成(每10秒增加1只怪物)
spawn_timer += 1
if spawn_timer >= FPS * 10:
monsters.append(Monster())
spawn_timer = 0
for monster in monsters:
monster.chase(player)
# 碰撞判定:玩家与光源(收集逻辑)
new_lights = []
for light in lights:
distance = ((player.x - light.x)**2 + (player.y - light.y)**2)**0.5
if distance < PLAYER_SIZE + LIGHT_SIZE:
# 收集成功
player.score += 1
player.light_radius = min(150, player.light_radius + 5) # 光源范围增大(奖励)
if collect_sound:
collect_sound.play()
new_lights.append(LightSource()) # 生成新光源
else:
new_lights.append(light)
lights = new_lights
# 碰撞判定:玩家与怪物(死亡逻辑)
for monster in monsters:
distance = ((player.x - monster.x)**2 + (player.y - monster.y)**2)**0.5
if distance < PLAYER_SIZE + MONSTER_SIZE:
show_game_over(player.score)
# 绘制游戏界面(按层级绘制:背景→光源→怪物→玩家)
screen.fill(DARK_GRAY)
# 先绘制所有光源(确保光源在最底层,营造环境光)
for light in lights:
light.draw(screen)
# 绘制怪物
for monster in monsters:
monster.draw(screen)
# 绘制玩家(玩家在最上层,确保可见)
player.draw(screen)
# 绘制得分
font = pygame.font.SysFont("Arial", 25)
score_text = font.render(f"光源数:{player.score}", True, GOLD_YELLOW)
screen.blit(score_text, (20, 20))
# 更新屏幕与控制帧率
pygame.display.update()
clock.tick(FPS)
# 启动游戏
if __name__ == "__main__":
main()