import pygame
import random
import sys

pygame.init()
# 高清16:9窗口，开启硬件加速、双缓冲防撕裂
SCREEN_WIDTH = 960
SCREEN_HEIGHT = 540
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SCALED | pygame.HWSURFACE | pygame.DOUBLEBUF)
pygame.display.set_caption("神庙逃亡")
clock = pygame.time.Clock()
FPS = 60

# ========== 字体初始化（规避SysFont None报错） ==========
try:
    font = pygame.font.SysFont("simhei", 36)
    over_font = pygame.font.SysFont("simhei", 72)
except Exception:
    font = pygame.font.Font(pygame.font.get_default_font(), 36)
    over_font = pygame.font.Font(pygame.font.get_default_font(), 72)

# ========== 沙漠风格配色（沙色跑道） ==========
BLACK = (0, 0, 0)
BROWN = (90, 60, 30)
BROWN_LIGHT = (125, 85, 45)
# 沙土跑道颜色
ROAD_COLOR = (194, 166, 124)    #浅沙黄主路面
ROAD_DARK = (146, 123, 87)       #深沙土阴影层
GRASS = (160,135,95)
GRASS_DARK = (115,95,65)
GOLD = (255, 200, 0)
GOLD_LIGHT = (255, 225, 100)
RED = (230, 30, 30)
RED_DARK = (175, 18, 18)
WHITE = (255, 255, 255)
DARK_GREY = (18, 18, 18)
TRAP_COLOR = (65, 65, 65)
ROOT_COLOR = (62, 38, 18)
BRIDGE_COLOR = (142, 112, 72)
BRIDGE_DARK = (108, 82, 48)
SKY_TOP = (135, 180, 215)
SKY_BOTTOM = (220, 235, 245)

# ========== 车道参数 ==========
lane_x = [240, 480, 720]
lane_width = 130
current_lane = 1
player_base_y = 430

# ========== 游戏全局变量 ==========
speed = 6.0
max_speed = 17
score = 0
gravity = 0.72
jump_vel = -14
player_vy = 0
is_ground = True
slide_timer = 0
slide_duration = 28
anim_frame = 0
anim_timer = 0
state = "run"  # run / jump / slide
coin_list = []
obstacle_list = []
turn_offset = 0
turn_dir = 0
road_slope = 0

obs_types = ["block", "wall", "trap", "root", "bridge"]


def reset_game():
    global current_lane, speed, score, player_vy, is_ground, slide_timer
    global anim_frame, anim_timer, state, coin_list, obstacle_list
    global turn_offset, turn_dir, road_slope, player_base_y
    current_lane = 1
    speed = 6.0
    score = 0
    player_vy = 0
    is_ground = True
    slide_timer = 0
    anim_frame = 0
    anim_timer = 0
    state = "run"
    coin_list.clear()
    obstacle_list.clear()
    turn_offset = 0
    turn_dir = 0
    road_slope = 0
    player_base_y = 430


reset_game()
running = True

