简易版2D我的世界C++程序(有点BUG,但是可以玩!!!)

1、按空格键来切换模式(挖掘模式和放置模式),一律用鼠标右键来操作!!! 2、按数字1和2键来切换放置的方块(1是草,2是木),树叶不能放置!!! 3、树木生成时可能有点BUG。 4、在操作时位置会有点偏移,请见谅。 5、地图默认大小为20*20,可以自己修改。(第15行和第16行) 6、本程序应该会持续更新

更新日志:

4月25日: 1、更新了新方块“石”,按数字3键切换(没错,树叶依然不可以放置) 2、石头会生成在草方块下面,会生成5层。 3、更改了地图的大小,为25*18。 4、操作偏移的bug依然存在(改了好几次,结果改的更离谱了)

#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include <windows.h>// 定义方块类型
typedef int BlockType;// 定义方块名称
const std::string BLOCK_NAMES[] = { "", "草", "木", "叶", "石" };// 定义世界的大小
const int WORLD_WIDTH = 25;
const int WORLD_HEIGHT = 18;// 定义世界地图
class World {
private:std::vector<std::vector<BlockType> > blocks;public:World() {blocks.resize(WORLD_HEIGHT);for (int y = 0; y < WORLD_HEIGHT; ++y) {blocks[y].resize(WORLD_WIDTH, 0);}generateTerrain();generateTrees();}// 生成简单地形void generateTerrain() {srand(static_cast<unsigned int>(time(NULL)));for (int x = 0; x < WORLD_WIDTH; ++x) {int height = rand() % 3 + 1;// 生成石头for (int y = WORLD_HEIGHT - 1; y >= WORLD_HEIGHT - 5; --y) {blocks[y][x] = 4;}// 生成草for (int y = WORLD_HEIGHT - 6; y >= WORLD_HEIGHT - 6 - height + 1; --y) {blocks[y][x] = 1;}}}// 生成树木void generateTrees() {for (int x = 0; x < WORLD_WIDTH; x += 5) { // 每隔 5 个方块尝试生成树木if (rand() % 2 == 0) { // 50% 的概率生成树木int baseY = WORLD_HEIGHT - 7; // 从可能的最上层草方块开始找while (baseY >= 0 && blocks[baseY][x] != 1) baseY--; // 找到最上层的草方块if (baseY > 0) {int treeHeight = rand() % 3 + 3; // 树高 3 - 5// 生成树干for (int i = 0; i < treeHeight; ++i) {if (baseY - i >= 0) {blocks[baseY - i][x] = 2;}}// 生成树叶int leafTop = baseY - treeHeight;for (int dy = -1; dy <= 1; ++dy) {for (int dx = -1; dx <= 1; ++dx) {if (leafTop + dy >= 0 && x + dx >= 0 && x + dx < WORLD_WIDTH) {blocks[leafTop + dy][x + dx] = 3;}}}}}}}// 放置方块void placeBlock(int x, int y, BlockType block) {if (x >= 0 && x < WORLD_WIDTH && y >= 0 && y < WORLD_HEIGHT) {blocks[y][x] = block;}}// 挖掘方块void digBlock(int x, int y) {if (x >= 0 && x < WORLD_WIDTH && y >= 0 && y < WORLD_HEIGHT) {blocks[y][x] = 0;}}// 查看方块BlockType getBlock(int x, int y) {if (x >= 0 && x < WORLD_WIDTH && y >= 0 && y < WORLD_HEIGHT) {return blocks[y][x];}return 0;}// 显示世界void display(HANDLE hOut) {COORD coord = { 0, 0 };SetConsoleCursorPosition(hOut, coord);for (int y = 0; y < WORLD_HEIGHT; ++y) {for (int x = 0; x < WORLD_WIDTH; ++x) {std::string blockName = BLOCK_NAMES[blocks[y][x]];if (blockName.empty()) {std::cout << "  ";} else {std::cout << blockName;if (blockName.length() == 1) {std::cout << " ";}}std::cout << " "; // 方块之间添加一个空格}std::cout << std::endl;}}
};// 获取鼠标点击的坐标并转换为地图坐标
void getMouseCoordinates(int& x, int& y) {POINT cursorPos;GetCursorPos(&cursorPos);HWND consoleWindow = GetConsoleWindow();RECT consoleRect;GetWindowRect(consoleWindow, &consoleRect);// 修正鼠标坐标转换,确保准确对应方块x = (cursorPos.x - consoleRect.left) / 25;y = (cursorPos.y - consoleRect.top) / 20;if (x < 0) x = 0;if (x >= WORLD_WIDTH) x = WORLD_WIDTH - 1;if (y < 0) y = 0;if (y >= WORLD_HEIGHT) y = WORLD_HEIGHT - 1;
}int main() {World world;BlockType currentBlock = 1;  // 初始方块类型为草bool rightButtonDown = false;bool key1Down = false;bool key2Down = false;bool key3Down = false;bool spaceDown = false;bool isDigging = false;  // 初始为放置模式HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);while (true) {// 双缓冲技术:先移动光标到屏幕左上角world.display(hOut);std::cout << "当前选择的方块:" << BLOCK_NAMES[currentBlock] << std::endl;std::cout << "当前模式:" << (isDigging ? "挖掘" : "放置") << std::endl;// 检测空格键切换模式if ((GetAsyncKeyState(VK_SPACE) & 0x8000) && !spaceDown) {isDigging = !isDigging;spaceDown = true;} else if (!(GetAsyncKeyState(VK_SPACE) & 0x8000)) {spaceDown = false;}// 检测鼠标右键if ((GetAsyncKeyState(VK_RBUTTON) & 0x8000) && !rightButtonDown) {int x, y;getMouseCoordinates(x, y);if (isDigging) {world.digBlock(x, y);} else {world.placeBlock(x, y, currentBlock);}rightButtonDown = true;} else if (!(GetAsyncKeyState(VK_RBUTTON) & 0x8000)) {rightButtonDown = false;}// 检测数字 1 键if ((GetAsyncKeyState(0x31) & 0x8000) && !key1Down) {currentBlock = 1;key1Down = true;} else if (!(GetAsyncKeyState(0x31) & 0x8000)) {key1Down = false;}// 检测数字 2 键if ((GetAsyncKeyState(0x32) & 0x8000) && !key2Down) {currentBlock = 2;key2Down = true;} else if (!(GetAsyncKeyState(0x32) & 0x8000)) {key2Down = false;}// 检测数字 3 键if ((GetAsyncKeyState(0x33) & 0x8000) && !key3Down) {currentBlock = 4;key3Down = true;} else if (!(GetAsyncKeyState(0x33) & 0x8000)) {key3Down = false;}if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {  // 按下 ESC 键退出break;}Sleep(50);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/77398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu使用dify源码安装部署教程+避坑指南

很多人,包括我在最初使用dify的时候都习惯使用docker来部署安装环境,但在二次开发使用过程中,我们可能希望使用源码来安装,那么这篇文章我将给大家分享如何在ubuntu系统下使用源码安装,并提供大家遇到的疑难杂症如下: dify安装使用过程中报错:/console/api/workspaces/…

java知识体系结构导航

很全&#xff1a;java知识体系结构 个人笔记链接 开发工具IDEA IDEA 插件推荐清单 IDEA快捷键大全 Java基础难点 基础知识_java动态代理 基础知识_java反射机制 基础知识-java流steam 基础知识-java集合collection Spring 01.Spring 框架的演化&#xff1a;从 XML 配置到…

RabbitMQ 的专业术语

术语定义示例/说明生产者&#xff08;Producer&#xff09;发送消息到 RabbitMQ 的客户端应用程序。日志系统将错误信息发送到 RabbitMQ。消费者&#xff08;Consumer&#xff09;从 RabbitMQ 队列中接收并处理消息的客户端应用程序。一个订单处理服务从队列中读取消息并更新数…

mac安装vm虚拟机安装包

因为mac安装虚拟机时&#xff0c;发现下载过程变得不太一样&#xff0c;会比较麻烦。所以决定发一下我已经下载的安装包&#xff0c;个人用户使用免费&#xff0c;商业版请自行去官网下载&#xff01; 百度网盘下载链接 百度网盘 请输入提取码 提取码:d4rc

LLama Factory从入门到放弃

目录 简介 安装 LLama Factory界面介绍 数据格式要求 微调训练 今天在这里介绍一种常用的大模型微调框架——LLama Factory。 简介 LLama Factory 是一个高效的界面化大语言模型微调工具库&#xff0c;支持多种参数高效微调技术&#xff0c;提供简洁接口和丰富示例&#…

如何借助全球动态IP实现多平台账号的批量注册?

无论是社交网络、在线购物平台还是专业应用软件&#xff0c;账号的创建和使用都是必不可少的。然而&#xff0c;在面对不同平台各自的注册限制和策略时&#xff0c;如何高效、安全且合法地进行账号批量注册成为了亟待解决的问题。本文将探讨全球动态IP在这一过程中的作用及其如…

django admin 添加自定义页面

在Django中&#xff0c;你可以通过多种方式向Django Admin添加自定义页面。以下是一些常见的方法&#xff1a; 方法1&#xff1a;使用ModelAdmin的get_urls()方法 如果你只是想添加一个简单的页面来展示信息&#xff0c;你可以在你的ModelAdmin类中重写get_urls()方法。 from…

Docker容器持久化

引言 Docker 容器作为一种轻量级、可移植的虚拟化技术&#xff0c;广泛应用于开发、测试和生产环境中。然而&#xff0c;容器天生是短暂的&#xff0c;意味着它们在生命周期结束后会被销毁&#xff0c;而其中的数据也会随之丢失。为了确保容器中的数据能够持久化&#xff0c;我…

ShaderToy学习笔记 02.圆

1. 画圆 1.1. 圆的方程 圆的方程是&#xff1a;(x^2 y^2 r^2)&#xff0c;其中(r)是圆的半径。 我们可以使用 desmos 来验证一下。 输入 x^2 y^2 -10&#xff0c;即可得到圆。 类似下图 1.2. 画圆的方式 画圆&#xff1a;使用圆的方程&#xff0c;判断每个像素点是否在圆…

一文详解卷积神经网络中的卷积层和池化层原理 !!

文章目录 前言 一、卷积核大小&#xff08;Kernel Size&#xff09; 1. 卷积核大小的作用 2. 常见的卷积核大小 3. 选择卷积核大小的原则 二、步长&#xff08;Stride&#xff09; 1. Stride的作用 三、填充&#xff08;Padding&#xff09; 1. 填充的作用 四、通道数&#xff…

云+AI双轮驱动,亚马逊云科技加速中国企业出海新浪潮

导读&#xff1a;全球化就是本地化 作者 | 小葳 图片来源 | 摄图 近年来&#xff0c;中国企业出海步伐不断加快&#xff0c;“不出海&#xff0c;就出局”成为很多企业的共识。 据沙利文统计&#xff0c;2024年上半年&#xff0c;超过2000家中国上市企业布局海外市场&#xff…

C语言HashTable基本理解

文章目录 一、哈希表概念1. 哈希表的基本概念2. 哈希表的核心组件2.1 哈希函数2.2 冲突处理&#xff08;哈希碰撞&#xff09; 3.哈希表的三种结构(1) 数组作为哈希表示例&#xff1a; 2. Set&#xff08;集合&#xff09;示例&#xff1a;查找数组中的重复元素1. Set 基础概念…

【缓存与数据库结合最终方案】伪从技术

实现伪从技术&#xff1a;基于Binlog的Following表变更监听与缓存更新 技术方案概述 要实现一个专门消费者服务作为Following表的伪从&#xff0c;订阅binlog并在数据变更时更新缓存&#xff0c;可以采用以下技术方案&#xff1a; 主要组件 MySQL Binlog监听&#xff1a;使…

《100天精通Python——基础篇 2025 第3天:变量与数据类型全面解析,掌握Python核心语法》

目录 一、Python变量的定义和使用二、Python整数类型&#xff08;int&#xff09;详解三、Python小数/浮点数&#xff08;float&#xff09;类型详解四、Python复数类型(complex)详解---了解五、Python字符串详解(包含长字符串和原始字符串)5.1 处理字符串中的引号5.2 字符串的…

【前后端分离项目】Vue+Springboot+MySQL

文章目录 1.安装 Node.js2.配置 Node.js 环境3.安装 Node.js 国内镜像4.创建 Vue 项目5.运行 Vue 项目6.访问 Vue 项目7.创建 Spring Boot 项目8.运行 Spring Boot 项目9.访问 Spring Boot 项目10.实现 Vue 与 Spring Boot 联动11.安装 axios12.编写请求13.调用函数请求接口14.…

线性代数(一些别的应该关注的点)

一、矩阵 矩阵运算&#xff1a;线性变换 缩放、平移、旋转 无所不能的矩阵 - 三维图形变换_哔哩哔哩_bilibili

01Redis快速入门(nosql、安装redis、客户端、命令及类型、java客户端、序列化)

Redis的常见命令和客户端使用 1.初识Redis Redis是一种键值型的NoSql数据库&#xff0c;这里有两个关键字&#xff1a; 键值型 NoSql 其中键值型&#xff0c;是指Redis中存储的数据都是以key、value对的形式存储&#xff0c;而value的形式多种多样&#xff0c;可以是字符串…

AI编程:[体验]从 0 到 1 开发一个项目的初体验

一、开发信息 开发时间&#xff1a;1.5-2天工具使用&#xff1a; 不熟练&#xff0c;开发本项目前1天&#xff0c;才简单使用了Cursor的功能 功能复杂度&#xff1a; 开发的功能相对简单。页面&#xff1a;2个&#xff0c;登录页面&#xff0c;个人中心页面功能&#xff1a;5个…

LeetCode-392 判断子序列

给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace"是"abcde"的一个子序列&#…

Linux 系统监控大师:Glances 工具详解助力自动化

看图猜诗&#xff0c;你有任何想法都可以在评论区留言哦~ 摘要 Glances 是一款基于 Python 开发的跨平台系统监控工具&#xff0c;集成了 CPU、内存、磁盘、网络、进程等核心指标的实时监控能力&#xff0c;并支持命令行、Web界面、客户端-服务器模式等多种使用场景。其轻量级…