更新日志

2025/6/14

制作基本玩法如下:

操作 移动 跳跃 切换物品栏 破坏方块 放置方块 退出
按键 / 空格 1~9 D(delete) P(put) Q(quit)

2025/6/15~2025/6/20

1.增加世界范围至1000*100

大范围世界可以更好的探索

2.修改放置和破坏逻辑

自由选择放置/破坏

3.添加更多信息

如血量、饱食度

4.添加新方块

现在方块类型如下:

空气 草方块 泥土 石头
煤炭矿 铁矿 钻石矿 原木
叶子 沙子 基岩

2025/6/21

优化打印方法

删除边框+减少闪烁+同步显示

优化钻石矿生成逻辑

解决了钻石矿生成在地表的BUG

减少了钻石矿脉在地下的数量

更改矿洞生成逻辑

不使用椭圆而是随机游走

矿石更加密集的分布(异常出现在地表不关我事)

2025/6/22

更改随机方式

把随机方法改成了rand(),可以自定义种子

添加指令

t键开启聊天,打开后可以输入指令

指令 \seed \tp @p ~±x ~±y
功能 获取种子 传送到x,yx,y

添加苹果

打破树叶有20%20\%的概率掉落苹果

修改世界生成的一部分逻辑

不产生浮空水

树冠更加还原

2025/6/23~2025/6/26

添加饱食度机制

每移动50次/等待10分钟会掉一格饱食度

拿着苹果按P键可以吃

改进地形生成

水湖不再是简简单单的一个长方形了

矿石和洞穴不会裸露在地表

绘图升级

饱食度和血量显示

以及若干项其他的

2025/7/4

渲染大改造

只能看到表面的方块

2025/8/30

更改重力系统

玩家落地不会穿过方块

准备更新

添加合成系统

打开背包可以合成物品

添加更多物品类型

自己看

修改物理系统

沙子下落

水和岩浆流动,相遇会发生反应

BUG反馈

BUG反馈(洛谷)

代码

// 字字落实
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <conio.h>
#include <windows.h>
#include <algorithm>
#include <sstream>
#include <unordered_map>

using namespace std;

// 控制台颜色常量
const int BLACK = 0;
const int BLUE = 1;
const int GREEN = 2;
const int CYAN = 3;
const int RED = 4;
const int MAGENTA = 5;
const int BROWN = 6;
const int LIGHTGRAY = 7;
const int DARKGRAY = 8;
const int LIGHTBLUE = 9;
const int LIGHTGREEN = 10;
const int LIGHTCYAN = 11;
const int LIGHTRED = 12;
const int LIGHTMAGENTA = 13;
const int YELLOW = 14;
const int WHITE = 15;

// 确保 ENABLE_VIRTUAL_TERMINAL_PROCESSING 被定义
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif

// 光标定位函数
void gotoXY(HANDLE hOut, int x, int y) {
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(hOut, pos);
}

// ANSI转义序列映射
void setColor(HANDLE hOut, int textColor, int bgColor) {
    static /*const*/ map<int, int> colorMap = {
        {BLACK, 30}, {RED, 31}, {GREEN, 32}, {BROWN, 33},
        {BLUE, 34}, {MAGENTA, 35}, {CYAN, 36}, {WHITE, 37},
        {DARKGRAY, 90}, {LIGHTRED, 91}, {LIGHTGREEN, 92}, {YELLOW, 93},
        {LIGHTBLUE, 94}, {LIGHTMAGENTA, 95}, {LIGHTCYAN, 96}, {LIGHTGRAY, 97}
    };
//    for (int i=0;i<=14;i++) {
//        colorMap[i]=30;
//    }
    
    auto textIt = colorMap.find(textColor);
    auto bgIt = colorMap.find(bgColor);
    
    string colorCode;
    if (textIt != colorMap.end() && bgIt != colorMap.end()) {
        colorCode = "\033[" + to_string(textIt->second) + ";" + to_string(bgIt->second + 10) + "m";
    }
    else {
        colorCode = "\033[0m";
    }
    
    DWORD written;
    WriteConsole(hOut, colorCode.c_str(), colorCode.length(), &written, NULL);
}

// 重置为默认颜色
void resetColor(HANDLE hOut) {
    const char* resetCode = "\033[0m";
    DWORD written;
    WriteConsole(hOut, resetCode, strlen(resetCode), &written, NULL);
}

enum class BlockType {
    AIR,       // 空气
    GRASS,     // 草方块
    DIRT,      // 泥土
    STONE,     // 石头
    COAL_ORE,  // 煤炭矿
    IRON_ORE,  // 铁矿
    DIAMOND_ORE, // 钻石矿
    WOOD,      // 原木
    LEAF,      // 叶子
    SAND,      // 沙子
    WATER,     // 水
    BEDROCK,   // 基岩
    COAL,      // 煤炭
    IRON,      // 铁
    DIAMOND,   // 钻石
    APPLE,     // 苹果 
    NONE       // 无物品
};

// 物品栏槽位
struct InventorySlot {
    BlockType type;
    int count;
};

struct BlockDisplay {
    string line1;   // 第一行内容
    string line2;   // 第二行内容
    int bgColor;    // 背景颜色
    string name;    // 方块名称
};

BlockDisplay getBlockDisplay(BlockType type) {
    static const map<BlockType, BlockDisplay> displayMap = {
        {BlockType::AIR,         {"    ", "    ", LIGHTCYAN,  " 空气 "}},
        {BlockType::GRASS,       {"草方", "块  ", GREEN,      "草方块"}},
        {BlockType::DIRT,        {"泥土", "    ", BROWN,      " 泥土 "}},
        {BlockType::STONE,       {"石头", "    ", DARKGRAY,   " 石头 "}},
        {BlockType::COAL_ORE,    {"煤炭", "矿  ", DARKGRAY,   "煤炭矿"}},
        {BlockType::IRON_ORE,    {"铁矿", "    ", DARKGRAY,   " 铁矿 "}},
        {BlockType::DIAMOND_ORE, {"钻石", "矿  ", LIGHTBLUE,  "钻石矿"}},
        {BlockType::WOOD,        {"原木", "    ", BROWN,      " 原木 "}},
        {BlockType::LEAF,        {"叶子", "    ", LIGHTGREEN, " 叶子 "}},
        {BlockType::SAND,        {"沙子", "    ", YELLOW,     " 沙子 "}},
        {BlockType::WATER,       {"水  ", "    ", BLUE,       "  水  "}},
        {BlockType::BEDROCK,     {"基岩", "    ", DARKGRAY,   " 基岩 "}},
        {BlockType::COAL,        {"煤炭", "    ", DARKGRAY,   " 煤炭 "}},
        {BlockType::IRON,        {"铁  ", "    ", DARKGRAY,   "  铁  "}},
        {BlockType::DIAMOND,     {"钻石", "    ", LIGHTBLUE,  " 钻石 "}},
        {BlockType::APPLE,       {"苹果", "    ", RED,        " 苹果 "}},
        {BlockType::NONE,        {"    ", "    ", BLACK,      "      "}}
    };
    return displayMap.at(type);
}

