基于控制台的小车导航游戏开发详解(C++实现)

news2025/4/24 7:46:32

本文将详细讲解一个基于C++控制台的小车导航游戏项目。通过该项目可以学习二维数组操作、队列数据结构应用以及游戏循环控制等核心编程概念,特别适合刚接触游戏开发的初学者学习。

一、项目概述

1.1 游戏规则

  1. 玩家可创建多辆具有不同初始位置和移动速度的小车

  2. 每辆小车需要在二维地图中从起点(S)移动至终点(E)

  3. 使用wasd键控制移动方向:

    • w:向上移动

    • a:向左移动

    • s:向下移动

    • d:向右移动

  4. 实时显示地图和小车位置,统计最终成功数量及最短耗时

1.2 核心功能

  • 多车队列管理

  • 动态地图渲染

  • 碰撞边界检测

  • 移动耗时统计

  • 游戏状态判断

二、核心代码解析

2.1 坐标系统与移动处理

cpp

if (sign == 'w') {
    new_x -= speed; // 向上移动
}
else if (sign == 'a') {
    new_y -= speed; // 向左移动
}
else if (sign == 's') {
    new_x += speed; // 向下移动
}
else if (sign == 'd') {
    new_y += speed; // 向右移动
}

坐标系统说明:

  • 使用二维数组的行列索引坐标系

  • x轴:垂直方向(行索引)

    • 增大表示向下移动

    • 减小表示向上移动

  • y轴:水平方向(列索引)

    • 增大表示向右移动

    • 减小表示向左移动

移动示例分析:
当输入's'(向下移动)时:

  • 实际是沿着垂直方向增加行索引

  • speed表示单次移动的格子数

  • 例如原位置(2,3),speed=2,向下移动后坐标变为(4,3)

三、完整源代码(带注释版)

cpp

#include <iostream>
#include <vector>
#include <queue>
#include <climits> // 用于INT_MAX
using namespace std;

// 小车结构体定义
struct car {
    int x, y;       // 当前位置坐标
    int speed;      // 移动速度(格子/秒)
    int time;       // 已用时间
    car(int _x, int _y, int _speed, int _time) 
        : x(_x), y(_y), speed(_speed), time(_time) {}
};

// 生成初始地图
vector<vector<char>> get_map(int m, int n) {
    return vector<vector<char>>(m, vector<char>(n, '#')); // '#'表示普通道路
}

// 输入校验函数
bool check(char sign) {
    return sign == 'w' || sign == 'a' || sign == 's' || sign == 'd';
}

