import pygame
import sys
import random

# ====================== 初始化 ======================
pygame.init()
pygame.font.init()

WIDTH, HEIGHT = 900, 550
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Super Mario")
clock = pygame.time.Clock()
FPS = 60

# ====================== 颜色 ======================
SKY_BLUE = (107, 185, 240)
BROWN = (120, 70, 30)
GREEN = (36, 160, 36)
DARK_GREEN = (10, 90, 10)
YELLOW = (255, 220, 0)
RED = (220, 30, 30)
GRAY = (80, 80, 80)
BLACK = (0, 0, 0)
WHITE = (255,255,255)
ORANGE = (255,130,0)

# ====================== 字体（修复崩溃） ======================
try:
    font = pygame.font.Font(None, 32)
except Exception:
    font = None

# ====================== 资源加载函数（保留接口，找不到图自动返回None） ======================
def load_image(path, w, h):
    try:
        img = pygame.image.load(path).convert_alpha()
        img = pygame.transform.scale(img, (w, h))
        return img
    except Exception:
        return None

# 图片路径（你后续放图片只需要把文件放进images文件夹即可）
IMG_MARIO = "images/mario.png"
IMG_GOOMBA = "images/goomba.png"
IMG_COIN = "images/coin.png"
IMG_PIPE = "images/pipe.png"
IMG_QUESTION = "images/question_block.png"
IMG_FLAG = "images/flag.png"

mario_img = load_image(IMG_MARIO, 40, 50)
goomba_img = load_image(IMG_GOOMBA, 36, 36)
coin_img = load_image(IMG_COIN, 20, 20)
pipe_img = load_image(IMG_PIPE, 60, 80)
question_img = load_image(IMG_QUESTION, 36, 36)
flag_img = load_image(IMG_FLAG, 40, 60)

# ====================== 马里奥数据 ======================
mario_w, mario_h = 40, 50
mario_x = 80
mario_y = HEIGHT - mario_h - 50
speed_x = 0
speed_y = 0
move_speed = 5
gravity = 0.8
jump_power = -18
on_ground = False
score = 0
facing_right = True

ground_y = HEIGHT - 50

# ====================== 地图元素 ======================
platforms = [
    (220, 360, 120, 22),
    (400, 290, 130, 22),
    (560, 220, 110, 22)
]

bricks = [
    (300, ground_y - 40, 36, 36),
    (520, ground_y - 40, 36, 36)
]

# 管道
pipes = [
    {"x": 650, "y": ground_y - 80, "w": 60, "h": 80}
]

# 终点旗帜
flag = {
    "x": 820,
    "y": ground_y - 60,
    "w": 40,
    "h": 60
}

# 问号砖块
question_blocks = [
    {"x": 340, "y": 250, "w": 36, "h": 36, "used": False, "coin_count": 3},
    {"x": 500, "y": 180, "w": 36, "h": 36, "used": False, "coin_count": 2}
]

# 地图静态金币
coins = []

def spawn_coins():
    global coins
    coins.clear()
    coin_positions = [
        (250, 320),
        (430, 250),
        (590, 180),
        (180, ground_y - 35),
        (450, ground_y - 35)
    ]
    for x, y in coin_positions:
        coins.append({"x": x, "y": y, "size": 20})

spawn_coins()

# 问号砖块顶出来的动态金币
pop_coins = []

# ====================== 敌人 ======================
enemies = []

def spawn_enemies():
    global enemies
    enemies.clear()
    enemies.append({
        "x": 350, "y": ground_y - 36,
        "w": 36, "h": 36,
        "vx": -1.5, "left": 280, "right": 550
    })
    enemies.append({
        "x": 600, "y": ground_y - 36,
        "w": 36, "h": 36,
        "vx": 1.2, "left": 540, "right": 750
    })

spawn_enemies()

# ====================== 游戏状态 ======================
game_over = False
game_clear = False

# AABB矩形碰撞
def rect_aabb(a, b):
    return (
        a["x"] < b["x"] + b["w"] and
        a["x"] + a["w"] > b["x"] and
        a["y"] < b["y"] + b["h"] and
        a["y"] + a["h"] > b["y"]
    )