// 检查方块是否可穿过(空气、水、叶子或原木)
bool isPassable(BlockType type) {
    return type == BlockType::AIR || type == BlockType::WATER || 
           type == BlockType::LEAF || type == BlockType::WOOD;
}

// 检查方块是否实体(不可穿过)
bool isSolid(BlockType type) {
    return !isPassable(type);
}

// 检查方块是否可以放置
bool canPlace(BlockType type) {
    return type != BlockType::AIR && type != BlockType::COAL && 
           type != BlockType::IRON && type != BlockType::DIAMOND && 
           type != BlockType::APPLE && type != BlockType::NONE;
}

// 检查方块是否可以使用 
bool canUse(BlockType type) {
    return type == BlockType::APPLE;
}

// 检查方块是否可以食用 
bool canEat(BlockType type) {
    return type == BlockType::APPLE;
}

// 检查方块是否可以破坏
bool canBreak(BlockType type) {
    return type != BlockType::AIR && type != BlockType::BEDROCK;
}

// 获取方块破坏后的掉落物
BlockType getDropItem(BlockType type) {
    switch (type) {
        case BlockType::COAL_ORE: return BlockType::COAL;
        case BlockType::IRON_ORE: return BlockType::IRON;
        case BlockType::DIAMOND_ORE: return BlockType::DIAMOND;
        case BlockType::LEAF:
            if (rand() % 100 > 20) {
                return BlockType::NONE;
            } else {
                return BlockType::APPLE;
            }
        default: return type;
    }
}

// 随机游走隧道生成函数
void generateRandomTunnel(vector<vector<BlockType>>& world, int startX, int startY, 
                         int length, int width, 
                         int WIDTH, int HEIGHT, int BEDROCK_LAYER) {
    int x = startX;
    int y = startY;
    
    for (int i = 0; i < length; i++) {
        // 确保位置在边界内
        x = max(0, min(WIDTH - 1, x));
        y = max(0, min(HEIGHT - 1, y));
        
        // 清除隧道区域(圆形)
        int radius = width / 2;
        for (int dx = -radius; dx <= radius; dx++) {
            for (int dy = -radius; dy <= radius; dy++) {
                if (dx*dx + dy*dy <= radius*radius + 1) { // +1 使形状更自然
                    int nx = x + dx;
                    int ny = y + dy;
                    
                    if (nx >= 0 && nx < WIDTH && ny >= 0 && ny < HEIGHT) {
                        // 确保不会破坏基岩及其上方的石头层
                        // 只允许破坏 y < 95 的方块
                        if (ny < HEIGHT - BEDROCK_LAYER) {
                            if (world[ny][nx] == BlockType::STONE) {
                                world[ny][nx] = BlockType::AIR;
                            }
                        }
                    }
                }
            }
        }
        
        // 随机选择下一步方向(70%水平,30%垂直)
        double direction = (1.0 * (rand() % 100) / 100);
        if (direction < 0.7) { // 水平移动
            if ((1.0 * (rand() % 100) / 100) < 0.5) x++; // 右
            else x--;                 // 左
        } else {                // 垂直移动
            if ((1.0 * (rand() % 100) / 100) < 0.5) y++; // 下
            else y--;                 // 上
        }
        
        // 10%概率增加宽度变化
        if ((1.0 * (rand() % 100) / 100) < 0.1) {
            width = max(1, min(6, width + ((1.0 * (rand() % 100) / 100) < 0.5 ? 1 : -1)));
        }
    }
}

