import pygame
import random                                                            

# 初始化
pygame.init()
W, H = 800, 600
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("图形RPG冒险")
clock = pygame.time.Clock()


WHITE = (255,255,255)
BLACK = (0,0,0)
RED = (220,30,30)
GREEN = (30,180,30)
BLUE = (30,80,220)
GRAY = (100,100,100)

# 玩家
player = {
    "name":"勇者",
    "hp":100,
    "max_hp":100,
    "atk":14,
    "level":1,
    "exp":0,
    "exp_need":70,
    "gold":50,
    "potion":2
}

monsters = [
    {"name":"史莱姆","hp":40,"max_hp":40,"atk":8,"exp":20,"gold":12},
    {"name":"野狼","hp":60,"max_hp":60,"atk":13,"exp":35,"gold":22},
    {"name":"哥布林","hp":80,"max_hp":80,"atk":17,"exp":55,"gold":40}
]

boss = {"name":"魔狼王","hp":180,"max_hp":180,"atk":24,"exp":200,"gold":130}

# 游戏状态
STATE_MAIN = 0
STATE_BATTLE = 1
STATE_SHOP = 2
state = STATE_MAIN
current_monster = None
msg = ""

def draw_text(text, x, y, size=24, color=BLACK):
    font = pygame.font.SysFont("simhei", size)
    surf = font.render(text, True, color)
    screen.blit(surf, (x,y))

def draw_hp_bar(x,y,w,h,current,maxval):
    ratio = current / maxval
    pygame.draw.rect(screen, GRAY, (x,y,w,h))
    pygame.draw.rect(screen, RED, (x,y,w*ratio,h))
    pygame.draw.rect(screen, BLACK, (x,y,w,h),2)

def level_up():
    while player["exp"] >= player["exp_need"]:
        player["exp"] -= player["exp_need"]
        player["level"] +=1
        player["max_hp"] +=22
        player["hp"] = player["max_hp"]
        player["atk"] +=4
        player["exp_need"] = int(player["exp_need"]*1.35)
        global msg
        msg = f"升级！等级{player['level']}"

def start_battle(is_boss=False):
    global state, current_monster, msg
    if is_boss:
        current_monster = boss.copy()
    else:
        current_monster = random.choice(monsters).copy()
    state = STATE_BATTLE
    msg = f"遭遇 {current_monster['name']}！"

def player_attack():
    global msg
    crit = random.random()
    if crit > 0.85:
        dmg = player["atk"] *2
        msg = "💥暴击！"
    else:
        dmg = random.randint(player["atk"]-3, player["atk"]+3)
        msg = f"你造成 {dmg} 伤害"
    current_monster["hp"] -= dmg
    if current_monster["hp"] <= 0:
        player["exp"] += current_monster["exp"]
        player["gold"] += current_monster["gold"]
        msg += f" 胜利！+{current_monster['exp']}经验 +{current_monster['gold']}金币"
        level_up()
        return True
    return False

def monster_attack():
    global msg
    dmg = random.randint(current_monster["atk"]-2, current_monster["atk"]+2)
    player["hp"] -= dmg
    msg = f"{current_monster['name']}攻击，你受到{dmg}伤害"

def use_potion():
    global msg
    if player["potion"]>0:
        player["potion"] -=1
        player["hp"] +=45
        if player["hp"]>player["max_hp"]:
            player["hp"] = player["max_hp"]
        msg = "喝下药水，恢复45生命"
    else:
        msg = "没有药水了！"

def try_escape():
    global state, msg
    if current_monster["name"] == "魔狼王":
        msg = "BOSS不能逃跑！"
        return
    if random.random()>0.45:
        state = STATE_MAIN
        msg = "逃跑成功"
    else:
        msg = "逃跑失败！"
        monster_attack()

# 主循环
running = True
while running:
    screen.fill((240,240,240))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN and event.button ==1:
            mx, my = pygame.mouse.get_pos()
            if state == STATE_MAIN:
                # 主界面按钮
                if 50<mx<300 and 180<my<230:
                    start_battle(False)
                if 50<mx<300 and 250<my<300:
                    start_battle(True)
                if 50<mx<300 and 320<my<370:
                    state = STATE_SHOP
                if 50<mx<300 and 390<my<440:
                    running = False
            elif state == STATE_BATTLE:
                #战斗按钮
                if 40<mx<190 and 480<my<530:
                    win = player_attack()
                    if not win:
                        monster_attack()
                    else:
                        state = STATE_MAIN
                if 210<mx<360 and 480<my<530:
                    use_potion()
                if 380<mx<530 and 480<my<530:
                    try_escape()
                if player["hp"] <=0:
                    msg = "游戏结束！"
                    running = False
            elif state == STATE_SHOP:
                if 50<mx<300 and 200<my<250:
                    if player["gold"]>=25:
                        player["gold"] -=25
                        player["potion"] +=1
                        msg = "购买药水成功"
                    else:
                        msg = "金币不足"
                if 50<mx<300 and 280<my<330:
                    state = STATE_MAIN

    # 主界面
    if state == STATE_MAIN:
        draw_text("==== 图形RPG冒险 ====", 20,20,32,BLUE)
        draw_text(f"等级:{player['level']}  HP:{player['hp']}/{player['max_hp']}",20,70)
        draw_text(f"攻击:{player['atk']}  经验:{player['exp']}/{player['exp_need']}",20,100)
        draw_text(f"金币:{player['gold']}  药水:{player['potion']}",20,130)
        draw_text(msg,20,150,22,RED)
        #按钮
        pygame.draw.rect(screen,GREEN,(50,180,250,50))
        draw_text("1.外出打怪",70,190,26)
        pygame.draw.rect(screen,RED,(50,250,250,50))
        draw_text("2.挑战BOSS魔狼王",70,260,26)
        pygame.draw.rect(screen,BLUE,(50,320,250,50))
        draw_text("3.商店",70,330,26)
        pygame.draw.rect(screen,GRAY,(50,390,250,50))
        draw_text("4.退出游戏",70,400,26)

    elif state == STATE_BATTLE:
        draw_text("【战斗】",300,20,30,RED)
        draw_text(f"怪物：{current_monster['name']}",30,80,26)
        draw_hp_bar(30,110,350,25,current_monster["hp"],current_monster["max_hp"])
        draw_text(f"{current_monster['hp']}/{current_monster['max_hp']}",400,110)

        draw_text("你的状态",30,180,26)
        draw_hp_bar(30,210,350,25,player["hp"],player["max_hp"])
        draw_text(f"{player['hp']}/{player['max_hp']}",400,210)
        draw_text(f"药水:{player['potion']}",30,250)
        draw_text(msg,30,290,22,BLUE)

        #战斗按钮
        pygame.draw.rect(screen,GREEN,(40,480,150,50))
        draw_text("攻击",70,490,24)
        pygame.draw.rect(screen,BLUE,(210,480,150,50))
        draw_text("喝药水",235,490,24)
        pygame.draw.rect(screen,GRAY,(380,480,150,50))
        draw_text("逃跑",410,490,24)

    elif state == STATE_SHOP:
        draw_text("=====商店=====",20,30,32,BLUE)
        draw_text(f"你的金币：{player['gold']}",20,80,24)
        draw_text(msg,20,120,22,RED)
        pygame.draw.rect(screen,GREEN,(50,200,250,50))
        draw_text("购买药水 25金币",70,210,24)
        pygame.draw.rect(screen,GRAY,(50,280,250,50))
        draw_text("返回",70,290,24)

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

pygame.quit()
