





《Paper Minecraft v3.0 - 增强版》玩法指南
🎮 游戏概述
这是一个基于控制台的2D版《我的世界》游戏,具有创造模式、多维度探索和丰富的方块系统。游戏采用ASCII字符图形,支持完整的世界生成、物品系统和跨维度冒险。
🕹️ 基本操控
游戏内操控(创造模式)
-
W/A/S/D - 向上/左/下/右移动
-
X - 破坏当前所在的方块
-
空格键 - 放置方块(或使用物品,如打火石)
-
数字键1-0 - 快速切换快捷栏
-
E - 打开物品栏界面
-
P - 打开设置菜单
-
F5 - 快速保存游戏
-
F6 - 快速加载游戏
-
ESC - 暂停游戏/返回菜单
菜单导航
-
W/S - 上下移动选择项
-
空格键 - 确认选择
-
ESC - 返回上一级菜单
-
A/D - 在某些设置中切换选项值
-
回车键 - 在输入框确认输入
🌍 游戏功能详解
1. 世界生成与管理
-
新建世界:在主菜单选择"New World",输入世界名称和种子
-
种子可为空(随机生成)或输入特定数字
-
世界名称不能重复
-
-
加载世界:在主菜单选择"Load World",从已保存的世界中选择
-
世界保存:
-
通过暂停菜单的"Save Game"保存
-
或按F5快速保存(仅当世界已有名称)
-
-
世界类型:
-
主世界(Overworld):蓝色天空,包含草地、树木、矿石等
-
下界(Nether):红色环境,包含熔岩、下界岩、石英矿等
-
2. 方块系统
游戏包含超过35种不同的方块,包括:
-
基础方块:草方块、泥土、石头、木头
-
矿石:煤矿石、铁矿石、金矿石、钻石矿石、红石矿石、绿宝石矿石
-
下界方块:下界岩、灵魂沙、下界砖、石英矿、下界金矿
-
特殊方块:水、熔岩、黑曜石、萤石、蘑菇
-
功能方块:下界传送门、火、打火石
3. 创造模式物品栏系统
游戏只有创造模式,但具有完整的物品管理系统:
-
无限资源:所有方块无限供应
-
物品栏界面(E键):
-
显示10个快捷栏槽位
-
可交换物品位置(用空格键选择后交换)
-
包含"创造模式菜单"选项,可访问所有方块
-
-
创造模式菜单:
-
浏览所有可用方块
-
选择后自动放入当前选中的快捷栏槽位
-
4. 下界维度系统
游戏的核心特色:完整的跨维度冒险
-
建造下界传送门:
-
用黑曜石(方块ID 32)建造4×5的框架
-
用打火石(方块ID 31)点击框架底部激活
-
传送门需要4×5的外框,内部2×3区域为空
-
-
跨维度旅行:
-
站在激活的传送门中自动进入另一维度
-
传送门有2秒冷却时间
-
两边的传送门会自动生成或激活
-
-
下界特色:
-
独特的红色环境
-
熔岩海、岩浆块、下界堡垒
-
下界石英矿、下界金矿
-
下界蘑菇、灵魂沙
-
萤石吊灯
-
5. 工具与互动
-
打火石(方块ID 31):
-
用于激活传送门
-
也可用于点燃火(点击黑曜石以外的地方)
-
-
水与熔岩:
-
可像普通方块一样放置
-
不能破坏基岩(方块ID 7)和传送门方块
-
6. 游戏设置
通过P键或暂停菜单进入设置:
-
帧率调整:5fps、10fps、50fps
-
渲染距离:5、10、15格
-
游戏保存/加载
-
返回游戏
🗺️ 世界生成特色
主世界:
-
程序化生成的山丘、山谷
-
自然生成的水体
-
随机树木和森林
-
地下矿洞系统
-
基岩层作为世界底部
下界:
-
多层基岩天花板和地板
-
复杂的洞穴系统
-
熔岩海
-
蘑菇森林
-
随机生成的地狱堡垒结构
-
矿脉:石英矿和金矿
📁 存档系统
-
游戏自动创建"saves"文件夹
-
每个世界保存为独立的.dat文件
-
包含:
-
种子和世界数据
-
玩家位置和状态
-
主世界和下界的所有方块
-
物品栏内容
-
当前所在维度信息
-
⚙️ 技术特性
-
实时渲染:根据渲染距离动态显示周围环境
-
双世界系统:同时维护主世界和下界的数据
-
防误操作延迟:菜单切换有1秒延迟,防止误操作
-
输入缓冲:支持世界名称和种子输入
🎯 游戏目标(创造模式)
虽然创造模式没有明确目标,但可以:
-
建造:创建宏伟的建筑和结构
-
探索:发现两个维度的所有特性
-
工程:建造功能性结构(如下界传送门系统)
-
收集:获得所有类型的方块
💡 实用技巧
-
快速建筑:使用创造模式菜单直接获取任何方块
-
维度标记:在传送门旁建造地标,防止迷路
-
安全第一:在下界小心熔岩海和岩浆块
-
备份存档:重要建筑前先备份世界文件
-
种子分享:记录有趣的种子与朋友分享相同世界
🚨 注意事项
-
游戏不能破坏基岩和传送门方块
-
水在下界会蒸发(游戏中可能不可放置)
-
某些方块(如火)会随时间消失
-
世界名称区分大小写
祝你在《Paper Minecraft v3.0》的方块世界中玩得愉快!有任何问题,可以查看游戏内的"About"部分获取更多信息。
cpp
#include<bits/stdc++.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <fstream>
#include <direct.h>
#include <io.h>
#include <sys/stat.h>
#define key(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1 : 0)
using namespace std;
// 游戏状态枚举
enum GameState {
MAIN_MENU,
IN_GAME,
INVENTORY_MENU,
SETTINGS_MENU,
NEW_WORLD_MENU,
LOAD_WORLD_MENU,
NETHER_DIMENSION
};
GameState gameState = MAIN_MENU;
string worldName = "";
bool isCreativeMode = true; // 只有创造模式
int world[301][601] = {0};
int netherWorld[301][601] = {0};
int grass[601] = {0};
int x = 300, y = 150;
int seed = 0;
int fps = 100, render = 10;
int currentBlock = 0;
int inventory[10] = {0};
int inventoryCount[10] = {0};
// 选择系统变量
int menuSelection = 0;
int inventorySelection = 0;
int worldSelection = 0;
vector<string> savedWorlds;
int creativeSelection = 0;
bool isSelectingItem = false;
int selectedSlot = -1;
bool inNether = false;
// 输入缓冲区
char worldNameInput[50] = "";
char seedInput[20] = "";
int inputPos = 0;
// 延迟控制
DWORD lastStateChangeTime = 0;
const int STATE_CHANGE_DELAY = 1000; // 1秒延迟
// 传送门冷却时间
DWORD lastPortalTime = 0;
const int PORTAL_COOLDOWN = 2000; // 2秒冷却时间
void _color(int a) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
}
struct item {
int color;
string appe;
string name;
int maxStack = 999999; // 无限堆叠
} block[100];
void init() {
// 空气 - 主世界为蓝色,下界为红色
block[0].appe = " ";
block[0].color = 144; // 主世界天空颜色
block[0].name = "Air";
// 石头和矿石
block[1].appe = "██";
block[1].color = 8;
block[1].name = "Stone";
block[2].appe = " ̄";
block[2].color = 47;
block[2].name = "Grass";
block[3].appe = " ";
block[3].color = 111;
block[3].name = "Dirt";
block[4].appe = "||";
block[4].color = 96;
block[4].name = "Wood";
block[5].appe = "◆◆";
block[5].color = 14;
block[5].name = "Coal Ore";
block[6].appe = "◆◆";
block[6].color = 8;
block[6].name = "Iron Ore";
block[7].appe = "==";
block[7].color = 1;
block[7].name = "Bedrock";
block[8].appe = "◆◆";
block[8].color = 15;
block[8].name = "Gold Ore";
block[9].appe = "◆◆";
block[9].color = 11;
block[9].name = "Diamond Ore";
block[10].appe = "◆◆";
block[10].color = 12;
block[10].name = "Redstone Ore";
block[11].appe = "◆◆";
block[11].color = 13;
block[11].name = "Emerald Ore";
block[12].appe = "◆◆";
block[12].color = 10;
block[12].name = "Copper Ore";
block[13].appe = "██";
block[13].color = 7;
block[13].name = "Cobblestone";
block[14].appe = "██";
block[14].color = 6;
block[14].name = "Bricks";
block[15].appe = "□";
block[15].color = 8;
block[15].name = "Gravel";
block[16].appe = "??";
block[16].color = 143;
block[16].name = "Sand";
block[17].appe = "※";
block[17].color = 15;
block[17].name = "Sandstone";
block[18].appe = "▓▓";
block[18].color = 10;
block[18].name = "Leaves";
block[19].appe = "██";
block[19].color = 130;
block[19].name = "Planks";
block[20].appe = "██";
block[20].color = 136;
block[20].name = "Stone Bricks";
block[21].appe = "~~";
block[21].color = 9;
block[21].name = "Water";
block[21].maxStack = 9999;
block[22].appe = "~~";
block[22].color = 12;
block[22].name = "Lava";
block[22].maxStack = 9999;
block[23].appe = "-=";
block[23].color = 15;
block[23].name = "Glass";
block[24].appe = "##";
block[24].color = 14;
block[24].name = "Glowstone";
block[25].appe = "██";
block[25].color = 112;
block[25].name = "Snow";
block[26].appe = "██";
block[26].color = 159;
block[26].name = "Ice";
block[27].appe = "██";
block[27].color = 42;
block[27].name = "Mossy Cobble";
block[28].appe = "██";
block[28].color = 124;
block[28].name = "Netherrack";
block[29].appe = "██";
block[29].color = 128;
block[29].name = "Soul Sand";
block[30].appe = "██";
block[30].color = 192;
block[30].name = "Nether Brick";
// 新增方块
block[31].appe = "FL";
block[31].color = 8;
block[31].name = "Flint and Steel";
block[31].maxStack = 1;
block[32].appe = "██";
block[32].color = 5;
block[32].name = "Obsidian";
block[33].appe = "##";
block[33].color = 13;
block[33].name = "Nether Portal";
block[33].maxStack = 0;
block[34].appe = "**";
block[34].color = 12;
block[34].name = "Fire";
block[34].maxStack = 0;
// 下界石英矿
block[35].appe = "◆◆";
block[35].color = 15;
block[35].name = "Nether Quartz";
// 下界金矿
block[36].appe = "◆◆";
block[36].color = 14;
block[36].name = "Nether Gold";
// 下界空气(浅红色)
block[37].appe = " ";
block[37].color = 204; // 红色背景
block[37].name = "Nether Air";
// 下界蘑菇
block[38].appe = "MM";
block[38].color = 13;
block[38].name = "Nether Mushroom";
// 岩浆块
block[39].appe = "MM";
block[39].color = 12;
block[39].name = "Magma Block";
// 初始化物品栏为空
for(int i = 0; i < 10; i++) {
inventory[i] = 0;
inventoryCount[i] = 0;
}
}
void print(int id) {
if(id >= 0 && id < 100 && block[id].color >= 0) {
_color(block[id].color);
printf("%s", block[id].appe.c_str());
} else {
_color(15);
printf(" ");
}
}
// ==================== 函数声明 ====================
bool checkNetherPortalOverworld(int x, int y);
bool checkNetherPortalNether(int x, int y);
void activateNetherPortalOverworld(int x, int y);
void activateNetherPortalNether(int x, int y);
void useFlintAndSteel(int x, int y);
void enterNether();
void returnToOverworld();
void generateNether();
void checkAndEnterPortal();
int ran(int x);
void spawn_tree(int x);
void generateWater();
void maps();
void showHotbar();
void showCreativeInventory();
void showInventoryMenu();
void addToInventory(int blockId);
void placeBlock();
bool worldExists(string filename);
void saveGame();
void loadGame(string filename);
void getSavedWorlds();
void screen();
void setting();
void showMainMenu();
void showNewWorldMenu();
void showLoadWorldMenu();
// ==================== 下界传送门相关代码 ====================
// 检查下界传送门框架(下界版本)
bool checkNetherPortalNether(int x, int y) {
if(x < 1 || x > 597 || y < 1 || y > 296) return false;
// 检查最小下界门尺寸:4×5框架,中间2×3为空
// 检查两侧柱子(5格高)
for(int i = 0; i < 5; i++) {
// 左侧柱子
if(netherWorld[y + i][x] != 32) return false;
// 右侧柱子
if(netherWorld[y + i][x + 3] != 32) return false;
}
// 检查顶部和底部(4格宽)
for(int i = 0; i < 4; i++) {
// 顶部
if(netherWorld[y][x + i] != 32) return false;
// 底部
if(netherWorld[y + 4][x + i] != 32) return false;
}
// 中间2×3区域必须是空的
for(int i = 1; i <= 2; i++) {
for(int j = 1; j <= 3; j++) {
if(netherWorld[y + j][x + i] != 0 && netherWorld[y + j][x + i] != 37) return false;
}
}
return true;
}
// 激活下界传送门(下界版本)
void activateNetherPortalNether(int x, int y) {
for(int i = 1; i <= 2; i++) {
for(int j = 1; j <= 3; j++) {
netherWorld[y + j][x + i] = 33; // 下界传送门方块
}
}
}
// 使用打火石
void useFlintAndSteel(int x, int y) {
if(inventory[currentBlock] != 31) return; // 确保当前选中的是打火石
if(!inNether) {
// 在主世界使用打火石
if(world[y][x] == 32) {
// 检查以当前点击位置为可能的传送门角落
for(int offsetX = -3; offsetX <= 0; offsetX++) {
for(int offsetY = -4; offsetY <= 0; offsetY++) {
int portalX = x + offsetX;
int portalY = y + offsetY;
if(portalX >= 1 && portalX <= 597 && portalY >= 1 && portalY <= 296) {
if(checkNetherPortalOverworld(portalX, portalY)) {
activateNetherPortalOverworld(portalX, portalY);
_color(10);
printf("Nether Portal Activated!\n");
Sleep(500);
return;
}
}
}
}
// 如果不是传送门框架,点火
world[y][x] = 34;
_color(12);
printf("Fire!\n");
Sleep(200);
}
} else {
// 在下界使用打火石
if(netherWorld[y][x] == 32) {
for(int offsetX = -3; offsetX <= 0; offsetX++) {
for(int offsetY = -4; offsetY <= 0; offsetY++) {
int portalX = x + offsetX;
int portalY = y + offsetY;
if(portalX >= 1 && portalX <= 597 && portalY >= 1 && portalY <= 296) {
if(checkNetherPortalNether(portalX, portalY)) {
activateNetherPortalNether(portalX, portalY);
_color(10);
printf("Nether Portal Activated!\n");
Sleep(500);
return;
}
}
}
}
// 如果不是传送门框架,点火
netherWorld[y][x] = 34;
_color(12);
printf("Fire!\n");
Sleep(200);
}
}
}
// 检查是否在传送门中并进入下界/返回主世界
void checkAndEnterPortal() {
// 检查传送门冷却时间
DWORD currentTime = GetTickCount();
if(currentTime - lastPortalTime < PORTAL_COOLDOWN) {
return;
}
if(!inNether) {
// 在主世界,检查是否站在传送门方块上
if(world[y][x] == 33) {
lastPortalTime = currentTime;
enterNether();
}
} else {
// 在下界,检查是否站在传送门方块上
if(netherWorld[y][x] == 33) {
lastPortalTime = currentTime;
returnToOverworld();
}
}
}
// 进入下界
void enterNether() {
if(inNether) return;
inNether = true;
gameState = NETHER_DIMENSION;
lastStateChangeTime = GetTickCount();
_color(12);
printf("Entering the Nether...\n");
Sleep(1000);
// 如果下界世界为空,生成下界
bool netherEmpty = true;
for(int i = 1; i <= 300; i++) {
for(int j = 1; j <= 600; j++) {
if(netherWorld[i][j] != 0 && netherWorld[i][j] != 37) {
netherEmpty = false;
break;
}
}
if(!netherEmpty) break;
}
if(netherEmpty) {
generateNether();
}
// 在对应的位置生成传送门(保持坐标对应)
int portalX = min(max(x, 2), 597);
int portalY = min(max(y, 2), 296);
// 确保不会超出边界
if(portalX > 597) portalX = 597;
if(portalX < 1) portalX = 1;
// 创建黑曜石框架
for(int i = 0; i < 5; i++) {
netherWorld[portalY + i][portalX] = 32;
netherWorld[portalY + i][portalX + 3] = 32;
}
for(int i = 0; i < 4; i++) {
netherWorld[portalY][portalX + i] = 32;
netherWorld[portalY + 4][portalX + i] = 32;
}
// 创建传送门
for(int i = 1; i <= 2; i++) {
for(int j = 1; j <= 3; j++) {
netherWorld[portalY + j][portalX + i] = 33;
}
}
// 设置玩家位置在传送门中间
x = portalX + 1;
y = portalY + 2;
}
// 返回主世界
void returnToOverworld() {
if(!inNether) return;
inNether = false;
gameState = IN_GAME;
lastStateChangeTime = GetTickCount();
_color(11);
printf("Returning to Overworld...\n");
Sleep(1000);
// 转换到主世界坐标
int portalX = min(max(x, 2), 597);
int portalY = min(max(y, 2), 296);
// 确保传送门存在,如果不存在就创建
if(!checkNetherPortalOverworld(portalX, portalY)) {
// 创建黑曜石框架
for(int i = 0; i < 5; i++) {
world[portalY + i][portalX] = 32;
world[portalY + i][portalX + 3] = 32;
}
for(int i = 0; i < 4; i++) {
world[portalY][portalX + i] = 32;
world[portalY + 4][portalX + i] = 32;
}
}
// 激活传送门
activateNetherPortalOverworld(portalX, portalY);
// 设置玩家位置在传送门中间
x = portalX + 1;
y = portalY + 2;
}
// 生成下界世界(改进版,更符合Minecraft原版)
void generateNether() {
memset(netherWorld, 0, sizeof(netherWorld));
// 1. 生成顶部和底部的基岩层
for(int j = 1; j <= 600; j++) {
netherWorld[1][j] = 7; // 顶部基岩
netherWorld[300][j] = 7; // 底部基岩
// 生成一些额外的基岩层,使基岩层更厚
if(j % 10 == 0) {
netherWorld[2][j] = 7;
netherWorld[299][j] = 7;
}
}
// 2. 生成主要的下界岩地形
// 使用Perlin噪声类似的方法生成地形
int heightMap[601];
int noise = 0;
// 初始化高度图
heightMap[1] = 50 + rand() % 50;
for(int j = 2; j <= 600; j++) {
int change = rand() % 3 - 1; // -1, 0, 1
heightMap[j] = max(10, min(200, heightMap[j-1] + change * (rand() % 3 + 1)));
}
// 平滑高度图
for(int j = 2; j < 600; j++) {
heightMap[j] = (heightMap[j-1] + heightMap[j] + heightMap[j+1]) / 3;
}
// 3. 填充下界岩
for(int j = 1; j <= 600; j++) {
int groundHeight = heightMap[j];
int ceilingHeight = groundHeight - 80 + rand() % 40; // 天花板高度,形成洞穴
for(int i = 2; i <= 299; i++) {
if(i <= ceilingHeight) {
// 洞穴上方的空气
netherWorld[i][j] = 37;
} else if(i <= groundHeight) {
// 下界岩主体
netherWorld[i][j] = 28;
} else {
// 地面下方的空气
netherWorld[i][j] = 37;
}
}
}
// 4. 生成熔岩海(在Y=200附近)
int lavaSeaLevel = 200;
for(int j = 1; j <= 600; j++) {
for(int i = lavaSeaLevel - 5; i <= lavaSeaLevel + 5; i++) {
if(i >= 2 && i <= 299 && netherWorld[i][j] == 28) {
netherWorld[i][j] = 22; // 熔岩
}
}
}
// 5. 生成矿洞
for(int cave = 0; cave < 15; cave++) {
int cave_x = rand() % 600 + 1;
int cave_y = 100 + rand() % 100;
int cave_size = rand() % 20 + 10;
for(int i = -cave_size; i <= cave_size; i++) {
for(int jj = -cave_size; jj <= cave_size; jj++) {
if(i*i + jj*jj <= cave_size*cave_size) {
int nx = cave_x + i;
int ny = cave_y + jj;
if(nx >= 1 && nx <= 600 && ny >= 2 && ny <= 299) {
if(netherWorld[ny][nx] == 28) {
netherWorld[ny][nx] = 37;
}
}
}
}
}
}
// 6. 生成倒挂的萤石(在洞穴顶部)
for(int j = 1; j <= 600; j++) {
for(int i = 2; i <= 299; i++) {
if(netherWorld[i][j] == 37 && netherWorld[i-1][j] == 28) {
// 这是洞穴的顶部
if(rand() % 100 < 2) { // 2%几率生成萤石
int glowstoneHeight = rand() % 5 + 1;
for(int k = 0; k < glowstoneHeight; k++) {
if(i + k <= 299 && netherWorld[i + k][j] == 37) {
netherWorld[i + k][j] = 24;
}
}
}
}
}
}
// 7. 生成蘑菇群落
for(int mushroom = 0; mushroom < 30; mushroom++) {
int mush_x = rand() % 600 + 1;
int mush_y = 0;
// 找到地面
for(int i = 2; i <= 299; i++) {
if(netherWorld[i][mush_x] == 28 && netherWorld[i+1][mush_x] == 37) {
mush_y = i + 1;
break;
}
}
if(mush_y > 0 && mush_y <= 299) {
int mush_size = rand() % 5 + 3;
for(int i = -mush_size; i <= mush_size; i++) {
for(int jj = -mush_size; jj <= mush_size; jj++) {
if(i*i + jj*jj <= mush_size*mush_size) {
int nx = mush_x + i;
int ny = mush_y + jj;
if(nx >= 1 && nx <= 600 && ny >= 2 && ny <= 299) {
if(netherWorld[ny][nx] == 37 && rand() % 3 == 0) {
netherWorld[ny][nx] = 38; // 下界蘑菇
}
}
}
}
}
}
}
// 8. 随机分布的沙砾和灵魂沙
for(int j = 1; j <= 600; j++) {
for(int i = 2; i <= 299; i++) {
if(netherWorld[i][j] == 28) {
// 随机生成沙砾
if(rand() % 100 < 3) {
netherWorld[i][j] = 15;
}
// 随机生成灵魂沙(通常在地面附近)
if(i > 150 && rand() % 100 < 5) {
netherWorld[i][j] = 29;
}
}
}
}
// 9. 生成岩浆块(靠近熔岩海)
for(int j = 1; j <= 600; j++) {
for(int i = lavaSeaLevel - 10; i <= lavaSeaLevel + 10; i++) {
if(i >= 2 && i <= 299 && netherWorld[i][j] == 28) {
if(rand() % 100 < 8) {
netherWorld[i][j] = 39; // 岩浆块
}
}
}
}
// 10. 生成下界石英矿(随机散布)
int quartzCount = 200;
for(int q = 0; q < quartzCount; q++) {
int qx = rand() % 600 + 1;
int qy = 50 + rand() % 200;
if(qx >= 1 && qx <= 600 && qy >= 2 && qy <= 299) {
if(netherWorld[qy][qx] == 28) {
netherWorld[qy][qx] = 35; // 下界石英矿
// 有时生成石英矿脉
if(rand() % 3 == 0) {
int veinSize = rand() % 3 + 1;
for(int dx = -veinSize; dx <= veinSize; dx++) {
for(int dy = -veinSize; dy <= veinSize; dy++) {
if(abs(dx) + abs(dy) <= veinSize) {
int nx = qx + dx;
int ny = qy + dy;
if(nx >= 1 && nx <= 600 && ny >= 2 && ny <= 299) {
if(netherWorld[ny][nx] == 28) {
netherWorld[ny][nx] = 35;
}
}
}
}
}
}
}
}
}
// 11. 生成下界金矿(在坑洞、地表或熔岩海下)
int goldCount = 100;
for(int g = 0; g < goldCount; g++) {
int gx = rand() % 600 + 1;
int gy = 0;
// 随机选择生成位置类型
int locationType = rand() % 3;
if(locationType == 0) {
// 在坑洞中
for(int i = 100; i <= 250; i++) {
if(netherWorld[i][gx] == 37 && netherWorld[i+1][gx] == 28) {
gy = i;
break;
}
}
} else if(locationType == 1) {
// 在地表
for(int i = 2; i <= 299; i++) {
if(netherWorld[i][gx] == 28 && netherWorld[i+1][gx] == 37) {
gy = i;
break;
}
}
} else {
// 在熔岩海下
gy = lavaSeaLevel - (rand() % 10 + 5);
}
if(gy > 0 && gy <= 299 && netherWorld[gy][gx] == 28) {
netherWorld[gy][gx] = 36; // 下界金矿
// 有时生成金矿脉
if(rand() % 2 == 0) {
int veinSize = rand() % 2 + 1;
for(int dx = -veinSize; dx <= veinSize; dx++) {
for(int dy = -veinSize; dy <= veinSize; dy++) {
if(abs(dx) + abs(dy) <= veinSize) {
int nx = gx + dx;
int ny = gy + dy;
if(nx >= 1 && nx <= 600 && ny >= 2 && ny <= 299) {
if(netherWorld[ny][nx] == 28) {
netherWorld[ny][nx] = 36;
}
}
}
}
}
}
}
}
// 12. 生成地狱砖结构
for(int structure = 0; structure < 10; structure++) {
int sx = rand() % 600 + 1;
int sy = 0;
// 找到地面
for(int i = 2; i <= 299; i++) {
if(netherWorld[i][sx] == 28 && netherWorld[i+1][sx] == 37) {
sy = i;
break;
}
}
if(sy > 0 && sy <= 299) {
int structureHeight = rand() % 10 + 5;
int structureWidth = rand() % 8 + 4;
for(int i = 0; i < structureHeight; i++) {
for(int jj = -structureWidth/2; jj <= structureWidth/2; jj++) {
int nx = sx + jj;
int ny = sy - i;
if(nx >= 1 && nx <= 600 && ny >= 2 && ny <= 299) {
if(i == 0 || i == structureHeight-1 || jj == -structureWidth/2 || jj == structureWidth/2) {
if(rand() % 3 == 0) {
netherWorld[ny][nx] = 30; // 地狱砖
}
}
}
}
}
}
}
}
// 检查下界传送门框架(主世界版本)
bool checkNetherPortalOverworld(int x, int y) {
if(x < 1 || x > 597 || y < 1 || y > 296) return false;
// 检查最小下界门尺寸:4×5框架,中间2×3为空
// 检查两侧柱子(5格高)
for(int i = 0; i < 5; i++) {
// 左侧柱子
if(world[y + i][x] != 32) return false;
// 右侧柱子
if(world[y + i][x + 3] != 32) return false;
}
// 检查顶部和底部(4格宽)
for(int i = 0; i < 4; i++) {
// 顶部
if(world[y][x + i] != 32) return false;
// 底部
if(world[y + 4][x + i] != 32) return false;
}
// 中间2×3区域必须是空的
for(int i = 1; i <= 2; i++) {
for(int j = 1; j <= 3; j++) {
if(world[y + j][x + i] != 0) return false;
}
}
return true;
}
// 激活下界传送门(主世界版本)
void activateNetherPortalOverworld(int x, int y) {
for(int i = 1; i <= 2; i++) {
for(int j = 1; j <= 3; j++) {
world[y + j][x + i] = 33; // 下界传送门方块
}
}
}
int ran(int x) {
int a = 50;
for (int i = 1; i <= x; i++) {
a = rand();
}
return a;
}
void spawn_tree(int x){
int height=ran(x)%3+4;
int treesize=1+(ran(x)%4);
int i,j;
if(grass[x]-2*treesize-height-1>=0){
for(i=1;i<=height;i++){
world[grass[x]-i][x]=4;
}
for(i=grass[x]-2*treesize-height-1;i<grass[x]-height;i++){
for(j=x-treesize;j<=x+treesize;j++){
world[i][j]=18;
}
}
}
}
// 改进的水生成算法
void generateWater() {
vector<pair<int, int>> lowPoints;
// 找到山谷
for(int j = 2; j < 600; j++) {
if(grass[j] > grass[j-1] && grass[j] > grass[j+1]) {
int valleyDepth = min(grass[j] - grass[j-1], grass[j] - grass[j+1]);
if(valleyDepth >= 3) {
lowPoints.push_back({j, grass[j]});
}
}
}
// 在低点生成水
for(auto& point : lowPoints) {
int startX = point.first;
int waterLevel = point.second + 1;
// 扩展水面
int leftX = startX;
while(leftX > 1 && grass[leftX] <= waterLevel) {
leftX--;
}
int rightX = startX;
while(rightX < 600 && grass[rightX] <= waterLevel) {
rightX++;
}
waterLevel = min(waterLevel, grass[startX] + 5);
// 填充水
for(int xx = leftX; xx <= rightX; xx++) {
for(int yy = waterLevel; yy <= waterLevel + 3; yy++) {
if(yy <= 300 && world[yy][xx] == 0) {
world[yy][xx] = 21;
}
}
}
}
}
void maps() {
int i, j, k;
// 生成地形高度
grass[1] = ran(seed) % 15 + 20;
for (k = 2; k <= 600; k++) {
int r = ran(seed + k - 1) % 3;
if (r == 0) grass[k] = grass[k - 1] + 1;
else if (r == 1) grass[k] = grass[k - 1] - 1;
else grass[k] = grass[k - 1];
// 确保高度在合理范围内
if(grass[k] < 10) grass[k] = 10;
if(grass[k] > 50) grass[k] = 50;
}
// 生成世界
for (j = 1; j <= 600; j++) {
// 空气层
for (i = 1; i < grass[j]; i++) {
world[i][j] = 0;
}
// 草皮层
world[grass[j]][j] = 2;
// 泥土层
for (i = grass[j] + 1; i <= grass[j] + 10; i++) {
if(i <= 300) world[i][j] = 3;
}
// 石头层
for (i = grass[j] + 11; i <= 299; i++) {
if(i <= 300) world[i][j] = 1;
}
// 基岩层
world[300][j] = 7;
}
// 生成水
generateWater();
// 生成矿洞
for (int cave = 0; cave < 40; cave++) {
int cave_x = ran(seed + cave * 100) % 600 + 1;
int cave_y = ran(seed + cave * 200) % 100 + grass[cave_x] + 15;
int cave_size = ran(seed + cave * 300) % 10 + 5;
for (int i = -cave_size; i <= cave_size; i++) {
for (int jj = -cave_size; jj <= cave_size; jj++) {
if (i*i + jj*jj <= cave_size*cave_size) {
int nx = cave_x + i;
int ny = cave_y + jj;
if (nx >= 1 && nx <= 600 && ny >= 1 && ny <= 300) {
if (world[ny][nx] == 1) world[ny][nx] = 0;
}
}
}
}
}
// 生成树
for(i = 7; i <= 593; i++){
if(ran(grass[i]) % 11 == 8){
spawn_tree(i);
}
}
}
void showHotbar() {
_color(15);
printf("\n");
// 显示物品栏
for(int i = 0; i < 10; i++) {
if(i == currentBlock) {
_color(240); // 白色背景,黑色文字
} else {
_color(15); // 黑色背景,白色文字
}
printf("[");
if(inventory[i] > 0 && inventoryCount[i] > 0) {
print(inventory[i]);
_color(15);
} else {
printf(" ");
_color(15);
}
printf("] ");
}
// 显示当前选中方块信息
_color(14);
printf(" Selected: ");
if(inventory[currentBlock] > 0 && inventoryCount[currentBlock] > 0) {
print(inventory[currentBlock]);
_color(14);
printf(" %s", block[inventory[currentBlock]].name.c_str());
} else {
printf("Empty");
}
}
// 显示创造模式物品栏
void showCreativeInventory() {
system("cls");
lastStateChangeTime = GetTickCount();
int creativeItems[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,31,32,35,36,38,39};
int itemCount = 36;
while(true) {
// 检查是否允许操作
if(GetTickCount() - lastStateChangeTime < STATE_CHANGE_DELAY) {
Sleep(100);
continue;
}
system("cls");
_color(14);
printf("=== CREATIVE INVENTORY ===\n");
_color(15);
printf("WASD: Move Space: Select ESC: Back\n\n");
// 显示所有物品
for(int i = 0; i < itemCount; i++) {
if(i == creativeSelection) {
_color(240); // 选中状态
} else {
_color(15);
}
printf("%02d. ", i+1);
print(creativeItems[i]);
printf(" %s", block[creativeItems[i]].name.c_str());
if(i == creativeSelection) printf(" <--");
printf("\n");
}
// 控制
if(key('W') && creativeSelection > 0) {
creativeSelection--;
Sleep(150);
}
if(key('S') && creativeSelection < itemCount-1) {
creativeSelection++;
Sleep(150);
}
if(key(VK_SPACE)) {
// 将物品添加到当前选中的快捷栏槽位
if(currentBlock >= 0 && currentBlock < 10) {
inventory[currentBlock] = creativeItems[creativeSelection];
inventoryCount[currentBlock] = 9999; // 无限数量
return;
}
}
if(key(VK_ESCAPE)) {
return;
}
Sleep(50);
}
}
// 显示物品栏界面
void showInventoryMenu() {
system("cls");
lastStateChangeTime = GetTickCount();
while(true) {
// 检查是否允许操作
if(GetTickCount() - lastStateChangeTime < STATE_CHANGE_DELAY) {
Sleep(100);
continue;
}
system("cls");
_color(14);
printf("=== INVENTORY ===\n");
_color(15);
printf("WASD: Move Space: Select/Exchange ESC: Exit\n\n");
// 显示物品栏槽位
for(int i = 0; i < 10; i++) {
if(i == inventorySelection) {
_color(240); // 选中状态
} else {
_color(15);
}
printf("Slot %d: ", i);
if(inventory[i] > 0 && inventoryCount[i] > 0) {
print(inventory[i]);
_color(i == inventorySelection ? 240 : 15);
printf(" %s ", block[inventory[i]].name.c_str());
} else {
printf("Empty");
}
if(i == currentBlock) printf(" [HOTBAR]");
if(isSelectingItem && selectedSlot == i) printf(" [SELECTED]");
printf("\n");
}
// 创造模式物品栏按钮
printf("\n");
if(inventorySelection == 10) {
_color(240);
printf("> Creative Menu <\n");
_color(15);
} else {
printf(" Creative Menu\n");
}
// 控制
if(key('W') && inventorySelection > 0) {
inventorySelection--;
Sleep(150);
}
if(key('S') && inventorySelection < 10) { // 10是创造模式菜单
inventorySelection++;
Sleep(150);
}
if(key(VK_SPACE)) {
if(inventorySelection == 10) {
// 打开创造模式物品栏
showCreativeInventory();
inventorySelection = 0;
} else {
if(!isSelectingItem) {
// 第一次选择
isSelectingItem = true;
selectedSlot = inventorySelection;
} else {
// 第二次选择,交换物品
if(selectedSlot != inventorySelection) {
// 交换物品
swap(inventory[selectedSlot], inventory[inventorySelection]);
swap(inventoryCount[selectedSlot], inventoryCount[inventorySelection]);
}
isSelectingItem = false;
selectedSlot = -1;
}
}
}
if(key(VK_ESCAPE)) {
isSelectingItem = false;
selectedSlot = -1;
return;
}
Sleep(50);
}
}
void addToInventory(int blockId) {
if(blockId == 0 || blockId == 7 || blockId == 33 || blockId == 34 || blockId == 37) return;
// 查找是否已有该方块
for(int i = 0; i < 10; i++) {
if(inventory[i] == blockId && inventoryCount[i] < 9999) {
inventoryCount[i]++;
return;
}
}
// 查找空槽位
for(int i = 0; i < 10; i++) {
if(inventory[i] == 0) {
inventory[i] = blockId;
inventoryCount[i] = 1;
return;
}
}
}
void placeBlock() {
if(inventory[currentBlock] > 0 && inventoryCount[currentBlock] > 0) {
if(!inNether) {
if(world[y][x] == 0 || world[y][x] == 21 || world[y][x] == 22) {
world[y][x] = inventory[currentBlock];
}
} else {
if(netherWorld[y][x] == 0 || netherWorld[y][x] == 21 || netherWorld[y][x] == 22 || netherWorld[y][x] == 37) {
netherWorld[y][x] = inventory[currentBlock];
}
}
}
}
bool worldExists(string filename) {
string path = "saves/" + filename + ".dat";
struct stat buffer;
return (stat(path.c_str(), &buffer) == 0);
}
void saveGame() {
// 创建saves文件夹
_mkdir("saves");
string path = "saves/" + worldName + ".dat";
// 检查世界是否已存在
if(worldExists(worldName) && worldName != "quicksave") {
_color(12);
printf("World name already exists!\n");
Sleep(1000);
return;
}
// 打开文件
ofstream file(path.c_str(), ios::binary);
if(!file.is_open()) {
_color(12);
printf("Failed to create save file!\n");
Sleep(1000);
return;
}
// 保存基本信息
file.write((char*)&seed, sizeof(int));
file.write((char*)&x, sizeof(int));
file.write((char*)&y, sizeof(int));
file.write((char*)&inNether, sizeof(bool));
file.write((char*)&isCreativeMode, sizeof(bool));
// 保存主世界数据
for(int i = 0; i <= 300; i++) {
file.write((char*)&world[i][0], 601 * sizeof(int));
}
// 保存下界世界数据
for(int i = 0; i <= 300; i++) {
file.write((char*)&netherWorld[i][0], 601 * sizeof(int));
}
// 保存物品栏
file.write((char*)inventory, 10 * sizeof(int));
file.write((char*)inventoryCount, 10 * sizeof(int));
file.close();
_color(10);
printf("Game saved to %s\n", path.c_str());
Sleep(1000);
}
void loadGame(string filename) {
string path = "saves/" + filename + ".dat";
// 检查文件是否存在
if(!worldExists(filename)) {
_color(12);
printf("Save file not found: %s\n", path.c_str());
Sleep(1000);
return;
}
// 打开文件
ifstream file(path.c_str(), ios::binary);
if(!file.is_open()) {
_color(12);
printf("Failed to open save file!\n");
Sleep(1000);
return;
}
// 读取基本信息
file.read((char*)&seed, sizeof(int));
file.read((char*)&x, sizeof(int));
file.read((char*)&y, sizeof(int));
file.read((char*)&inNether, sizeof(bool));
file.read((char*)&isCreativeMode, sizeof(bool));
// 读取主世界数据
for(int i = 0; i <= 300; i++) {
file.read((char*)&world[i][0], 601 * sizeof(int));
}
// 读取下界世界数据
for(int i = 0; i <= 300; i++) {
file.read((char*)&netherWorld[i][0], 601 * sizeof(int));
}
// 读取物品栏
file.read((char*)inventory, 10 * sizeof(int));
file.read((char*)inventoryCount, 10 * sizeof(int));
file.close();
worldName = filename;
_color(10);
printf("Game loaded from %s\n", path.c_str());
Sleep(1000);
}
// 获取所有保存的世界
void getSavedWorlds() {
savedWorlds.clear();
// 检查saves文件夹是否存在
struct stat info;
if(stat("saves", &info) != 0) {
_mkdir("saves");
return;
}
// 遍历saves文件夹
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile("saves\\*.dat", &findFileData);
if(hFind != INVALID_HANDLE_VALUE) {
do {
string filename = findFileData.cFileName;
filename = filename.substr(0, filename.length() - 4); // 去掉.dat扩展名
savedWorlds.push_back(filename);
} while(FindNextFile(hFind, &findFileData) != 0);
FindClose(hFind);
}
}
void screen() {
int i, j;
// 根据维度选择要渲染的世界
int (*currentWorld)[601] = inNether ? netherWorld : world;
// 计算渲染范围
int startY = max(1, y - render);
int endY = min(300, y + render);
int startX = max(1, x - render);
int endX = min(600, x + render);
// 渲染世界
for (i = startY; i <= endY; i++) {
for (j = startX; j <= endX; j++) {
if (i == y && j == x) {
_color(11);
printf("[]");
} else {
// 如果在下界且是空气方块,使用下界空气的颜色
if(inNether && currentWorld[i][j] == 0) {
print(37); // 下界空气
} else {
print(currentWorld[i][j]);
}
}
}
printf("\n");
}
// 显示信息
_color(14);
printf("POS X:%d Y:%d ", x, y);
_color(10);
printf("FPS:%d ", 1000/fps);
_color(11);
printf("Render:%d ", render);
// 显示当前维度
if(inNether) {
_color(12);
printf("NETHER ");
} else {
_color(11);
printf("OVERWORLD ");
}
// 显示世界名称
_color(14);
if(!worldName.empty()) {
printf("World: %s", worldName.c_str());
}
showHotbar();
// 显示帮助提示
_color(8);
printf("\nE:Inventory P:Settings F5:Save F6:Load ESC:Menu");
}
void setting() {
int op = 0;
int newfps = fps, newrender = render;
system("cls");
lastStateChangeTime = GetTickCount();
while (true) {
// 检查是否允许操作
if(GetTickCount() - lastStateChangeTime < STATE_CHANGE_DELAY) {
Sleep(100);
continue;
}
system("cls");
_color(15);
printf("### Settings ###\n\n");
// 显示选项
for(int i = 0; i < 5; i++) {
if(i == op) {
_color(240); // 选中状态
} else {
_color(15);
}
switch(i) {
case 0:
printf("> Frame Rate: ");
if(newfps == 200) printf("[5fps] 10fps 50fps");
else if(newfps == 100) printf("5fps [10fps] 50fps");
else printf("5fps 10fps [50fps]");
break;
case 1:
printf("> Render Distance: ");
if(newrender == 5) printf("[5] 10 15");
else if(newrender == 10) printf("5 [10] 15");
else printf("5 10 [15]");
break;
case 2:
printf("> Save Game");
break;
case 3:
printf("> Load Game");
break;
case 4:
printf("> Back to Game");
break;
}
printf("\n");
}
_color(8);
printf("\nWASD: Navigate Space: Select D: Change value\n");
// 控制
if(key('W') && op > 0) {
op--;
Sleep(150);
}
if(key('S') && op < 4) {
op++;
Sleep(150);
}
if(key(VK_SPACE) || key('A')) {
switch(op) {
case 0: // 帧率
if(newfps == 200) newfps = 100;
else if(newfps == 100) newfps = 18;
else newfps = 200;
break;
case 1: // 渲染距离
if(newrender == 5) newrender = 10;
else if(newrender == 10) newrender = 15;
else newrender = 5;
break;
case 2: // 保存游戏
saveGame();
break;
case 3: // 加载游戏
gameState = LOAD_WORLD_MENU;
getSavedWorlds();
return;
case 4: // 返回游戏
fps = newfps;
render = newrender;
gameState = IN_GAME;
return;
}
Sleep(150);
}
if(key('D')) {
switch(op) {
case 0: // 帧率
if(newfps == 200) newfps = 100;
else if(newfps == 100) newfps = 18;
else newfps = 200;
break;
case 1: // 渲染距离
if(newrender == 5) newrender = 10;
else if(newrender == 10) newrender = 15;
else newrender = 5;
break;
}
Sleep(150);
}
if(key(VK_ESCAPE)) {
gameState = IN_GAME;
return;
}
Sleep(50);
}
}
void showMainMenu() {
menuSelection = 0;
system("cls");
lastStateChangeTime = GetTickCount();
while(gameState == MAIN_MENU) {
// 检查是否允许操作
if(GetTickCount() - lastStateChangeTime < STATE_CHANGE_DELAY) {
Sleep(100);
continue;
}
system("cls");
_color(14);
printf(" Paper Minecraft v3.0 \n");
_color(15);
printf(" Enhanced Edition \n\n");
// 显示菜单选项
string menuItems[] = {"New World", "Load World", "About", "Quit"};
for(int i = 0; i < 4; i++) {
if(i == menuSelection) {
_color(224);
printf(" > %s < \n", menuItems[i].c_str());
_color(15);
} else {
_color(15);
printf(" %s \n", menuItems[i].c_str());
}
}
_color(7);
printf("\nWASD: Navigate Space: Select\n");
// 控制
if(key('W') && menuSelection > 0) {
menuSelection--;
Sleep(200);
}
if(key('S') && menuSelection < 3) {
menuSelection++;
Sleep(200);
}
if(key(VK_SPACE)) {
switch(menuSelection) {
case 0: // New World
memset(worldNameInput, 0, sizeof(worldNameInput));
inputPos = 0;
gameState = NEW_WORLD_MENU;
lastStateChangeTime = GetTickCount();
return;
case 1: // Load World
gameState = LOAD_WORLD_MENU;
getSavedWorlds();
lastStateChangeTime = GetTickCount();
return;
case 2: // About
system("cls");
_color(14);
printf("\n\n About Paper Minecraft v3.0\n\n");
_color(15);
printf(" Enhanced Features:\n");
printf(" - Nether Dimension\n");
printf(" - Improved Water Generation\n");
printf(" - Enhanced Inventory System\n");
printf(" - World Management\n\n");
printf(" Controls:\n");
printf(" WASD - Move/Navigate menus\n");
printf(" Space - Select/Place block\n");
printf(" E - Open inventory\n");
printf(" X - Destroy block\n");
printf(" P - Settings\n");
printf(" F5 - Quick Save\n");
printf(" F6 - Quick Load\n");
printf(" ESC - Pause menu\n\n");
_color(9);
printf(" Press any key to continue...");
while(!_kbhit());
_getch();
break;
case 3: // Quit
exit(0);
}
Sleep(200);
}
Sleep(100);
}
}
void showNewWorldMenu() {
memset(worldNameInput, 0, sizeof(worldNameInput));
memset(seedInput, 0, sizeof(seedInput));
int currentInput = 0; // 0:世界名称, 1:种子
system("cls");
lastStateChangeTime = GetTickCount();
while(gameState == NEW_WORLD_MENU) {
// 检查是否允许操作
if(GetTickCount() - lastStateChangeTime < STATE_CHANGE_DELAY) {
Sleep(100);
continue;
}
system("cls");
_color(14);
printf("=== Create New World ===\n\n");
// 显示世界名称输入
_color(15);
printf("World Name: %s", worldNameInput);
if(currentInput == 0) printf("_");
printf("\n");
// 显示种子输入
_color(15);
printf("Seed (press Enter for random): %s", seedInput);
if(currentInput == 1) printf("_");
printf("\n\n");
_color(8);
printf("Press Enter to confirm input\n");
printf("Press ESC to go back\n");
// 处理键盘输入
if(_kbhit()) {
char ch = _getch();
if(ch == '\r' || ch == '\n') { // Enter键
if(currentInput == 0) {
// 检查世界名称是否为空
if(strlen(worldNameInput) == 0) {
_color(12);
printf("\nWorld name cannot be empty!\n");
Sleep(1000);
continue;
}
// 检查世界名称是否已存在
worldName = worldNameInput;
if(worldExists(worldName)) {
_color(12);
printf("\nWorld name already exists!\n");
Sleep(1000);
continue;
}
// 切换到种子输入
currentInput = 1;
} else if(currentInput == 1) {
// 处理种子
if(strlen(seedInput) > 0) {
seed = atoi(seedInput);
} else {
// 生成随机种子
seed = (time(NULL) + GetTickCount()) % 1000000;
sprintf(seedInput, "%d", seed);
}
printf("\nGenerating terrain...\n");
seed = abs(seed % 10001);
srand(seed);
// 初始化世界
memset(world, 0, sizeof(world));
memset(netherWorld, 0, sizeof(netherWorld));
memset(grass, 0, sizeof(grass));
init();
maps();
generateNether();
// 设置初始位置
x = 300;
y = grass[300] > 0 ? grass[300] - 1 : 150;
// 给创造模式初始物品
inventory[0] = 2; inventoryCount[0] = 999999; // 草方块
inventory[1] = 3; inventoryCount[1] = 999999; // 泥土
inventory[2] = 1; inventoryCount[2] = 999999; // 石头
inventory[3] = 32; inventoryCount[3] = 999999; // 黑曜石
inventory[4] = 31; inventoryCount[4] = 1; // 打火石
gameState = IN_GAME;
lastStateChangeTime = GetTickCount();
return;
}
} else if(ch == '\b') { // Backspace键
if(currentInput == 0 && strlen(worldNameInput) > 0) {
worldNameInput[strlen(worldNameInput)-1] = '\0';
} else if(currentInput == 1 && strlen(seedInput) > 0) {
seedInput[strlen(seedInput)-1] = '\0';
}
} else if(ch == 27) { // ESC键返回
gameState = MAIN_MENU;
lastStateChangeTime = GetTickCount();
return;
} else if(isprint(ch)) { // 可打印字符
if(currentInput == 0 && strlen(worldNameInput) < 49) {
int len = strlen(worldNameInput);
worldNameInput[len] = ch;
worldNameInput[len+1] = '\0';
} else if(currentInput == 1 && strlen(seedInput) < 19) {
// 确保输入的是数字
if(isdigit(ch) || ch == '-') {
int len = strlen(seedInput);
seedInput[len] = ch;
seedInput[len+1] = '\0';
}
}
}
}
Sleep(50);
}
}
void showLoadWorldMenu() {
worldSelection = 0;
system("cls");
lastStateChangeTime = GetTickCount();
while(gameState == LOAD_WORLD_MENU) {
// 检查是否允许操作
if(GetTickCount() - lastStateChangeTime < STATE_CHANGE_DELAY) {
Sleep(100);
continue;
}
system("cls");
_color(14);
printf("=== Load World ===\n\n");
if(savedWorlds.empty()) {
_color(15);
printf("No saved worlds found!\n\n");
} else {
// 显示世界列表
for(int i = 0; i < savedWorlds.size(); i++) {
if(i == worldSelection) {
_color(240);
printf("> %s <\n", savedWorlds[i].c_str());
_color(15);
} else {
printf(" %s\n", savedWorlds[i].c_str());
}
}
}
// Back按钮
printf("\n");
if(worldSelection == savedWorlds.size()) {
_color(240);
printf("> Back <\n");
_color(15);
} else {
printf(" Back\n");
}
_color(8);
printf("\nWASD: Navigate Space: Select ESC: Back\n");
// 控制
int totalItems = savedWorlds.size() + 1; // 世界列表 + Back按钮
if(key('W') && worldSelection > 0) {
worldSelection--;
Sleep(200);
}
if(key('S') && worldSelection < totalItems - 1) {
worldSelection++;
Sleep(200);
}
if(key(VK_SPACE)) {
if(worldSelection < savedWorlds.size()) {
loadGame(savedWorlds[worldSelection]);
gameState = IN_GAME;
lastStateChangeTime = GetTickCount();
return;
} else {
gameState = MAIN_MENU;
lastStateChangeTime = GetTickCount();
return;
}
}
if(key(VK_ESCAPE)) {
gameState = MAIN_MENU;
lastStateChangeTime = GetTickCount();
return;
}
Sleep(100);
}
}
int main() {
system("title Paper Minecraft v3.0 - Enhanced Edition");
system("mode con cols=130 lines=45");
srand(time(NULL));
init();
while(true) {
switch(gameState) {
case MAIN_MENU:
showMainMenu();
break;
case NEW_WORLD_MENU:
showNewWorldMenu();
break;
case LOAD_WORLD_MENU:
showLoadWorldMenu();
break;
case IN_GAME:
case NETHER_DIMENSION:
screen();
// 检查是否允许操作
if(GetTickCount() - lastStateChangeTime < STATE_CHANGE_DELAY) {
Sleep(fps);
system("cls");
break;
}
// 移动
if (key('W')) y--;
if (key('S')) y++;
if (key('A')) x--;
if (key('D')) x++;
// 边界检查
if (x > 600) x = 600;
if (x < 1) x = 1;
if (y > 300) y = 300;
if (y < 1) y = 1;
// 物品栏选择(数字键)
for(int i = 0; i < 10; i++) {
if(key('0' + i)) {
currentBlock = i;
}
}
// 破坏方块
if (key('X')) {
int destroyedBlock;
if(!inNether) {
destroyedBlock = world[y][x];
if(destroyedBlock != 0 && destroyedBlock != 7 && destroyedBlock != 33 && destroyedBlock != 34) {
world[y][x] = 0;
addToInventory(destroyedBlock);
}
} else {
destroyedBlock = netherWorld[y][x];
if(destroyedBlock != 0 && destroyedBlock != 7 && destroyedBlock != 33 && destroyedBlock != 34 && destroyedBlock != 37) {
netherWorld[y][x] = 37; // 下界空气
addToInventory(destroyedBlock);
}
}
}
// 放置方块或使用物品
if (key(VK_SPACE)) {
if(inventory[currentBlock] == 31) {
useFlintAndSteel(x, y);
} else {
placeBlock();
}
}
// 检查传送门
checkAndEnterPortal();
// 打开物品栏
if (key('E')) {
showInventoryMenu();
}
// 设置菜单
if (key('P')) {
setting();
}
// 快速保存/加载
if (key(VK_F5)) {
if(!worldName.empty()) {
saveGame();
}
}
if (key(VK_F6)) {
if(worldExists("quicksave")) {
loadGame("quicksave");
}
}
// ESC暂停菜单
if (key(VK_ESCAPE)) {
int pauseSelection = 0;
DWORD pauseStartTime = GetTickCount();
while(true) {
// 延迟防止误操作
if(GetTickCount() - pauseStartTime < 500) {
Sleep(100);
continue;
}
system("cls");
_color(14);
printf("=== Game Paused ===\n\n");
string pauseItems[] = {"Resume", "Save Game", "Load Game", "Settings", "Quit to Menu"};
for(int i = 0; i < 5; i++) {
if(i == pauseSelection) {
_color(240);
printf("> %s <\n", pauseItems[i].c_str());
_color(15);
} else {
printf(" %s\n", pauseItems[i].c_str());
}
}
_color(8);
printf("\nWASD: Navigate Space: Select\n");
if(key('W') && pauseSelection > 0) {
pauseSelection--;
Sleep(200);
}
if(key('S') && pauseSelection < 4) {
pauseSelection++;
Sleep(200);
}
if(key(VK_SPACE)) {
switch(pauseSelection) {
case 0: // Resume
break;
case 1: // Save Game
saveGame();
continue;
case 2: // Load Game
gameState = LOAD_WORLD_MENU;
getSavedWorlds();
lastStateChangeTime = GetTickCount();
break;
case 3: // Settings
setting();
break;
case 4: // Quit to Menu
gameState = MAIN_MENU;
lastStateChangeTime = GetTickCount();
break;
}
break;
}
if(key(VK_ESCAPE)) {
break;
}
Sleep(100);
}
}
Sleep(fps);
system("cls");
break;
}
}
return 0;
}