// 生成1000×100的随机地形(带矿洞)
vector<vector<BlockType>> generateWorld() {
    const int WIDTH = 1000;
    const int HEIGHT = 100;
    const int BEDROCK_LAYER = 5; // 基岩层厚度
    const int DIAMOND_MIN_Y = HEIGHT - 15; // 钻石矿最小生成高度 (y>85)
    const int MAX_CAVE_DEPTH = HEIGHT - 20; // 矿洞最大深度 (y<80)
    
    // 创建世界网格(初始为空气)
    vector<vector<BlockType>> world(HEIGHT, vector<BlockType>(WIDTH, BlockType::AIR));
    
    // 生成高度图(使用简单噪声)
    vector<int> groundHeight(WIDTH);
    for (int x = 0; x < WIDTH; x++) {
        // 基础高度(平原地面在50高度)
        int baseHeight = 50;
        
        // 添加轻微噪声(±4格)
        double noise = sin(x * 0.02) * 1.5 + cos(x * 0.05) * 1.2 + sin(x * 0.03) * 1.3;
        groundHeight[x] = baseHeight + static_cast<int>(noise);
        
        // 确保高度在合理范围内
        groundHeight[x] = max(10, min(HEIGHT - 10, groundHeight[x]));
    }
    
    // 填充世界(从顶部到底部)
    for (int x = 0; x < WIDTH; x++) {
        // 基岩层(世界底部)
        for (int y = HEIGHT - BEDROCK_LAYER; y < HEIGHT; y++) {
            if (y == HEIGHT - 1) {
                world[y][x] = BlockType::BEDROCK;
            } else {
                world[y][x] = BlockType::STONE; // 基岩上方的石头层
            }
        }
        
        // 从地表向下填充
        for (int y = groundHeight[x]; y < HEIGHT - BEDROCK_LAYER; y++) {
            // 地表层 - 草方块
            if (y == groundHeight[x]) {
                world[y][x] = BlockType::GRASS;
            }
            // 浅层(泥土)
            else if (y <= groundHeight[x] + 3) {
                world[y][x] = BlockType::DIRT;
            }
            // 深层(石头和矿石)
            else {
                // 深层矿石生成(煤炭、铁矿、钻石)
                double r = (1.0 * (rand() % 100) / 100);
                if (r < 0.02) { // 2%的概率生成煤炭矿
                    world[y][x] = BlockType::COAL_ORE;
                } else if (r < 0.005) { // 0.5%的概率生成铁矿
                    world[y][x] = BlockType::IRON_ORE;
                } else if (r < 0.0005 && y >= DIAMOND_MIN_Y) { // 0.05%的概率生成钻石矿,且只在地下15层以内
                    world[y][x] = BlockType::DIAMOND_ORE;
                } else {
                    world[y][x] = BlockType::STONE;
                }
            }
        }
    }
    
    // 使用随机游走算法生成矿洞
    for (int i = 0; i < 60; i++) { // 增加矿洞数量到60个
        // 随机选择起始点(在地表下)
        int startX = static_cast<int>((1.0 * (rand() % 100) / 100) * (WIDTH - 20)) + 10;
        
        // 确保矿洞不会在接近基岩的地方生成(至少离基岩层10格以上)
        int minY = groundHeight[startX] + 5;
        int maxY = MAX_CAVE_DEPTH; // 最大深度限制
        
        if (maxY < minY) continue; // 如果地表高度太高,跳过
        
        int startY = minY + static_cast<int>((1.0 * (rand() % 100) / 100) * (maxY - minY));
        
        // 矿洞参数
        int tunnelLength = 80 + static_cast<int>((1.0 * (rand() % 100) / 100) * 120); // 80-200步长
        int tunnelWidth = 2 + static_cast<int>((1.0 * (rand() % 100) / 100) * 3);     // 2-5格宽
        int branchChance = 20; // 20%概率产生分支
        int maxBranches = 3;   // 最多3个分支
        
        // 主矿洞生成
        generateRandomTunnel(world, startX, startY, tunnelLength, tunnelWidth, WIDTH, HEIGHT, BEDROCK_LAYER);
        
        // 生成分支
        int branches = 0;
        for (int j = 0; j < tunnelLength && branches < maxBranches; j++) {
            if (static_cast<int>((1.0 * (rand() % 100) / 100) * 100) < branchChance) {
                int branchX = startX;
                int branchY = startY;
                int branchLength = 30 + static_cast<int>((1.0 * (rand() % 100) / 100) * 70); // 30-100步长
                int branchWidth = 1 + static_cast<int>((1.0 * (rand() % 100) / 100) * 2);    // 1-3格宽
                
                // 随机选择分支方向(上下左右)
                int dir = static_cast<int>((1.0 * (rand() % 100) / 100) * 4);
                switch (dir) {
                    case 0: branchX += 5; break; // 右
                    case 1: branchX -= 5; break; // 左
                    case 2: branchY += 5; break; // 下
                    case 3: branchY -= 5; break; // 上
                }
                
                // 确保分支不会在基岩附近生成
                if (branchY < HEIGHT - BEDROCK_LAYER - 5) {
                    generateRandomTunnel(world, branchX, branchY, branchLength, branchWidth, WIDTH, HEIGHT, BEDROCK_LAYER);
                    branches++;
                }
            }
        }
    }
    
    // 添加小型矿脉(包括钻石)
    for (int i = 0; i < 100; i++) {
        int veinX = static_cast<int>((1.0 * (rand() % 100) / 100) * (WIDTH - 20)) + 10;
        
        // 矿脉类型(煤炭、铁矿或钻石)
        BlockType veinType;
        double r = (1.0 * (rand() % 100) / 100);
        if (r < 0.6) {
            veinType = BlockType::COAL_ORE; // 60%煤炭
        } else if (r < 0.9) {
            veinType = BlockType::IRON_ORE; // 30%铁矿
        } else {
            veinType = BlockType::DIAMOND_ORE; // 10%钻石
        }
        
        // 根据矿脉类型设置生成深度
        int minDepth, maxDepth;
        if (veinType == BlockType::DIAMOND_ORE) {
            minDepth = DIAMOND_MIN_Y; // 钻石矿最小深度
            maxDepth = HEIGHT - BEDROCK_LAYER - 5; // 钻石矿最大深度
        } else {
            minDepth = groundHeight[veinX] + 10; // 其他矿石最小深度
            maxDepth = HEIGHT - BEDROCK_LAYER - 5; // 其他矿石最大深度
        }
        
        // 确保深度范围有效
        if (minDepth >= maxDepth) continue;
        
        int veinY = minDepth + static_cast<int>((1.0 * (rand() % 100) / 100) * (maxDepth - minDepth));
        
        int veinSize = 5 + static_cast<int>((1.0 * (rand() % 100) / 100) * 10); // 5-15格大小
        
        for (int dx = -veinSize; dx <= veinSize; dx++) {
            for (int dy = -veinSize; dy <= veinSize; dy++) {
                int xPos = veinX + dx;
                int yPos = veinY + dy;
                
                if (xPos >= 0 && xPos < WIDTH && yPos >= 0 && yPos < HEIGHT) {
                    // 矿脉形状(随机斑点)
                    if (abs(dx) + abs(dy) < veinSize && (1.0 * (rand() % 100) / 100) < 0.7) {
                        // 确保不会替换基岩层
                        if (world[yPos][xPos] == BlockType::STONE && yPos < HEIGHT - BEDROCK_LAYER) {
                            world[yPos][xPos] = veinType;
                        }
                    }
                }
            }
        }
    }
    
    // 添加湖泊(在地表)
    for (int i = 0; i < 20; i++) { // 增加湖泊数量
        int lakeX = static_cast<int>((1.0 * (rand() % 100) / 100) * (WIDTH - 10)) + 5;
        int lakeY = groundHeight[lakeX]; // 地表位置
        int lakeWidth = 5 + static_cast<int>((1.0 * (rand() % 100) / 100) * 8);
        int lakeDepth = 2 + static_cast<int>((1.0 * (rand() % 100) / 100) * 3);
        
        for (int dx = -lakeWidth / 2 - 1 - static_cast<int>((1.0 * (rand() % 100) / 100) * 3); dx < lakeWidth / 2 + 1 + static_cast<int>((1.0 * (rand() % 100) / 100) * 3); dx++) {
            int xPos = lakeX + dx;
            if (xPos < 0 || xPos >= WIDTH) continue;
            
            for (int dy = 0; dy < lakeDepth + 3; dy++) {
                int yPos = lakeY + dy;
                if (yPos < HEIGHT && yPos >= 0) {
                    if (world[yPos - 1][xPos] == BlockType::AIR) {
                        world[yPos][xPos] = BlockType::SAND;
                    } else if (world[yPos][xPos] == BlockType::AIR) {
                        world[yPos][xPos] = BlockType::DIRT;
                    } else if (world[yPos][xPos] == BlockType::GRASS) {
                        world[yPos][xPos] = BlockType::DIRT;
                    }
                }
            }
        }
        
        for (int dx = -lakeWidth / 2; dx < lakeWidth / 2; dx++) {
            int xPos = lakeX + dx;
            if (xPos < 0 || xPos >= WIDTH) continue;
            
            int newLakeDepth = lakeDepth;
            if (dx == -lakeWidth / 2 || dx == lakeWidth / 2 - 1) {
            	newLakeDepth--;
			}
            for (int dy = 0; dy < newLakeDepth; dy++) {
                int yPos = lakeY + dy;
                if (yPos < HEIGHT && yPos >= 0) {
                    world[yPos][xPos] = BlockType::WATER;
                }
            }
            
            for (int dy = 1; dy <= 10; dy++) {
                int yPos = lakeY - dy;
                world[yPos][xPos] = BlockType::AIR;
            }
        }
    }
    
    // 在地表生成树木(草方块上)
    for (int x = 0; x < WIDTH; x++) {
        if ((1.0 * (rand() % 100) / 100) < 0.05 && world[groundHeight[x]][x] == BlockType::GRASS) {
            int treeHeight = 3 + static_cast<int>((1.0 * (rand() % 100) / 100)); // 3-4格高
            
            // 生成树干(从地表向上)
            for (int i = 1; i <= treeHeight && (groundHeight[x] - i) >= 0; i++) {
                world[groundHeight[x] - i][x] = BlockType::WOOD;
            }
            
            // 生成树叶(树干顶部)
            int canopyY = groundHeight[x] - treeHeight;
            if (canopyY >= 0) {
                // 树叶层(树冠)
                int leafRadius = 2;
                for (int dy = 0; dy >= -leafRadius - 1; dy--) {
                    for (int dx = -leafRadius; dx <= leafRadius; dx++) {
                        int nx = x + dx;
                        int ny = canopyY + dy;
                        if (nx >= 0 && nx < WIDTH && ny >= 0 && ny < HEIGHT) {
                            if (world[ny][nx] == BlockType::AIR) {
                                world[ny][nx] = BlockType::LEAF;
                            }
                        }
                    }
                    if (leafRadius == 2) {
                        leafRadius = 1;
                    }
                }
                // 树顶
                if (canopyY - 1 >= 0) {
                    world[canopyY - 1][x] = BlockType::LEAF;
                }
            }
        }
    }
    
    // 修复y=95层问题:确保基岩层上方的石头层不被破坏
    for (int x = 0; x < WIDTH; x++) {
        for (int y = HEIGHT - BEDROCK_LAYER; y < HEIGHT - 1; y++) { // y=95到98
            // 如果这些位置被破坏成了空气,恢复为石头
            if (world[y][x] == BlockType::AIR) {
                world[y][x] = BlockType::STONE;
            }
        }
    }
    
    // 在深层添加额外的钻石矿
    for (int i = 0; i < 500; i++) { // 增加钻石矿生成次数
        int diamondX = static_cast<int>((1.0 * (rand() % 100) / 100) * WIDTH);
        int diamondY = DIAMOND_MIN_Y + static_cast<int>((1.0 * (rand() % 100) / 100) * (HEIGHT - BEDROCK_LAYER - DIAMOND_MIN_Y - 1));
        
        if (diamondY >= DIAMOND_MIN_Y && diamondY < HEIGHT - BEDROCK_LAYER) {
            // 确保位置是石头
            if (world[diamondY][diamondX] == BlockType::STONE) {
                world[diamondY][diamondX] = BlockType::DIAMOND_ORE;
            }
        }
    }
    
    return world;
}

