import pygame
import random
import sys
import math
import os

pygame.init()
WIDTH, HEIGHT = 1000, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("骑龙勇士历险记｜飞行版")
clock = pygame.time.Clock()
FPS = 60

# ========== 颜色定义 ==========
SKY_TOP = (40, 80, 160)
SKY_BOTTOM = (130, 190, 255)
WHITE = (255, 255, 255)
RED = (220, 20, 20)
GOLD = (255, 200, 0)
BLACK = (0, 0, 0)
GREEN = (30, 180, 40)
BLUE_DRAGON = (20, 120, 200)
FIRE_COLOR = (255, 100, 0)
SHIELD_COLOR = (80, 180, 255)
HEAL_COLOR = (255, 60, 120)
PURPLE = (160, 50, 220)

# ===== 安全中文字体加载 =====
font_path = None
if os.path.exists(r"C:\Windows\Fonts\simhei.ttf"):
    font_path = r"C:\Windows\Fonts\simhei.ttf"

try:
    if font_path:
        font = pygame.font.Font(font_path, 24)
        big_font = pygame.font.Font(font_path, 48)
    else:
        font = pygame.font.Font(None, 24)
        big_font = pygame.font.Font(None, 48)
except:
    font = pygame.font.Font(None, 24)
    big_font = pygame.font.Font(None, 48)


# ========== 按键数字编码(绕过K_W缺失BUG) ==========
KEY_W = 119
KEY_S = 115
KEY_A = 97
KEY_D = 100
KEY_SPACE = 32
KEY_P = 112

# ========== 游戏全局变量 ==========
game_state = "menu"   # menu,play,pause,gameover,nextlevel
level = 1
score = 0

# 视差背景滚动
bg1_x = 0
bg2_x = WIDTH