# ====================== 主循环 ======================
running = True
while running:
    clock.tick(FPS)
    screen.fill(SKY_BLUE)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    if not game_over and not game_clear:
        keys = pygame.key.get_pressed()
        speed_x = 0

        if keys[pygame.K_LEFT]:
            speed_x = -move_speed
            facing_right = False
        if keys[pygame.K_RIGHT]:
            speed_x = move_speed
            facing_right = True
        if keys[pygame.K_SPACE] and on_ground:
            speed_y = jump_power
            on_ground = False

        # 重力
        speed_y += gravity
        mario_x += speed_x
        mario_y += speed_y

        # 边界限制
        mario_x = max(0, min(mario_x, WIDTH - mario_w))

        # 地面碰撞
        on_ground = False
        if mario_y + mario_h >= ground_y:
            mario_y = ground_y - mario_h
            speed_y = 0
            on_ground = True

        mario_rect = {"x": mario_x, "y": mario_y, "w": mario_w, "h": mario_h}

        # 平台碰撞
        for px, py, pw, ph in platforms:
            plat_rect = {"x": px, "y": py, "w": pw, "h": ph}
            if rect_aabb(mario_rect, plat_rect) and speed_y > 0:
                mario_y = py - mario_h
                speed_y = 0
                on_ground = True

        # 问号砖块碰撞（从下方顶）
        for qb in question_blocks:
            qb_rect = {"x": qb["x"], "y": qb["y"], "w": qb["w"], "h": qb["h"]}
            if rect_aabb(mario_rect, qb_rect):
                if speed_y < 0 and mario_y + mario_h > qb["y"] + qb["h"] // 2:
                    mario_y = qb["y"] + qb["h"]
                    speed_y = 0
                    if not qb["used"] and qb["coin_count"] > 0:
                        qb["coin_count"] -= 1
                        score += 100
                        pop_coins.append({
                            "x": qb["x"] + 8,
                            "y": qb["y"] - 30,
                            "vy": -10,
                            "size": 20
                        })
                        if qb["coin_count"] == 0:
                            qb["used"] = True

        # 管道碰撞阻挡
        for pipe in pipes:
            if rect_aabb(mario_rect, pipe):
                if speed_x > 0:
                    mario_x = pipe["x"] - mario_w
                if speed_x < 0:
                    mario_x = pipe["x"] + pipe["w"]

        # 到达终点旗帜 → 通关
        if rect_aabb(mario_rect, flag):
            game_clear = True

        # 拾取地图金币
        new_coins = []
        for coin in coins:
            coin_rect = {"x": coin["x"], "y": coin["y"], "w": coin["size"], "h": coin["size"]}
            if rect_aabb(mario_rect, coin_rect):
                score += 100
            else:
                new_coins.append(coin)
        coins = new_coins

        # 动态弹出金币物理
        new_pop_coins = []
        for pc in pop_coins:
            pc["vy"] += gravity
            pc["y"] += pc["vy"]
            pc_rect = {"x": pc["x"], "y": pc["y"], "w": pc["size"], "h": pc["size"]}
            if rect_aabb(mario_rect, pc_rect):
                score += 100
            else:
                if pc["y"] < ground_y:
                    new_pop_coins.append(pc)
        pop_coins = new_pop_coins

        # 敌人巡逻与碰撞判定
        for enemy in enemies[:]:
            enemy["x"] += enemy["vx"]
            if enemy["x"] <= enemy["left"]:
                enemy["vx"] = abs(enemy["vx"])
            if enemy["x"] >= enemy["right"]:
                enemy["vx"] = -abs(enemy["vx"])

            enemy_rect = {"x": enemy["x"], "y": enemy["y"], "w": enemy["w"], "h": enemy["h"]}
            if rect_aabb(mario_rect, enemy_rect):
                if speed_y > 0 and mario_y + mario_h - 15 < enemy["y"] + enemy["h"] // 2:
                    score += 200
                    enemies.remove(enemy)
                    speed_y = -10
                else:
                    game_over = True

    # ====================== 绘制所有物体 ======================
    # 地面
    pygame.draw.rect(screen, BROWN, (0, ground_y, WIDTH, 50))

    # 平台
    for p in platforms:
        pygame.draw.rect(screen, GREEN, p)

    # 砖块
    for b in bricks:
        pygame.draw.rect(screen, BROWN, b)

    # 问号砖块
    for qb in question_blocks:
        if qb["used"]:
            pygame.draw.rect(screen, GRAY, (qb["x"], qb["y"], qb["w"], qb["h"]))
        else:
            if question_img:
                screen.blit(question_img, (qb["x"], qb["y"]))
            else:
                pygame.draw.rect(screen, YELLOW, (qb["x"], qb["y"], qb["w"], qb["h"]))
                pygame.draw.line(screen, BLACK, (qb["x"]+12, qb["y"]+8), (qb["x"]+24, qb["y"]+8),2)
                pygame.draw.line(screen, BLACK, (qb["x"]+18, qb["y"]+8), (qb["x"]+18, qb["y"]+22),2)

    # 管道
    for pipe in pipes:
        if pipe_img:
            screen.blit(pipe_img, (pipe["x"], pipe["y"]))
        else:
            pygame.draw.rect(screen, GREEN, (pipe["x"], pipe["y"], pipe["w"], pipe["h"]))
            pygame.draw.rect(screen, DARK_GREEN, (pipe["x"]+4, pipe["y"]+4, pipe["w"]-8, pipe["h"]-8))

    # 终点旗帜
    if flag_img:
        screen.blit(flag_img, (flag["x"], flag["y"]))
    else:
        pygame.draw.rect(screen, DARK_GREEN, (flag["x"]+18, flag["y"], 4, flag["h"]))
        pygame.draw.circle(screen, RED, (flag["x"]+20, flag["y"]+12), 10)

    # 静态金币
    for coin in coins:
        if coin_img:
            screen.blit(coin_img, (coin["x"], coin["y"]))
        else:
            pygame.draw.circle(screen, YELLOW, (coin["x"] + coin["size"] // 2, coin["y"] + coin["size"] // 2), coin["size"] // 2)
            pygame.draw.circle(screen, ORANGE, (coin["x"] + coin["size"] // 2, coin["y"] + coin["size"] // 2), coin["size"] // 2 - 3,2)

    # 弹出金币
    for pc in pop_coins:
        if coin_img:
            screen.blit(coin_img, (pc["x"], pc["y"]))
        else:
            pygame.draw.circle(screen, YELLOW, (pc["x"] + pc["size"] // 2, pc["y"] + pc["size"] // 2), pc["size"] // 2)

    # 敌人蘑菇怪
    for enemy in enemies:
        if goomba_img:
            screen.blit(goomba_img, (enemy["x"], enemy["y"]))
        else:
            pygame.draw.rect(screen, (120,70,40), (enemy["x"], enemy["y"], enemy["w"], enemy["h"]))
            pygame.draw.circle(screen, WHITE, (enemy["x"]+9, enemy["y"]+11),5)
            pygame.draw.circle(screen, WHITE, (enemy["x"]+27, enemy["y"]+11),5)

    # 马里奥绘制
    if mario_img:
        if facing_right:
            screen.blit(mario_img, (mario_x, mario_y))
        else:
            flipped = pygame.transform.flip(mario_img, True, False)
            screen.blit(flipped, (mario_x, mario_y))
    else:
        pygame.draw.rect(screen, RED, (mario_x, mario_y, mario_w, mario_h))
        pygame.draw.rect(screen, (255,180,100), (mario_x+8, mario_y+6,24,16))

    # 分数文字
    if font:
        score_text = font.render(f"Score: {score}", True, BLACK)
        screen.blit(score_text, (20, 15))
        if game_over:
            over_text = font.render("GAME OVER! Close window to exit", True, RED)
            screen.blit(over_text, (WIDTH // 2 - 180, HEIGHT // 2))
        if game_clear:
            clear_text = font.render("LEVEL CLEAR! You reached the flag!", True, GREEN)
            screen.blit(clear_text, (WIDTH // 2 - 220, HEIGHT // 2))

    pygame.display.flip()

pygame.quit()
sys.exit()