// 玩家结构
struct Player {
    int x;          // X坐标(世界坐标,-499~500)
    int y;          // Y坐标(世界坐标,0~99)
    float velocity; // 垂直速度
    bool inWater;   // 是否在水中
    bool onGround;  // 是否站在地面上
    bool canJump;   // 是否可以跳跃
    vector<InventorySlot> inventory; // 物品栏 (9个槽位)
    vector<InventorySlot> backpack;   // 背包 (27个槽位)
    int selectedSlot; // 当前选中的物品栏槽位
    int health;     // 血量(0-20)
    int hunger;     // 饱食度(0-20)
    int Hunger;     // 累计饥饿 
};

// 初始化玩家
void initPlayer(Player& player) {
    player.x = 0;   // 世界中心
    player.y = 45;  // 地表上方
    player.velocity = 0.0f;
    player.inWater = false;
    player.onGround = false;
    player.canJump = true;
    player.health = 20;
    player.hunger = 20;
    player.inventory = vector<InventorySlot>(9, {BlockType::NONE, 0});
    player.backpack = vector<InventorySlot>(27, {BlockType::NONE, 0}); // 初始化背包
    player.selectedSlot = 0;
}

// 添加物品到物品栏或背包
void addToInventory(Player& player, BlockType type) {
    // 无法获得空气、水和基岩
    if (type == BlockType::AIR || type == BlockType::WATER || type == BlockType::BEDROCK) {
        return;
    }
    
    // 先尝试物品栏
    for (auto& slot : player.inventory) {
        if (slot.type == type) {
            slot.count++;
            return;
        }
    }
    
    // 接着尝试背包
    for (auto& slot : player.backpack) {
        if (slot.type == type) {
            slot.count++;
            return;
        }
    }
    
    // 物品栏找空槽位
    for (auto& slot : player.inventory) {
        if (slot.type == BlockType::NONE) {
            slot.type = type;
            slot.count = 1;
            return;
        }
    }
    
    // 背包找空槽位
    for (auto& slot : player.backpack) {
        if (slot.type == BlockType::NONE) {
            slot.type = type;
            slot.count = 1;
            return;
        }
    }
    
    // 物品栏和背包都满了,物品掉落(目前不会发生)
}

// 使用当前选中的物品
bool useSelectedItem(Player& player) {
    InventorySlot& slot = player.inventory[player.selectedSlot];
    if (slot.type == BlockType::NONE || slot.count <= 0) {
        return false;
    }
    
    // 减少数量
    slot.count--;
    
    // 如果数量为0,清空槽位
    if (slot.count == 0) {
        slot.type = BlockType::NONE;
    }
    
    return true;
}

// 生成血量字符串
string getHealthBar(int value) {
    string bar;
    // 每2点一个单位
    for (int i = 0; i < 10; i++) {
        int points = value - i * 2;
        if (points >= 2) {
            bar += "■■  "; // 满
        } else if (points >= 1) {
            bar += "■□  "; // 半
        } else {
            bar += "□□  "; // 空
        }
    }
    return bar;
}

// 生成饱食度字符串
string getHungerBar(int value) {
    string bar;
    // 每2点一个单位
    for (int i = 9; i >= 0; i--) {
        int points = value - i * 2;
        if (points >= 2) {
            bar += "■■  "; // 满
        } else if (points >= 1) {
            bar += "□■  "; // 半
        } else {
            bar += "□□  "; // 空
        }
    }
    return bar;
}