// 打印当前地图状态
void print(vector<vector<char>> maze) {
    for (int i = 0; i < maze.size(); i++) {
        for (int j = 0; j < maze[0].size(); j++) {
            cout << maze[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}

int main() {
    queue<car> q; // 小车队列
    int num;
    cout << "请输入想要的车的数量: ";
    cin >> num;
    
    // 初始化小车信息
    for (int i = 0; i < num; i++) {
        cout << "请输入车的初始位置 (x, y) 和速度 (格/秒): " << endl;
        int cur_x, cur_y, cur_speed;
        cin >> cur_x >> cur_y >> cur_speed;
        q.push(car(cur_x, cur_y, cur_speed, 0));
    }

    // 创建地图
    cout << "请输入地图大小 (m * n): " << endl;
    int dx, dy;
    cin >> dx >> dy;
    vector<vector<char>> maze = get_map(dx, dy);
    maze[0][0] = 'S';          // 设置起点
    maze[dx-1][dy-1] = 'E';    // 设置终点

    int win_count = 0;
    int whole_time_min = INT_MAX; // 记录最短时间

    // 处理每辆小车
    while (!q.empty()) {
        car cur_car = q.front();
        q.pop();
        
        // 初始化小车位置
        maze[cur_car.x][cur_car.y] = '*'; 
        print(maze);

        char sign;
        while (true) {
            cout << "请移动小车 (w:上, a:左, s:下, d:右): ";
            cin >> sign;
            
            // 输入验证
            if (!check(sign)) {
                cout << "无效输入,请输入 w/a/s/d!" << endl;
                continue;
            }

            // 计算新坐标
            int new_x = cur_car.x;
            int new_y = cur_car.y;
            switch(sign) {
                case 'w': new_x -= cur_car.speed; break;
                case 'a': new_y -= cur_car.speed; break;
                case 's': new_x += cur_car.speed; break;
                case 'd': new_y += cur_car.speed; break;
            }

            // 边界检查
            if (new_x < 0 || new_x >= dx || new_y < 0 || new_y >= dy) {
                cout << "移动超出地图范围!" << endl;
                break;
            }

            // 更新地图
            maze[cur_car.x][cur_car.y] = '#'; // 清除旧位置
            cur_car.x = new_x;
            cur_car.y = new_y;
            maze[new_x][new_y] = '*';         // 标记新位置
            cur_car.time++;                   // 更新时间

            print(maze); // 输出当前地图

            // 到达终点判断
            if (cur_car.x == dx-1 && cur_car.y == dy-1) {
                whole_time_min = min(whole_time_min, cur_car.time);
                win_count++;
                cout << "成功抵达终点!用时:" << cur_car.time << "秒" << endl;
                break;
            }
        }
    }

    // 输出最终统计
    cout << "\n===== 游戏结束 =====" << endl;
    cout << "总共 " << num << " 辆车,成功 " << win_count 
         << " 辆,失败 " << num - win_count << " 辆" << endl;
    cout << "最短用时记录:" << whole_time_min + 1 << "秒" << endl;
    cout << "感谢您的游玩!" << endl;

    return 0;
}

四、运行示例

请输入想要的车的数量: 1
请输入车的初始位置 (x, y) 和速度 (格/秒): 
0 0 2
请输入地图大小 (m * n): 
5 5

S # # # #
# # # # #
# # # # # 
# # # # #
# # # # E

请移动小车 (w/a/s/d): d
...(移动过程省略)...

成功抵达终点!用时:4秒

===== 游戏结束 =====
总共 1 辆车,成功 1 辆,失败 0 辆
最短用时记录:4秒

五、扩展方向

  1. 添加障碍物系统

  2. 实现多车同时移动

  3. 增加移动动画效果

  4. 开发自动寻路算法

  5. 添加图形界面(SDL/OpenGL)

本项目通过简洁的代码实现了游戏核心机制,可作为学习二维游戏开发的基础模板。读者可以在此代码基础上进行扩展,开发出更复杂的游戏功能。

欢迎指出不足之处!!!

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

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

相关文章

色谱图QCPColorMap

一、QCPColorMap 概述 QCPColorMap 是 QCustomPlot 中用于绘制二维颜色图的类&#xff0c;可以将矩阵数据可视化为颜色图&#xff08;热力图&#xff09;&#xff0c;支持自定义色标和插值方式。 二、主要属性 属性类型描述dataQCPColorMapData存储颜色图数据的对象interpol…

最新扣子(Coze)案例教程:飞书多维表格按条件筛选记录 + 读取分页Coze工作流,无限循环使用方法,手把手教学,完全免费教程

大家好&#xff0c;我是斜杠君。 &#x1f468;‍&#x1f4bb; 星球群里有同学想学习一下飞书多维表格的使用方法&#xff0c;关于如何通过按条件筛选飞书多维表格中的记录&#xff0c;以及如何使用分页解决最多一次只能读取500条的限制问题。 斜杠君今天就带大家一起搭建一…

Spring AI Alibaba-02-多轮对话记忆、持久化消息记录

Spring AI Alibaba-02-多轮对话记忆、持久化消息记录 Lison <dreamlison163.com>, v1.0.0, 2025.04.19 文章目录 Spring AI Alibaba-02-多轮对话记忆、持久化消息记录多轮对话对话持久-Redis 本次主要聚焦于多轮对话功能的实现&#xff0c;后续会逐步增加更多实用内容&…

联邦元学习实现个性化物联网的框架

随着数据安全和隐私保护相关法律法规的出台&#xff0c;需要直接在中央服务器上收集和处理数据的集中式解决方案&#xff0c;对于个性化物联网而言&#xff0c;训练各种特定领域场景的人工智能模型已变得不切实际。基于此&#xff0c;中山大学&#xff0c;南洋理工大学&#xf…

实验1 温度转换与输入输出强化

知识点&#xff1a;input()/print()、分支语句、字符串处理&#xff08;教材2.1-2.2&#xff09; 实验任务&#xff1a; 1. 实现摄氏温度与华氏温度互转&#xff08;保留两位小数&#xff09; 2. 扩展功能&#xff1a;输入错误处理&#xff08;如非数字输入提示重新输入&#x…

【AI】SpringAI 第五弹:接入千帆大模型

1. 添加依赖 <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-qianfan</artifactId> </dependency> 2. 编写 yml 配置文件 spring:ai:qianfan:api-key: 你的api-keysecret-key: 你的secr…

[Godot] C#2D平台游戏基础移动和进阶跳跃代码

本文章给大家分享一下如何实现基本的移动和进阶的跳跃&#xff08;跳跃缓冲、可变跳跃、土狼时间&#xff09;以及相对应的重力代码&#xff0c;大家可以根据自己的需要自行修改 实现效果 场景搭建 因为Godot不像Unity&#xff0c;一个节点只能绑定一个脚本&#xff0c;所以我…

【Unity笔记】Unity + OpenXR项目无法启动SteamVR的排查与解决全指南

图片为AI生成 一、前言 随着Unity在XR领域全面转向OpenXR标准&#xff0c;越来越多的开发者选择使用OpenXR来构建跨平台的VR应用。但在项目实际部署中发现&#xff1a;打包成的EXE程序无法正常启动SteamVR&#xff0c;或者SteamVR未能识别到该应用。本文将以“Unity OpenXR …

使用 rebase 轻松管理主干分支

前言 最近遇到一个技术团队的 dev 环境分支错乱&#xff0c;因为是多人合作大家各自提交信息&#xff0c;导致出现很多交叉合并记录&#xff0c;让对应 log 看起来非常混乱&#xff0c;难以阅读。 举例说明 假设我们有一个项目&#xff0c;最初develop分支有 3 个提交记录&a…

【愚公系列】《Python网络爬虫从入门到精通》063-项目实战电商数据侦探(主窗体的数据展示)

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…

HttpSessionListener 的用法笔记250417

HttpSessionListener 的用法笔记250417 以下是关于 HttpSessionListener 的用法详解&#xff0c;涵盖核心方法、实现步骤、典型应用场景及注意事项&#xff0c;帮助您全面掌握会话&#xff08;Session&#xff09;生命周期的监听与管理&#xff1a; 1. 核心功能 HttpSessionLi…

火山RTC 5 转推CDN 布局合成规则

实时音视频房间&#xff0c;转推CDN&#xff0c;文档&#xff1a; 转推直播--实时音视频-火山引擎 一、转推CDN 0、前提 * 在调用该接口前&#xff0c;你需要在[控制台](https://console.volcengine.com/rtc/workplaceRTC)开启转推直播功能。<br> * 调…

Spark两种运行模式与部署

1. Spark 的运行模式 部署Spark集群就两种方式&#xff0c;单机模式与集群模式 单机模式就是为了方便开发者调试框架的运行环境。但是生产环境中&#xff0c;一般都是集群部署。 现在Spark目前支持的部署模式&#xff1a; &#xff08;1&#xff09;Local模式&#xff1a;在本地…

qt画一朵花

希望大家的生活都更加美好&#xff0c;画一朵花送给大家 效果图 void FloatingArrowPubshButton::paintEvent(QPaintEvent *event) {QPainter painter(this);painter.setRenderHints(QPainter::Antialiasing);QPen pen;pen.setColor("green");pen.setWidth(5);QBrush…

服务器上安装maven

1.安装 下载安装包 https://maven.apache.org/download.cgi 解压安装包 cd /opt/software tar -xzvf apache-maven-3.9.9-bin.tar.gz 安装目录(/opt/maven/) mv /opt/software/apache-maven-3.9.9 /opt/ 3.权限设置 把/opt/software/apache-maven-3.9.9 文件夹重命名为ma…

UOS+N 卡 + CUDA 环境下 X86 架构 DeepSeek 基于 vLLM 部署与 Dify 平台搭建指南

一、文档说明 本文档是一份关于 DeepSeek 在X86架构下通vLLM工具部署的操作指南&#xff0c;主要面向需要在UOSN卡CUDA环境中部署DeepSeek的技术人员&#xff0c;旨在指导文档使用者完成从 Python 环境升级、vLLM 库安装、模型部署到 Dify 平台搭建的全流程操作。 二、安装Pyt…

MySQL终章(8)JDBC

目录 1.前言 2.正文 2.1JDBC概念 2.2三种编码方式 2.2.1第一种 2.2.2第二种&#xff08;优化版&#xff09; 2.2.3第三种&#xff08;更优化版&#xff09; 3.小结 1.前言 哈喽大家好吖&#xff0c;今天来给大家带来Java中的JDBC的讲解&#xff0c;之前学习的都是操作…

Python 爬虫如何伪装 Referer?从随机生成到动态匹配

一、Referer 的作用与重要性 Referer 是 HTTP 请求头中的一个字段&#xff0c;用于标识请求的来源页面。它在网站的正常运行中扮演着重要角色&#xff0c;例如用于统计流量来源、防止恶意链接等。然而&#xff0c;对于爬虫来说&#xff0c;Referer 也可能成为被识别为爬虫的关…

【MySQL】表的约束(主键、唯一键、外键等约束类型详解)、表的设计

目录 1.数据库约束 1.1 约束类型 1.2 null约束 — not null 1.3 unique — 唯一约束 1.4 default — 设置默认值 1.5 primary key — 主键约束 自增主键 自增主键的局限性&#xff1a;经典面试问题&#xff08;进阶问题&#xff09; 1.6 foreign key — 外键约束 1.7…

基于STC89C52RC和8X8点阵屏、独立按键的小游戏《打砖块》

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、8X8点阵屏2、独立按键3、定时器04、定时器1 四、主函数总结 系列文章目录 前言 用的是普中A2开发板&#xff0c;外设有&#xff1a;8X8LED点阵屏、独立按键。 【单片机】STC89C52RC 【频率】12T11.0592MHz 效…