import tkinter as tk

# ---------- 常量 ----------
CELL_SIZE = 20          # 每个格子像素大小
COLS = 40               # 世界宽度（格子数）
ROWS = 30               # 世界高度（格子数）
TOOLBAR_HEIGHT = 60     # 底部工具栏高度

# 方块类型（ID 从 0 开始，0 代表空气）
BLOCK_AIR = 0
BLOCK_GRASS = 1
BLOCK_DIRT = 2
BLOCK_STONE = 3
BLOCK_WOOD = 4
BLOCK_LEAVES = 5
BLOCK_SAND = 6
BLOCK_WATER = 7
BLOCK_PLANKS = 8

# 方块颜色（用于绘制）
COLORS = {
    BLOCK_AIR:    "#ffffff",   # 白色（透明效果）
    BLOCK_GRASS:  "#7cfc00",   # 草绿
    BLOCK_DIRT:   "#8b5a2b",   # 棕色
    BLOCK_STONE:  "#808080",   # 灰色
    BLOCK_WOOD:   "#8b4513",   # 深棕
    BLOCK_LEAVES: "#228b22",   # 森林绿
    BLOCK_SAND:   "#f4e4a0",   # 沙色
    BLOCK_WATER:  "#1e90ff",   # 道奇蓝
    BLOCK_PLANKS: "#deb887",   # 黄褐色
}

# 工具栏显示顺序（每个方块对应的显示名称）
TOOLBAR_BLOCKS = [
    (BLOCK_GRASS,   "草地"),
    (BLOCK_DIRT,    "泥土"),
    (BLOCK_STONE,   "石头"),
    (BLOCK_WOOD,    "木头"),
    (BLOCK_LEAVES,  "树叶"),
    (BLOCK_SAND,    "沙子"),
    (BLOCK_WATER,   "水"),
    (BLOCK_PLANKS,  "木板"),
]