# ========== 龙(玩家)类 ==========
class Dragon:
    def __init__(self):
        self.x = 150
        self.y = HEIGHT//2
        self.w = 80
        self.h = 50
        self.speed = 6
        self.hp = 100
        self.max_hp = 100
        self.shield = 0
        self.fire_power = 1      # 火焰数量 1~3
        self.fire_cooldown = 0
        self.wing_frame = 0
        self.wing_timer = 0

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[KEY_W] and self.y>10:
            self.y -= self.speed
        if keys[KEY_S] and self.y<HEIGHT-self.h-10:
            self.y += self.speed
        if keys[KEY_A] and self.x>10:
            self.x -= self.speed
        if keys[KEY_D] and self.x<WIDTH-self.w-10:
            self.x += self.speed

        if self.fire_cooldown>0:
            self.fire_cooldown -=1

        # 翅膀扇动动画
        self.wing_timer +=1
        if self.wing_timer>6:
            self.wing_timer=0
            self.wing_frame = (self.wing_frame+1)%4

    def draw(self):
        # 龙身体
        pygame.draw.ellipse(screen,BLUE_DRAGON,(self.x,self.y,self.w,self.h))
        # 龙头
        pygame.draw.circle(screen,BLUE_DRAGON,(int(self.x+self.w),int(self.y+self.h//2)),22)
        # 翅膀扇动
        wing_y_offset = [-12,-6,6,12][self.wing_frame]
        pygame.draw.polygon(screen,(60,160,220),[
            (self.x+25, self.y+10),
            (self.x+5, self.y-20+wing_y_offset),
            (self.x+35, self.y-10+wing_y_offset)
        ])
        pygame.draw.polygon(screen,(60,160,220),[
            (self.x+25, self.y+self.h-10),
            (self.x+5, self.y+self.h+20+wing_y_offset),
            (self.x+35, self.y+self.h+10+wing_y_offset)
        ])
        # 护盾光环
        if self.shield>0:
            pygame.draw.circle(screen,SHIELD_COLOR,(int(self.x+self.w//2),int(self.y+self.h//2)),55,3)

    def shoot_fire(self):
        if self.fire_cooldown>0:
            return []
        self.fire_cooldown = 18
        fires=[]
        base_y = self.y+self.h//2
        if self.fire_power == 1:
            fires.append(Fire(self.x+self.w, base_y))
        elif self.fire_power ==2:
            fires.append(Fire(self.x+self.w, base_y-12))
            fires.append(Fire(self.x+self.w, base_y+12))
        elif self.fire_power >=3:
            fires.append(Fire(self.x+self.w, base_y-18))
            fires.append(Fire(self.x+self.w, base_y))
            fires.append(Fire(self.x+self.w, base_y+18))
        return fires

# ========== 火焰子弹 ==========
class Fire:
    def __init__(self,x,y):
        self.x = x
        self.y = y
        self.radius = 10
        self.speed = 10
        self.damage = 25

    def update(self):
        self.x += self.speed

    def draw(self):
        pygame.draw.circle(screen,FIRE_COLOR,(int(self.x),int(self.y)),self.radius)

    def offscreen(self):
        return self.x>WIDTH+20

# ========== 敌人基类 ==========
class Enemy:
    def __init__(self,lv):
        self.x = WIDTH+random.randint(20,100)
        self.y = random.randint(30,HEIGHT-80)
        self.w = 50
        self.h = 45
        self.hp = 40 + lv*15
        self.max_hp = self.hp
        self.speed = 2+lv*0.4
        self.is_boss = False

    def update(self):
        self.x -= self.speed

    def draw(self):
        pygame.draw.rect(screen,RED,(self.x,self.y,self.w,self.h))
        hp_w = self.w*(self.hp/self.max_hp)
        pygame.draw.rect(screen,GREEN,(self.x,self.y-8,hp_w,4))

    def offscreen(self):
        return self.x < -60

# ========== BOSS类 ==========
class Boss(Enemy):
    def __init__(self,lv):
        super().__init__(lv)
        self.w = 140
        self.h = 110
        self.hp = 250 + lv*120
        self.max_hp = self.hp
        self.speed = 1.2
        self.is_boss = True
        self.move_timer = 0

    def update(self):
        self.x -= self.speed
        self.move_timer +=1
        self.y += math.sin(self.move_timer*0.04)*2.5
        if self.y<20: self.y=20
        if self.y>HEIGHT-self.h-20: self.y=HEIGHT-self.h-20

    def draw(self):
        pygame.draw.ellipse(screen,PURPLE,(self.x,self.y,self.w,self.h))
        hp_w = self.w*(self.hp/self.max_hp)
        pygame.draw.rect(screen,RED,(self.x,self.y-12,self.w,6))
        pygame.draw.rect(screen,GREEN,(self.x,self.y-12,hp_w,6))

# ========== 道具类 回血 /护盾 /火焰强化 ==========
class Item:
    def __init__(self):
        self.x = WIDTH+30
        self.y = random.randint(40,HEIGHT-60)
        self.radius =16
        self.kind = random.choice(["heal","shield","fireup"])
        self.speed = 2.5

    def update(self):
        self.x -= self.speed

    def draw(self):
        if self.kind == "heal":
            c = HEAL_COLOR
        elif self.kind == "shield":
            c = SHIELD_COLOR
        else:
            c = GOLD
        pygame.draw.circle(screen,c,(int(self.x),int(self.y)),self.radius)

    def offscreen(self):
        return self.x<-30

# ========== 碰撞检测 ==========
def rect_circle_collision(rx,ry,rw,rh,cx,cy,cr):
    closest_x = max(rx, min(cx, rx+rw))
    closest_y = max(ry, min(cy, ry+rh))
    dx = cx - closest_x
    dy = cy - closest_y
    return (dx*dx+dy*dy) < cr*cr

# ========== 实例初始化 ==========
def reset_game():
    global dragon,fire_list,enemy_list,item_list,spawn_timer,boss_spawned
    dragon = Dragon()
    fire_list = []
    enemy_list = []
    item_list = []
    spawn_timer = 0
    boss_spawned = False

reset_game()

# ========== 主循环 ==========
running = True
while running:
    # 背景渐变
    for y in range(HEIGHT):
        ratio = y/HEIGHT
        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),(WIDTH,y))

    # 视差滚动远景
    bg1_x -=1.2
    bg2_x -=1.2
    if bg1_x <= -WIDTH: bg1_x = WIDTH
    if bg2_x <= -WIDTH: bg2_x = WIDTH
    pygame.draw.circle(screen,(220,220,220),(int(bg1_x+100),120),40)
    pygame.draw.circle(screen,(220,220,220),(int(bg2_x+300),220),55)
    pygame.draw.circle(screen,(220,220,220),(int(bg1_x+600),80),35)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            keycode = event.key
            # P键暂停
            if keycode == KEY_P and game_state == "play":
                game_state = "pause"
            elif keycode == KEY_P and game_state == "pause":
                game_state = "play"

            if game_state == "menu":
                if keycode == KEY_SPACE:
                    game_state = "play"
                    level=1
                    score=0
                    reset_game()
            if game_state == "nextlevel":
                if keycode == KEY_SPACE:
                    level +=1
                    reset_game()
                    game_state = "play"

    # ----------------菜单界面----------------
    if game_state == "menu":
        text1 = big_font.render("骑龙勇士历险记",True,WHITE)
        text2 = font.render("WASD移动｜空格喷火｜P暂停",True,WHITE)
        text3 = font.render("按空格键开始游戏",True,GOLD)
        screen.blit(text1,(WIDTH//2-text1.get_width()//2,180))
        screen.blit(text2,(WIDTH//2-text2.get_width()//2,280))
        screen.blit(text3,(WIDTH//2-text3.get_width()//2,350))

    # ----------------暂停界面----------------
    elif game_state == "pause":
        pause_text = big_font.render("游戏暂停",True,WHITE)
        tip_text = font.render("按P键继续游戏",True,WHITE)
        screen.blit(pause_text,(WIDTH//2-pause_text.get_width()//2,220))
        screen.blit(tip_text,(WIDTH//2-tip_text.get_width()//2,300))

    # ----------------下一关过渡----------------
    elif game_state == "nextlevel":
        lv_text = big_font.render(f"第 {level+1} 关即将开启!",True,GOLD)
        tip = font.render("空格键进入下一关(敌人更强!)",True,WHITE)
        screen.blit(lv_text,(WIDTH//2-lv_text.get_width()//2,220))
        screen.blit(tip,(WIDTH//2-tip.get_width()//2,300))

    # ----------------游戏运行----------------
    elif game_state == "play":
        dragon.update()
        # 开火
        keys = pygame.key.get_pressed()
        if keys[KEY_SPACE]:
            new_fires = dragon.shoot_fire()
            fire_list.extend(new_fires)

        # 生成敌人
        spawn_timer +=1
        if not boss_spawned:
            if spawn_timer > max(70-level*5,25):
                spawn_timer = 0
                # 每12个普通敌人刷BOSS
                if random.randint(1,12)==1:
                    enemy_list.append(Boss(level))
                else:
                    enemy_list.append(Enemy(level))

        # 生成道具
        if random.randint(1,220)==1:
            item_list.append(Item())

        # 更新火焰
        for f in fire_list[:]:
            f.update()
            if f.offscreen():
                fire_list.remove(f)

        # 更新敌人
        for e in enemy_list[:]:
            e.update()
            if e.offscreen():
                enemy_list.remove(e)
            # 火焰击中敌人
            for f in fire_list[:]:
                if rect_circle_collision(e.x,e.y,e.w,e.h,f.x,f.y,f.radius):
                    e.hp -= f.damage
                    fire_list.remove(f)
                    if e.hp <= 0:
                        enemy_list.remove(e)
                        score += 100 if e.is_boss else 20
                        if e.is_boss:
                            boss_spawned = True
                            game_state = "nextlevel"
                    break
            # 敌人撞到龙
            if rect_circle_collision(e.x,e.y,e.w,e.h,dragon.x+dragon.w//2,dragon.y+dragon.h//2,30):
                if dragon.shield>0:
                    dragon.shield=0
                else:
                    dragon.hp -= 1
                if dragon.hp <= 0:
                    game_state = "gameover"

        # 更新道具
        for it in item_list[:]:
            it.update()
            if it.offscreen():
                item_list.remove(it)
            # 拾取道具
            dx = (dragon.x+dragon.w//2)-it.x
            dy = (dragon.y+dragon.h//2)-it.y
            dist = math.hypot(dx,dy)
            if dist < 45:
                item_list.remove(it)
                if it.kind == "heal":
                    dragon.hp = min(dragon.hp+35, dragon.max_hp)
                elif it.kind == "shield":
                    dragon.shield = 1
                elif it.kind == "fireup":
                    dragon.fire_power = min(dragon.fire_power+1, 3)

        # 绘制
        dragon.draw()
        for f in fire_list:
            f.draw()
        for e in enemy_list:
            e.draw()
        for it in item_list:
            it.draw()

        # UI信息
        hp_text = font.render(f"生命:{dragon.hp}/{dragon.max_hp}",True,WHITE)
        sc_text = font.render(f"分数:{score}",True,WHITE)
        lv_text = font.render(f"关卡:{level}",True,WHITE)
        pow_text = font.render(f"火焰等级:{dragon.fire_power}",True,GOLD)
        shield_text = font.render("护盾激活!" if dragon.shield>0 else "",True,SHIELD_COLOR)
        screen.blit(hp_text,(10,10))
        screen.blit(sc_text,(10,35))
        screen.blit(lv_text,(10,60))
        screen.blit(pow_text,(10,85))
        screen.blit(shield_text,(10,110))

    # ----------------游戏结束----------------
    elif game_state == "gameover":
        over_text = big_font.render("游戏结束!",True,RED)
        final_score = font.render(f"最终分数:{score}",True,WHITE)
        restart = font.render("关闭窗口重新运行",True,WHITE)
        screen.blit(over_text,(WIDTH//2-over_text.get_width()//2,200))
        screen.blit(final_score,(WIDTH//2-final_score.get_width()//2,280))
        screen.blit(restart,(WIDTH//2-restart.get_width()//2,340))

    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
sys.exit()