// 检查方块是否可见 
bool isVisible(Player player, int worldX, int worldY, const vector<vector<BlockType>>& world) {
    // 玩家位置总是可见
    if (worldX == player.x && worldY == player.y) {
        return true;
    }
    
    // 检查方块是否可穿过
    if (worldY >= 0 && worldY < 100 && worldX >= -499 && worldX < 501) {
        int arrayX = worldX + 499;
        int arrayY = worldY;
        BlockType block = world[arrayY][arrayX];
        
        if (isPassable(block)) {
            return true;
        }
        
        // 检查四个方向相邻方块是否可穿过
        int dx[] = {0, 0, -1, 1};
        int dy[] = {-1, 1, 0, 0};
        for (int i = 0; i < 4; i++) {
            int nx = worldX + dx[i];
            int ny = worldY + dy[i];
            if (ny >= 0 && ny < 100 && nx >= -499 && nx < 501) {
                int nArrayX = nx + 499;
                int nArrayY = ny;
                BlockType neighbor = world[nArrayY][nArrayX];
                if (isPassable(neighbor)) {
                    return true;
                }
            }
        }
    }
    return false;
}

// 渲染背包界面
void renderBackpack(HANDLE hOut, Player& player, int selectedIndex) {
    // 清屏
    system("cls");
    
    // 显示标题
    gotoXY(hOut, 0, 0);
    setColor(hOut, BROWN, BLACK);
    cout << "============================================== 背包 ==============================================";
    
    // 渲染背包内容 (3行9列)
    for (int i = 0; i < 3; i++) {
        gotoXY(hOut, 0, i * 2 + 2);
        for (int j = 0; j < 9; j++) {
            int index = i * 9 + j;
            const InventorySlot& slot = player.backpack[index];
            BlockDisplay itemDisplay = getBlockDisplay(slot.type);
            string name = itemDisplay.name;
            int color = itemDisplay.bgColor;
            
            // 高亮选中的槽位
            if (index == selectedIndex) {
                setColor(hOut, BLACK, LIGHTGRAY);
            } else {
                resetColor(hOut);
            }
            
            cout << "[";
	        if (index == selectedIndex) {
	            setColor(hOut, color, LIGHTGRAY); // 选中的槽位:灰色背景
	        } else {
	            setColor(hOut, WHITE, color); // 其他槽位:黑色背景
	        }
			cout << name;
	        if (index == selectedIndex) {
	            setColor(hOut, BLACK, LIGHTGRAY); // 选中的槽位:灰色背景
	        } else {
	            resetColor(hOut); // 其他槽位:黑色背景
	        }
			cout << ":" << slot.count << "]";
            
            // 添加空格分隔
            resetColor(hOut);
            if (j < 8) cout << " ";
        	else cout << "  ";
        }
    }
    
    // 显示物品栏标题
    gotoXY(hOut, 0, 9);
    setColor(hOut, BROWN, BLACK);
    cout << "--------------------------------------------- 物品栏 ---------------------------------------------";
    
    // 渲染物品栏
    gotoXY(hOut, 0, 11);
    for (int i = 0; i < 9; i++) {
        const InventorySlot& slot = player.inventory[i];
        BlockDisplay itemDisplay = getBlockDisplay(slot.type);
        string name = itemDisplay.name;
        int color = itemDisplay.bgColor;
        resetColor(hOut);
        cout << "[";
	    setColor(hOut, WHITE, color);
		cout << name;
	    resetColor(hOut);
		cout << ":" << slot.count << "]";
        
        // 添加空格分隔
        resetColor(hOut);
        if (i < 8) cout << " ";
        else cout << "  ";
    }
    
    // 操作提示
    gotoXY(hOut, 0, 13);
    resetColor(hOut);
    cout << "操作说明:";
    gotoXY(hOut, 0, 14);
    cout << "- 方向键: 选择背包物品";
    gotoXY(hOut, 0, 15);
    cout << "- 数字键(1-9): 将选中物品放入物品栏对应槽位";
    gotoXY(hOut, 0, 16);
    cout << "- E/ESC: 关闭背包";
}