# ---------- 游戏主类 ----------
class Minecraft2D:
    def __init__(self, root):
        self.root = root
        self.root.title("2D 我的世界")
        self.root.resizable(False, False)

        # 世界数据（二维列表）
        self.world = [[BLOCK_AIR for _ in range(COLS)] for _ in range(ROWS)]
        self._init_world()

        # 玩家位置（行列索引）
        self.player_row = ROWS // 2
        self.player_col = COLS // 2

        # 当前选中的方块（默认第一个）
        self.selected_block = TOOLBAR_BLOCKS[0][0]

        # 创建画布（大小 = 世界区域 + 工具栏）
        self.canvas_width = COLS * CELL_SIZE
        self.canvas_height = ROWS * CELL_SIZE + TOOLBAR_HEIGHT
        self.canvas = tk.Canvas(root, width=self.canvas_width,
                                height=self.canvas_height,
                                bg="#f0f0f0")
        self.canvas.pack()

        # 绑定鼠标事件
        self.canvas.bind("<Button-1>", self.on_left_click)   # 左键破坏
        self.canvas.bind("<Button-3>", self.on_right_click)  # 右键放置
        self.canvas.bind("<Button-2>", self.on_middle_click) # 中键拾取（可选）

        # 绑定键盘事件（玩家移动）
        root.bind("<KeyPress-w>", lambda e: self.move_player(-1, 0))
        root.bind("<KeyPress-s>", lambda e: self.move_player(1, 0))
        root.bind("<KeyPress-a>", lambda e: self.move_player(0, -1))
        root.bind("<KeyPress-d>", lambda e: self.move_player(0, 1))

        # 工具栏点击事件（直接在画布上绘制按钮，并绑定点击区域）
        # 我们在 draw 方法中绘制工具栏，并存储每个按钮的矩形ID和对应的方块ID
        self.toolbar_rects = []  # 存储 (矩形id, 方块id)

        # 绘制初始界面
        self.draw()

    def _init_world(self):
        """生成一个简单的初始地形：草地层 + 泥土层 + 石头基底，并点缀树木"""
        for r in range(ROWS):
            for c in range(COLS):
                if r < 5:   # 天空（空气）
                    self.world[r][c] = BLOCK_AIR
                elif r == 5:
                    self.world[r][c] = BLOCK_GRASS
                elif r < 10:
                    self.world[r][c] = BLOCK_DIRT
                else:
                    self.world[r][c] = BLOCK_STONE

        # 在草地表面随机种树（简单放置木头和树叶）
        import random
        for _ in range(8):
            c = random.randint(5, COLS - 6)
            r = 5  # 草地层
            # 树干（高 3-4 格）
            trunk_height = random.randint(3, 4)
            for i in range(trunk_height):
                if r + i < ROWS:
                    self.world[r + i][c] = BLOCK_WOOD
            # 树叶（在树干顶部周围）
            leaf_row = r + trunk_height - 1
            for dr in (-1, 0, 1):
                for dc in (-1, 0, 1):
                    nr, nc = leaf_row + dr, c + dc
                    if 0 <= nr < ROWS and 0 <= nc < COLS and self.world[nr][nc] == BLOCK_AIR:
                        self.world[nr][nc] = BLOCK_LEAVES

        # 添加一个小水池
        for r in range(7, 9):
            for c in range(3, 6):
                if 0 <= r < ROWS and 0 <= c < COLS:
                    self.world[r][c] = BLOCK_WATER

    def move_player(self, dr, dc):
        """移动玩家，边界限制"""
        new_r = self.player_row + dr
        new_c = self.player_col + dc
        if 0 <= new_r < ROWS and 0 <= new_c < COLS:
            self.player_row = new_r
            self.player_col = new_c
            self.draw()

    def get_block_at(self, row, col):
        """安全获取方块，边界外返回空气"""
        if 0 <= row < ROWS and 0 <= col < COLS:
            return self.world[row][col]
        return BLOCK_AIR

    def set_block_at(self, row, col, block_id):
        """安全设置方块"""
        if 0 <= row < ROWS and 0 <= col < COLS:
            self.world[row][col] = block_id

    def on_left_click(self, event):
        """左键点击：破坏方块（设置为空气）"""
        col = event.x // CELL_SIZE
        row = event.y // CELL_SIZE
        # 确保点击在世界区域内（不是工具栏）
        if row < ROWS and col < COLS:
            self.set_block_at(row, col, BLOCK_AIR)
            self.draw()

    def on_right_click(self, event):
        """右键点击：放置当前选中的方块"""
        col = event.x // CELL_SIZE
        row = event.y // CELL_SIZE
        if row < ROWS and col < COLS:
            # 不能放在玩家所在格（防止卡住）
            if row == self.player_row and col == self.player_col:
                return
            self.set_block_at(row, col, self.selected_block)
            self.draw()

    def on_middle_click(self, event):
        """中键点击：拾取目标方块的类型（方便快速切换）"""
        col = event.x // CELL_SIZE
        row = event.y // CELL_SIZE
        if row < ROWS and col < COLS:
            block = self.get_block_at(row, col)
            if block != BLOCK_AIR:
                # 检查是否在工具栏中
                for b_id, name in TOOLBAR_BLOCKS:
                    if b_id == block:
                        self.selected_block = b_id
                        self.draw()
                        return

    def draw(self):
        """绘制整个界面（世界 + 工具栏）"""
        self.canvas.delete("all")

        # ---- 绘制世界 ----
        for r in range(ROWS):
            for c in range(COLS):
                block_id = self.world[r][c]
                color = COLORS.get(block_id, "#ffffff")
                x1 = c * CELL_SIZE
                y1 = r * CELL_SIZE
                x2 = x1 + CELL_SIZE
                y2 = y1 + CELL_SIZE
                self.canvas.create_rectangle(x1, y1, x2, y2,
                                             fill=color, outline="gray")

        # ---- 绘制玩家（红色高亮） ----
        px = self.player_col * CELL_SIZE
        py = self.player_row * CELL_SIZE
        self.canvas.create_rectangle(px, py, px + CELL_SIZE, py + CELL_SIZE,
                                     outline="red", width=3)

        # ---- 绘制工具栏 ----
        tool_y = ROWS * CELL_SIZE
        # 背景条
        self.canvas.create_rectangle(0, tool_y, self.canvas_width, self.canvas_height,
                                     fill="#d3d3d3", outline="")

        # 绘制每个工具按钮
        self.toolbar_rects.clear()
        btn_width = 50
        btn_height = TOOLBAR_HEIGHT - 10
        margin = 10
        start_x = 10

        for idx, (block_id, name) in enumerate(TOOLBAR_BLOCKS):
            x1 = start_x + idx * (btn_width + 5)
            y1 = tool_y + 5
            x2 = x1 + btn_width
            y2 = y1 + btn_height

            # 背景色（如果选中则高亮）
            fill_color = "#a0a0a0" if block_id == self.selected_block else "#e0e0e0"
            rect = self.canvas.create_rectangle(x1, y1, x2, y2,
                                                fill=fill_color, outline="black")
            # 方块预览小方块
            preview_size = 20
            px_pre = x1 + (btn_width - preview_size) // 2
            py_pre = y1 + 5
            self.canvas.create_rectangle(px_pre, py_pre,
                                         px_pre + preview_size, py_pre + preview_size,
                                         fill=COLORS[block_id], outline="black")
            # 文字标签
            self.canvas.create_text(x1 + btn_width//2, y1 + btn_height - 12,
                                    text=name, font=("Arial", 8))

            # 存储矩形ID与方块ID的映射（用于点击检测）
            self.toolbar_rects.append((rect, block_id))

            # 为每个按钮绑定点击事件（通过标签绑定）
            self.canvas.tag_bind(rect, "<Button-1>",
                                 lambda e, b=block_id: self.select_tool(b))

    def select_tool(self, block_id):
        """选择工具栏中的方块"""
        self.selected_block = block_id
        self.draw()

# ---------- 启动游戏 ----------
if __name__ == "__main__":
    root = tk.Tk()
    game = Minecraft2D(root)
    root.mainloop()