while running:
    clock.tick(FPS)
    # 天空垂直渐变
    for y in range(SCREEN_HEIGHT // 3):
        ratio = y / (SCREEN_HEIGHT // 3)
        r = int(SKY_TOP[0] * (1 - ratio) + SKY_BOTTOM[0] * ratio)
        g = int(SKY_TOP[1] * (1 - ratio) + SKY_BOTTOM[1] * ratio)
        b = int(SKY_TOP[2] * (1 - ratio) + SKY_BOTTOM[2] * ratio)
        pygame.draw.line(screen, (r, g, b), (0, y), (SCREEN_WIDTH, y))

    # 下层天空底色
    pygame.draw.rect(screen, SKY_BOTTOM, [0, SCREEN_HEIGHT // 3, SCREEN_WIDTH, SCREEN_HEIGHT])
    # 沙漠土地分层景深（替换草地为荒漠沙土地面）
    pygame.draw.rect(screen, GRASS_DARK, (0, int(SCREEN_HEIGHT * 0.30), SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.draw.rect(screen, GRASS, (0, int(SCREEN_HEIGHT * 0.38), SCREEN_WIDTH, SCREEN_HEIGHT))

    # 事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    keys = pygame.key.get_pressed()

    # 操控
    if state != "jump":
        if keys[pygame.K_LEFT] and current_lane > 0:
            current_lane -= 1
        if keys[pygame.K_RIGHT] and current_lane < 2:
            current_lane += 1
        if keys[pygame.K_UP] and is_ground:
            state = "jump"
            player_vy = jump_vel
            is_ground = False
        if keys[pygame.K_DOWN] and is_ground and state == "run":
            state = "slide"
            slide_timer = slide_duration

    # 弯道系统
    if turn_dir != 0:
        turn_offset += turn_dir * 1.3
        if abs(turn_offset) > 75:
            turn_dir = 0
    if random.randint(1, 360) == 1 and turn_dir == 0:
        turn_dir = random.choice([-1, 1])

    # 坡道加速减速
    if random.randint(1, 420) == 1 and road_slope == 0:
        road_slope = random.choice([-2.6, 2.6])
    if road_slope != 0:
        speed += road_slope * 0.016
        road_slope *= 0.98
        if abs(road_slope) < 0.08:
            road_slope = 0
    speed = min(speed, max_speed)

    # 跳跃重力运算
    if state == "jump":
        player_vy += gravity
        player_base_y += player_vy
        if player_base_y >= 430:
            player_base_y = 430
            state = "run"
            player_vy = 0
            is_ground = True

    # 滑铲倒计时
    if state == "slide":
        slide_timer -= 1
        if slide_timer <= 0:
            state = "run"

    px = lane_x[current_lane] + turn_offset
    py = player_base_y

    # 奔跑腿部动画计时器
    anim_timer += 1
    if anim_timer >= 7:
        anim_timer = 0
        anim_frame = (anim_frame + 1) % 4

    # ========== 绘制沙色跑道、白线边框 ==========
    for lx in lane_x:
        real_x = lx + turn_offset
        pygame.draw.rect(screen, ROAD_COLOR, (real_x - lane_width // 2, 0, lane_width, SCREEN_HEIGHT))
        pygame.draw.rect(screen, ROAD_DARK, (real_x - lane_width // 2 + 5, 0, lane_width - 10, SCREEN_HEIGHT))
        #车道分隔白线
        pygame.draw.rect(screen, WHITE, (real_x - lane_width // 2 - 4, 0, 7, SCREEN_HEIGHT))
        pygame.draw.rect(screen, WHITE, (real_x + lane_width // 2 - 4, 0, 7, SCREEN_HEIGHT))

    # 道路外侧荒漠沙土
    pygame.draw.rect(screen, GRASS_DARK, (0, 0, lane_x[0] - 65 + turn_offset, SCREEN_HEIGHT))
    pygame.draw.rect(screen, GRASS_DARK, (lane_x[-1] + 65 + turn_offset, 0, SCREEN_WIDTH, SCREEN_HEIGHT))

    # 生成金币、障碍物
    if random.randint(1, 70) == 1:
        l = random.randint(0, 2)
        coin_list.append([lane_x[l] + turn_offset, -30])
    if random.randint(1, 110) == 1:
        l = random.randint(0, 2)
        t = random.choice(obs_types)
        obstacle_list.append([lane_x[l] + turn_offset, -35, t])

    # 更新金币
    for c in coin_list[:]:
        c[1] += speed
        if c[1] > SCREEN_HEIGHT:
            coin_list.remove(c)
        if abs(c[0] - px) < 38 and abs(c[1] - py) < 44:
            coin_list.remove(c)
            score += 15

    # 更新障碍物与碰撞检测
    game_over = False
    player_hit_h = 44
    if state == "slide":
        player_hit_h = 21

    for o in obstacle_list[:]:
        ox, oy, otype = o
        o[1] += speed
        if o[1] > SCREEN_HEIGHT:
            obstacle_list.remove(o)
            continue
        hit = False
        if abs(ox - px) < 36 and abs(oy - py) < player_hit_h:
            if otype == "wall" and state == "jump":
                hit = False
            elif otype == "block" and state == "slide":
                hit = False
            elif otype == "trap":
                hit = not (state == "jump")
            elif otype == "root":
                hit = not (state == "slide")
            elif otype == "bridge":
                hit = not (state == "jump")
            else:
                hit = True
        if hit:
            game_over = True

    # ========== 高光金币渲染 ==========
    for (cx, cy) in coin_list:
        pygame.draw.circle(screen, GOLD_LIGHT, (cx, cy), 17)
        pygame.draw.circle(screen, GOLD, (cx, cy), 13)
        pygame.draw.circle(screen, WHITE, (cx - 5, cy - 5), 5)

    # ========== 带明暗阴影的障碍物 ==========
    for o in obstacle_list:
        ox, oy, otype = o
        if otype == "block":
            pygame.draw.rect(screen, BROWN, (ox - 23, oy, 46, 44))
            pygame.draw.rect(screen, BROWN_LIGHT, (ox - 19, oy + 3, 18, 16))
        elif otype == "wall":
            pygame.draw.rect(screen, RED_DARK, (ox - 19, oy - 56, 38, 67))
            pygame.draw.rect(screen, RED, (ox - 15, oy - 52, 30, 58))
        elif otype == "trap":
            pygame.draw.rect(screen, DARK_GREY, (ox - 26, oy, 52, 32))
            pygame.draw.rect(screen, TRAP_COLOR, (ox - 21, oy + 4, 42, 22))
        elif otype == "root":
            pygame.draw.ellipse(screen, ROOT_COLOR, (ox - 32, oy, 64, 30))
        elif otype == "bridge":
            pygame.draw.rect(screen, BRIDGE_DARK, (ox - 37, oy, 26, 47))
            pygame.draw.rect(screen, BRIDGE_COLOR, (ox - 33, oy + 3, 18, 38))

    # ========== 精致动画人物 ==========
    leg_offset = [-13, 0, 13, 0][anim_frame]
    if state == "run":
        pygame.draw.rect(screen, (225, 65, 65), (px - 21, py, 42, 44))
        pygame.draw.rect(screen, (45, 45, 190), (px - 19 + leg_offset, py + 42, 15, 17))
        pygame.draw.rect(screen, (45, 45, 190), (px + 5 - leg_offset, py + 42, 15, 17))
    elif state == "jump":
        pygame.draw.circle(screen, (225, 65, 65), (int(px), int(py)), 24)
    elif state == "slide":
        pygame.draw.rect(screen, (225, 65, 65), (px - 23, py + 23, 46, 21))

    # 速度递增、得分
    speed += 0.0035
    score += 0.06

    # UI文字
    info_text = font.render(f"分数:{int(score)} 奔跑速度:{round(speed,1)}", True, WHITE)
    screen.blit(info_text, (18, 18))

    # 游戏结束界面
    if game_over:
        gameover_text = over_font.render("游戏结束", True, RED)
        screen.blit(gameover_text, (260, 220))
        restart_tip = font.render("按下空格键重新开始", True, WHITE)
        screen.blit(restart_tip, (290, 360))
        if keys[pygame.K_SPACE]:
            reset_game()

    pygame.display.update()

pygame.quit()
sys.exit()