// 渲染世界(包含玩家和状态信息)
void renderWorld(HANDLE hOut, const vector<vector<BlockType>>& world, const Player& player, 
                int selectedX = -1, int selectedY = -1, bool initialRender = false) {
    const int VIEW_WIDTH = 23;
    const int VIEW_HEIGHT = 11;
    
    // 计算视图范围(以玩家为中心)
    int startX = player.x - VIEW_WIDTH / 2;
    int startY = player.y - VIEW_HEIGHT / 2;
    
    // 确保视图在边界内
    startX = max(-499, min(501 - VIEW_WIDTH, startX));
    startY = max(0, min(100 - VIEW_HEIGHT, startY));
    
    static vector<vector<BlockType>> lastWorld(VIEW_HEIGHT, vector<BlockType>(VIEW_WIDTH, BlockType::AIR));
    static int lastPlayerX = -1000;
    static int lastPlayerY = -1000;
    static int lastSelectedX = -1000;
    static int lastSelectedY = -1000;
    static int lastHealth = -1;
    static int lastHunger = -1;
    static int lastSelectedSlot = -1;
    static vector<InventorySlot> lastInventory(9, {BlockType::NONE, 0});
    
    // 渲染视图范围内的方块
    for (int viewY = 0; viewY < VIEW_HEIGHT; viewY++) {
        int worldY = startY + viewY;
        
        for (int viewX = 0; viewX < VIEW_WIDTH; viewX++) {
            int worldX = startX + viewX;
    	    BlockType block = BlockType::AIR;
    	    
    	    // 检查可见性
	        bool visible = isVisible(player, worldX, worldY, world);
	        if (!visible) {
	            block = BlockType::NONE; // 不可见方块显示为黑色
	        } else if (worldY >= 0 && worldY < 100 && worldX >= -499 && worldX < 501) {
	            int arrayX = worldX + 499;
	            int arrayY = worldY;
	            block = world[arrayY][arrayX];
	        }
            
            // 检查是否需要重绘 
            bool needRedraw = initialRender || 
                             lastWorld[viewY][viewX] != block ||
                             (worldX == player.x && worldY == player.y) != (worldX == lastPlayerX && worldY == lastPlayerY) ||
                             (worldX == selectedX && worldY == selectedY) != (worldX == lastSelectedX && worldY == lastSelectedY);
            
            if (needRedraw) {
                // 计算控制台位置
                int consoleY = viewY * 2 + 2;
                int consoleX = viewX * 4;
                
                // 移动到方块位置
                gotoXY(hOut, consoleX, consoleY);
                
                // 获取方块信息 
                BlockDisplay display = getBlockDisplay(block);
                
                // 检查是否是选中的方块
                if (worldX == selectedX && worldY == selectedY) {
                    setColor(hOut, BLACK, WHITE); // 白底黑字
	                // 检查是否是玩家位置
	                if (worldX == player.x && worldY == player.y) {
	                	cout << "玩家"; 
					} else {
                    	cout << display.line1;
					}
                }
                else if (worldX != player.x or worldY != player.y or block != BlockType::AIR) {
	                // 检查是否是玩家位置
	                if (worldX == player.x && worldY == player.y) {
	                    setColor(hOut, WHITE, RED); // 玩家红色背景
	                } else {
	                    setColor(hOut, WHITE, display.bgColor); // 方块背景色
					}
                    cout << display.line1;
                }
				else {
                    setColor(hOut, WHITE, RED); // 玩家红色背景
                    cout << "玩家";
				}
                
                // 移动到第二行
                gotoXY(hOut, consoleX, consoleY + 1);
                
                // 检查是否是选中的方块
                if (worldX == selectedX && worldY == selectedY) {
                    setColor(hOut, BLACK, WHITE); // 白底黑字
	                // 检查是否是玩家位置
	                if (worldX == player.x && worldY == player.y) {
	                	cout << "    "; 
					} else {
                    	cout << display.line2;
					}
                }
                else if (worldX != player.x or worldY != player.y or block != BlockType::AIR) {
	                // 检查是否是玩家位置
	                if (worldX == player.x && worldY == player.y) {
	                    setColor(hOut, WHITE, RED); // 玩家红色背景
	                } else {
	                    setColor(hOut, WHITE, display.bgColor); // 方块背景色
					}
                    cout << display.line2;
                }
				else {
                    cout << "    ";
				}
                
                // 更新缓存
                lastWorld[viewY][viewX] = block;
            }
        }
    }
    
    // 显示血量和饱食度(使用■、□表示)
    if (initialRender || player.health != lastHealth) {
        gotoXY(hOut, 0, VIEW_HEIGHT * 2 + 2);
        setColor(hOut, LIGHTRED, BLACK);
        cout << getHealthBar(player.health);
        gotoXY(hOut, 0, VIEW_HEIGHT * 2 + 3);
        setColor(hOut, LIGHTRED, BLACK);
        cout << getHealthBar(player.health);
        lastHealth = player.health;
    }
    
    if (initialRender || player.hunger != lastHunger) {
        gotoXY(hOut, 54, VIEW_HEIGHT * 2 + 2);
        setColor(hOut, YELLOW, BLACK);
        cout << getHungerBar(player.hunger);
        gotoXY(hOut, 54, VIEW_HEIGHT * 2 + 3);
        setColor(hOut, YELLOW, BLACK);
        cout << getHungerBar(player.hunger);
        lastHunger = player.hunger;
    }
    
    // 显示物品栏
    bool inventoryChanged = false;
    for (int i = 0; i < 9; i++) {
        if (player.inventory[i].type != lastInventory[i].type || 
            player.inventory[i].count != lastInventory[i].count ||
            (i == player.selectedSlot) != (i == lastSelectedSlot)) {
            inventoryChanged = true;
            break;
        }
    }
    
    if (initialRender || inventoryChanged) {
        gotoXY(hOut, 0, VIEW_HEIGHT * 2 + 4);
        for (int i = 0; i < 9; i++) {
            const InventorySlot& slot = player.inventory[i];
            BlockDisplay itemDisplay = getBlockDisplay(slot.type);
            string name = itemDisplay.name;
            int color = itemDisplay.bgColor;
            if (i == player.selectedSlot) {
                setColor(hOut, BLACK, LIGHTGRAY); // 选中的槽位:灰色背景
            } else {
                resetColor(hOut); // 其他槽位:黑色背景
            }
            cout << "[";
	        if (i == player.selectedSlot) {
	            setColor(hOut, color, LIGHTGRAY); // 选中的槽位:灰色背景
	        } else {
	            setColor(hOut, WHITE, color); // 其他槽位:黑色背景
	        }
			cout << name;
	        if (i == player.selectedSlot) {
	            setColor(hOut, BLACK, LIGHTGRAY); // 选中的槽位:灰色背景
	        } else {
	            resetColor(hOut); // 其他槽位:黑色背景
	        }
			cout << ":" << slot.count << "]";
            
            // 添加空格分隔
            resetColor(hOut);
            if (i < 8) cout << " ";
            else cout << "  ";
            
            // 更新缓存
            lastInventory[i] = slot;
        }
        lastSelectedSlot = player.selectedSlot;
    }
    
    // 显示坐标
    if (initialRender || player.x != lastPlayerX || player.y != lastPlayerY) {
        resetColor(hOut);
        gotoXY(hOut, 0, 1);
        cout << "X:" << player.x << " Y:" << 99 - player.y << "        ";
        lastPlayerX = player.x;
        lastPlayerY = player.y;
    }
    
    // 更新选中位置缓存
    lastSelectedX = selectedX;
    lastSelectedY = selectedY;
}

int main() {
    // 启用ANSI转义序列支持
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD dwMode = 0;
    GetConsoleMode(hOut, &dwMode);
    dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    SetConsoleMode(hOut, dwMode);
    
    // 设置控制台窗口大小
    COORD size = { 100, 30 };
    SetConsoleScreenBufferSize(hOut, size);
    SMALL_RECT rc = { 0, 0, 99, 29 };
    SetConsoleWindowInfo(hOut, true, &rc);
    CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
    SetConsoleCursorInfo(hOut, &cursor_info);
    
    // 设置随机种子
    cout << "请输入种子(空表示随机):\033[?25h";
    setColor(hOut, BROWN, BLACK);
    string s;
	getline(cin, s);
	int seed;
	if (s == "") {
		seed = time(nullptr);
	} else {
		seed = stoll(s);
	}
	cout << "\033[?25l";
    resetColor(hOut);
    srand(seed);
    system("cls");
    
    // 生成1000×100的世界
    cout << "正在生成世界..." << endl;
    vector<vector<BlockType>> world = generateWorld();
    cout << "世界生成完成!按任意键开始游戏" << endl;
    _getch();
    system("cls");
    
    // 初始化玩家
    Player player;
    initPlayer(player);
    
    // 方块选择模式变量
    bool inSelectionMode = false;
    bool isDiggingMode = false;
    int selectedX = player.x;
    int selectedY = player.y + 1; // 默认选择玩家下方方块
    
    // 背包模式变量
    bool isBackpackOpen = false;
    int backpackSelected = 0; // 背包选中的槽位
    
    // 游戏主循环
    bool initialRender = true;
    while (true) {
        bool playerMoved = false; // 标记玩家是否移动
        bool playerJumped = false; // 标记玩家是否跳跃
        bool blockChanged = false; // 标记方块是否被破坏或放置
        
        // 处理输入
        if (_kbhit()) {
            char key = _getch();
            
            // 如果在背包模式
            if (isBackpackOpen) {
                // 方向键移动选择框
                if (key == 75 && backpackSelected > 0) { // 左箭头
                    backpackSelected--;
                    
                    // 重新渲染背包
                    renderBackpack(hOut, player, backpackSelected);
                }
                else if (key == 77 && backpackSelected < 26) { // 右箭头
                    backpackSelected++;
                    
                    // 重新渲染背包
                    renderBackpack(hOut, player, backpackSelected);
                }
                else if (key == 72 && backpackSelected >= 9) { // 上箭头
                    backpackSelected -= 9;
                    
                    // 重新渲染背包
                    renderBackpack(hOut, player, backpackSelected);
                }
                else if (key == 80 && backpackSelected < 18) { // 下箭头
                    backpackSelected += 9;
                    
                    // 重新渲染背包
                    renderBackpack(hOut, player, backpackSelected);
                }
                // 数字键交换物品
                else if (key >= '1' && key <= '9') {
                    int slotIndex = key - '1'; // 物品栏槽位
                    
                    // 获取选中的背包物品
                    InventorySlot& backpackSlot = player.backpack[backpackSelected];
                    InventorySlot& invSlot = player.inventory[slotIndex];
                    
                    // 如果两个槽位的物品类型相同,则合并
                    if (backpackSlot.type == invSlot.type) {
                        invSlot.count += backpackSlot.count;
                        backpackSlot.type = BlockType::NONE;
                        backpackSlot.count = 0;
                    } 
                    // 否则交换两个槽位的物品
                    else {
                        InventorySlot temp = backpackSlot;
                        backpackSlot = invSlot;
                        invSlot = temp;
                    }
                    
                    // 重新渲染背包
                    renderBackpack(hOut, player, backpackSelected);
                }
                // E/ESC关闭背包
                else if (key == 'e' || key == 'E' || key == 27) {
                    isBackpackOpen = false;
                    initialRender = true; // 重新渲染世界
                    system("cls"); // 清屏
                }
            }
            // 如果在选择模式
            else if (inSelectionMode) {
                // 方向键移动选择框
                if (key == 75 && selectedX > -499) { // 左箭头
                	if (isVisible(player, selectedX - 1, selectedY, world)) {
                		selectedX--;
					}
                }
                else if (key == 77 && selectedX < 500) { // 右箭头
                	if (isVisible(player, selectedX + 1, selectedY, world)) {
                		selectedX++;
					}
                }
                else if (key == 72 && selectedY > 0) { // 上箭头
                	if (isVisible(player, selectedX, selectedY - 1, world)) {
                		selectedY--;
					}
                }
                else if (key == 80 && selectedY < 99) { // 下箭头
                	if (isVisible(player, selectedX, selectedY + 1, world)) {
                		selectedY++;
					}
                }
                // 空格确认操作
                else if (key == 32) { // 空格
                    // 确保在世界范围内
                    if (selectedY >= 0 && selectedY < 100 && selectedX >= -499 && selectedX < 501) {
                        // 转换为数组索引
                        int arrayX = selectedX + 499;
                        int arrayY = selectedY;
                        
                        // 挖掘操作
                        if (isDiggingMode) {
                            // 检查是否可以破坏(基岩、水、空气不能挖掘)
                            BlockType targetBlock = world[arrayY][arrayX];
                            if (targetBlock != BlockType::BEDROCK && 
                                targetBlock != BlockType::WATER && 
                                targetBlock != BlockType::AIR) {
                                
                                // 获取掉落物
                                BlockType drop = getDropItem(targetBlock);
                                
                                // 添加到物品栏
                                addToInventory(player, drop);
                                
                                // 破坏方块(变为空气)
                                world[arrayY][arrayX] = BlockType::AIR;
                                blockChanged = true;
                            }
                        }
                        // 放置操作
                        else {
                            // 获取当前选中的物品
                            BlockType selected = player.inventory[player.selectedSlot].type;
                            
                            // 检查是否可以放置
                            if (canPlace(selected)) {
                                // 检查目标位置是否可以放置(非水方块或玩家位置不能放置)
                                if ((world[arrayY][arrayX] == BlockType::AIR || world[arrayY][arrayX] == BlockType::WATER) && 
                                    (selectedX != player.x || selectedY != player.y)) {
                                    
                                    // 使用物品
                                    if (useSelectedItem(player)) {
                                        // 放置方块
                                        world[arrayY][arrayX] = selected;
                                        blockChanged = true;
                                    }
                                }
                            }
                        }
                    }
                    inSelectionMode = false;
                }
                // ESC退出选择模式
                else if (key == 27) { // ESC
                    inSelectionMode = false;
                }
            }
            // 不在任何特殊模式
            else {
                // 打开背包
                if (key == 'e' || key == 'E') {
                    isBackpackOpen = true;
                    backpackSelected = 0; // 默认选中第一个槽位
                    renderBackpack(hOut, player, backpackSelected);
                }
                // 左移
                else if (key == 75 && player.x > -499) { // 左箭头
                    // 检查左侧方块是否可穿过
                    int arrayX = (player.x - 1) + 499;
                    int arrayY = player.y;
                    if (arrayX >= 0 && arrayX < 1000 && arrayY >= 0 && arrayY < 100) {
                        if (isPassable(world[arrayY][arrayX])) {
                            player.x--;
                            player.Hunger += 240;
                            playerMoved = true;
                        }
                    }
                }
                // 右移
                else if (key == 77 && player.x < 500) { // 右箭头
                    // 检查右侧方块是否可穿过
                    int arrayX = (player.x + 1) + 499;
                    int arrayY = player.y;
                    if (arrayX >= 0 && arrayX < 1000 && arrayY >= 0 && arrayY < 100) {
                        if (isPassable(world[arrayY][arrayX])) {
                            player.x++;
                            player.Hunger += 240;
                            playerMoved = true;
                        }
                    }
                }
                // 跳跃
                else if (key == 32) { // 空格
                    // 只有在地面上或水中才能跳跃
                    if (player.canJump && (player.onGround || player.inWater)) {
                        player.Hunger += 240;
                        player.velocity = -1.1f;
                        player.onGround = false;
                        player.canJump = false; // 防止连续跳跃
                        playerJumped = true;
                    }
                }
                // 物品栏选择 (1-9)
                else if (key >= '1' && key <= '9') {
                    int slot = key - '1'; // 转换为0-8的索引
                    if (slot >= 0 && slot < 9) {
                        player.selectedSlot = slot;
                    }
                }
                // 破坏方块 (D键)
                else if (key == 'd' || key == 'D') {
                    inSelectionMode = true;
                    isDiggingMode = true;
                    selectedX = player.x;
                    selectedY = player.y; // 默认选择玩家方块
                }
                // 放置方块/使用物品 (P键)
                else if (key == 'p' || key == 'P') {
					BlockType selected = player.inventory[player.selectedSlot].type;
					// 使用物品 
					if (canUse(selected)) {
						// 食用食物 
						if (canEat(selected)) {
							if (player.hunger != 20) {
								// 苹果 
								if (selected == BlockType::APPLE) {
									player.hunger = min(player.hunger + 4, 20);
								}
								// 消耗物品
								useSelectedItem(player);
							}
						}
					}
					// 放置方块 
					else {
	                    inSelectionMode = true;
	                    isDiggingMode = false;
	                    selectedX = player.x;
	                    selectedY = player.y;
	                }
                }
                // 指令 
                else if (key == 't' || key == 'T') {
    				setColor(hOut, BROWN, BLACK);
	                cout << "\033[?25h";
                	gotoXY(hOut, 0, 27);
                	cout << "                                                                                                      ";
                	gotoXY(hOut, 0, 27);
					while (!_kbhit());
					if (_getch() != 10) {
						char c;
						cin >> c;
	                	if (c == '/') {
		                	string op;
		                	cin >> op;
		                	// 获取种子 
		                	if (op == "seed") {
		                		gotoXY(hOut, 0, 27);
				                cout << "                                                                                                      ";
								gotoXY(hOut, 0, 27);
				                cout << seed << endl;
							}
		                	// 传送
		                	else if (op == "tp") {
		                		string obj;
		                		cin >> obj;
		                		string sx, sy;
		                		cin >> sx >> sy;
		                		int nx, ny;
		                		if (sx == "~") {
		                			nx = player.x;
								} else if (sx[0] == '~') {
		                			if (sx[1] == '+') {
		                				nx = player.x + stoll(sx.substr(2));
									} else if (sx[1] == '-') {
		                				nx = player.x - stoll(sx.substr(2));
									} else {
		                				nx = player.x + stoll(sx.substr(1));
									}
								} else {
									nx = stoll(sx);
								}
								if (sy == "~") {
									ny = 99 - player.y;
		                		} else if (sy[0] == '~') {
		                			if (sy[1] == '+') {
		                				ny = 99 - player.y + stoll(sy.substr(2));
									} else if (sy[1] == '-') {
		                				ny = 99 - player.y - stoll(sy.substr(2));
									} else {
		                				ny = 99 - player.y + stoll(sy.substr(1));
									}
								} else {
									ny = stoll(sy);
								}
								ny = 99 - ny;
				                gotoXY(hOut, 0, 27);
				                cout << "                                                                                                      ";
		                		gotoXY(hOut, 0, 27);
		                		if (obj != "@p") {
				                	cout << "选择对象失败" << endl;
		                		} else if (nx > 500 or nx < -499 or ny > 98 or ny < 0) {
				                	cout << "超出世界范围,无法传送" << endl;
								} else {
				                	player.x = nx;
			                		player.y = ny;
			                	}
							}
						} else {
				            gotoXY(hOut, 0, 27);
				            cout << "                                                                                                      ";
		                	gotoXY(hOut, 0, 27);
						}
	    				resetColor(hOut);
		                cout << "\033[?25l";
		            }
				}
                // 退出
                else if (key == 'q' || key == 'Q') {
                    break;
                }
            }
        }
        
        // 饥饿 
        player.Hunger++; 
        if (player.Hunger >= 12000) {
        	if (player.hunger > 0) {
	        	player.hunger--;
	        }
        	player.Hunger = 0;
		}
        
        // 物理更新(只在非选择模式和非背包模式)
        if (!inSelectionMode && !isBackpackOpen) {
            player.velocity = min(player.velocity + 0.1f, 1.0f); // 重力加速度
            int newY = player.y + static_cast<int>(player.velocity);
            
            // 检查是否在水中
            bool wasInWater = player.inWater;
            int arrayX = player.x + 499;
            int arrayY = player.y;
            if (arrayX >= 0 && arrayX < 1000 && arrayY >= 0 && arrayY < 100) {
                player.inWater = (world[arrayY][arrayX] == BlockType::WATER);
            } else {
                player.inWater = false;
            }
            
            // 如果在水里,减缓下落速度
            if (player.inWater) {
            	if (player.velocity > 1.0f) {
                	player.velocity *= 0.8f;
				} else {
					player.velocity += 0.0001f;
				}
                player.canJump = true; // 在水中时可以重置跳跃能力
            }
            
            // 碰撞检测
            bool wasOnGround = player.onGround;
            player.onGround = false;
            
            if (newY != player.y) {
                // 检查下方方块是否可穿过
                int belowX = player.x + 499;
                int belowY = newY;
                if (belowY < 100 && belowY >= 0 && belowX >= 0 && belowX < 1000) {
                    if (isPassable(world[belowY][belowX])) {
                        // 可以下落
                        player.y = newY;
                    } else {
                        // 碰到实体方块
                        if (player.velocity > 0) {
                            // 落到方块上
                            player.y = newY - 1;
                            player.onGround = true;
                            player.canJump = true; // 落地后可以再次跳跃
                        } else {
                            // 碰到基岩层 
                            player.y = newY + 1;
                        }
                        player.velocity = 0.0f;
                    }
                } else {
                    // 边界处理
                    if (newY < 0) {
                        player.y = 0;
                        player.velocity = 0.0f;
                    } else if (newY >= 100) {
                        player.y = 99;
                        player.velocity = 0.0f;
                        player.onGround = true;
                        player.canJump = true;
                    }
                }
            }
            
            // 边界检查
            player.x = max(-499, min(500, player.x));
            player.y = max(0, min(99, player.y));
            
            // 更新地面状态
            int groundCheckX = player.x + 499;
            int groundCheckY = player.y + 1;
            if (groundCheckY < 100 && groundCheckY >= 0 && groundCheckX >= 0 && groundCheckX < 1000) {
                player.onGround = isSolid(world[groundCheckY][groundCheckX]);
            }
            
            // 在水中时自动重置跳跃能力
            if (player.inWater) {
                player.canJump = true;
            }
        }
        
        // 如果不是背包模式,渲染世界
        if (!isBackpackOpen) {
            // 显示模式提示
            gotoXY(hOut, 0, 0);
            resetColor(hOut);
            if (inSelectionMode) {
                if (isDiggingMode) {
                    cout << "挖掘模式: 用方向键选择方块,空格挖掘,ESC取消";
                } else {
                    cout << "放置模式: 用方向键选择位置,空格放置,ESC取消";
                }
            } else {
                cout << "移动: 方向键  跳跃: 空格  挖掘: D  放置/使用: P  背包: E  指令: t  退出: Q";
            }
            cout << "                              ";
            
            // 渲染世界(在选择模式下传递选中位置)
            if (inSelectionMode) {
                renderWorld(hOut, world, player, selectedX, selectedY, initialRender);
            } else {
                renderWorld(hOut, world, player, -1, -1, initialRender);
            }
            
            initialRender = false;
        }
        
        // 控制帧率
        Sleep(50);
    }
    
    // 结束画面 
    system("cls");
    cout << "感谢游玩!" << endl;
    
    return 0;
}