5.C++入门实践项目总结

5.总结


5.1 知识点

学习的主要内容

总结讲什么

为什么要讲练结合

如何培养良好的学习习惯

如何快速的提升编程能力


5.2 核心要点速览

控制台输入输出

功能 方法/语法 说明
隐藏输入并单键获取 #include <conio.h>
int c = _getch();
无需回车,输入内容不显示,返回ASCII码
特殊键捕获 if (c == 0 || c == 224) c = _getch(); 第一次获取特殊键标识,第二次获取具体编码
清空控制台 system("cls"); 清除屏幕所有内容

特殊键编码:上箭头=72、下箭头=80、左箭头=75、右箭头=77

自定义控制台操作

功能 函数原型 参数说明
设置光标位置 void setCursorPosition(int x, int y); x列、y行,左上角为(0,0)
设置控制台大小 void setConsoleSize(int width, int height); 宽度、高度(缓冲区自动适配)
设置文本颜色 void setTextColor(WORD color); color为颜色码
隐藏/显示光标 void setCursorVisibility(bool visible); true显示,false隐藏
关闭控制台 void closeConsole(); 发送关闭消息至控制台窗口

颜色码:红色=4、绿色=2、蓝色=1,可通过位或混合(如 4|2 为黄色)

注意事项:坐标系中视觉上 1y ≈ 2x,边界处理需注意

随机数生成

函数 说明
int getRandom(int min, int max); 生成 [min, max] 范围内的随机整数
int r = getRandom(10, 20);  // 10-20随机数

实现原理:基于C++11随机数库(random_device + mt19937引擎 + 均匀分布)

项目调试

快捷键 功能
F9 设置/取消断点
F10 单步执行(逐过程)
F5 继续执行到下一断点
监视窗口 实时查看变量值

调试用途:排查代码错误、理清程序逻辑

实践项目:打怪兽拯救公主

场景结构

场景 ID 功能
开始场景 1 显示标题,选择开始/退出游戏
游戏场景 2 战斗区域 + 信息区域,回合制战斗
结束场景 3 显示结果,选择重玩/退出

核心机制

场景切换:通过 nowSceneID 变量控制,主循环用 switch 分发到不同场景逻辑

红墙绘制:用 字符绘制边界,战斗区域与信息区域分隔

角色属性

角色 位置 攻击力 血量 图标 颜色
玩家 (4,5) 8-12 100 黄色
Boss (24,15) 7-13 100 绿色
公主 (24,5) - - 蓝色

回合制战斗

  • 玩家在Boss周围四方向按J键触发
  • 每回合双方互相攻击,扣血 = 攻击力
  • Boss死亡后公主出现,玩家接触公主通关
  • 玩家死亡则游戏失败

移动控制:WASD控制方向,边界检测防止越界,不可覆盖敌人位置


5.3 面试题精选

基础题

1. _getch()cin 的区别

题目

在控制台游戏开发中,_getch()cin 都可以获取用户输入,它们有什么区别?各自适用于什么场景?

深入解析

_getch()cin 是两种不同的输入方式,核心区别在于输入机制和用户体验。

cin 的特点

  • 需要用户输入后按回车确认
  • 输入内容会显示在控制台上
  • 适合需要输入完整字符串的场景
  • 属于标准 C++ 输入流

_getch() 的特点

  • 无需按回车,按下按键立即获取
  • 输入内容不会显示在控制台上
  • 返回按键的 ASCII 码
  • 特殊键(方向键、功能键)需要调用两次:第一次返回 0 或 224,第二次返回具体编码
  • 属于 <conio.h> 库,Windows 平台特有
#include <conio.h>

// 普通键直接获取
int c = _getch();
if (c == 'w' || c == 'W') {
    // 处理 w 键
}

// 特殊键需要调用两次
if (c == 0 || c == 224) {
    c = _getch();
    switch (c) {
        case 72: // 上箭头
        case 80: // 下箭头
        case 75: // 左箭头
        case 77: // 右箭头
    }
}

适用场景

  • cin:表单输入、配置设置、需要用户确认的场景
  • _getch():游戏控制、菜单选择、快捷键响应
答题示例

两者主要区别在于输入机制。cin 需要回车确认,输入可见,适合字符串输入场景;_getch() 无需回车,输入不可见,适合游戏控制和即时响应场景。

游戏开发中常用 _getch() 实现角色移动、菜单选择等功能,因为用户期望按键即响应,不需要额外确认步骤。特殊键如方向键需要调用两次 _getch(),第一次获取标识(0或224),第二次获取具体编码。

参考文章
  • 1.必备知识点-控制台相关方法

2. 控制台游戏中如何实现角色移动

题目

在控制台游戏中,如何实现角色在屏幕上的移动?需要考虑哪些问题?

深入解析

控制台角色移动的核心是:位置变量 + 输入检测 + 重绘机制。

基本实现步骤

  1. 定义位置变量:用 xy 存储角色坐标
  2. 监听输入:通过 _getch() 获取按键
  3. 更新位置:根据按键修改坐标值
  4. 擦除旧位置:在原位置打印空格
  5. 绘制新位置:在新位置打印角色图标
int x = 0, y = 0;
while (true) {
    // 绘制角色
    setCursorPosition(x, y);
    cout << "■";
    
    // 等待输入
    int c = _getch();
    
    // 擦除旧位置
    setCursorPosition(x, y);
    cout << "  ";
    
    // 更新位置
    switch (c) {
        case 'W': case 'w': y--; break;
        case 'S': case 's': y++; break;
        case 'A': case 'a': x -= 2; break;  // 注意:x移动2单位
        case 'D': case 'd': x += 2; break;
    }
    
    // 边界检测
    if (x < 0) x = 0;
    if (y < 0) y = 0;
}

需要考虑的问题

问题 解决方案
边界越界 坐标限制在窗口范围内
闪烁问题 先擦除再绘制,或使用双缓冲
坐标单位 控制台字符宽高不等,视觉上 1y ≈ 2x
碰撞检测 移动前检测目标位置是否有障碍物
光标闪烁 使用 setCursorVisibility(false) 隐藏光标
答题示例

实现角色移动需要四个步骤:监听输入、擦除旧位置、更新坐标、绘制新位置。核心是用位置变量记录坐标,每次移动时先擦除再重绘。

需要注意几个问题:一是边界检测,防止角色越界;二是坐标单位,控制台字符宽高不等,横向移动要乘2才能和纵向视觉一致;三是隐藏光标避免闪烁;四是碰撞检测,移动前检查目标位置是否可行。

参考文章
  • 1.必备知识点-控制台相关方法

进阶题

1. 多场景游戏的切换机制设计

题目

一个游戏通常有多个场景(开始界面、游戏界面、结束界面),如何设计场景切换机制?

深入解析

场景切换是游戏架构的基础,常用方案是状态机模式:用变量标识当前场景,主循环根据场景ID分发到对应逻辑。

核心设计

int nowSceneID = 1;  // 当前场景ID
string gameOverInfo = "";  // 场景间传递的数据

while (true) {
    switch (nowSceneID) {
        case 1:  // 开始场景
            // 处理开始界面逻辑
            // 选择开始游戏后:nowSceneID = 2;
            break;
        case 2:  // 游戏场景
            // 处理游戏逻辑
            // 游戏结束后:nowSceneID = 3;
            break;
        case 3:  // 结束场景
            // 处理结束界面逻辑
            // 选择重玩:nowSceneID = 1;
            break;
    }
}

设计要点

要点 说明
场景ID 用整数或枚举标识每个场景
场景入口 每个场景开始时清屏、初始化状态
场景出口 切换时设置下一个场景ID
数据传递 通过变量在场景间传递数据(如游戏结果)
内层循环 每个场景可以用内层while处理自己的输入逻辑

场景切换流程

开始场景(ID=1) → 选择开始 → 游戏场景(ID=2)
游戏场景(ID=2) → 游戏结束 → 结束场景(ID=3)
结束场景(ID=3) → 选择重玩 → 开始场景(ID=1)
答题示例

场景切换常用状态机模式。用一个变量存储当前场景ID,主循环通过switch分发到不同场景的处理逻辑。每个场景处理完后修改场景ID,下一轮循环自动进入新场景。

设计要点包括:场景入口时清屏初始化,场景出口时设置下一个ID,场景间通过变量传递数据。每个场景可以有内层循环处理自己的输入逻辑,退出内层循环后自然切换到下一场景。

参考文章
  • 4.打怪兽拯救公主实践

2. 回合制战斗系统的设计思路

题目

如何设计一个回合制战斗系统?需要考虑哪些要素?

深入解析

回合制战斗是经典的游戏机制,核心是状态控制 + 伤害计算 + 结果判定

核心要素

要素 说明
战斗状态 用布尔变量标识是否处于战斗中
角色属性 攻击力范围、血量、防御力等
触发条件 玩家在敌人相邻位置按键触发
战斗流程 每回合双方各攻击一次
伤害计算 攻击力随机,扣血 = 攻击力 - 防御力
结束判定 任一方血量归零则战斗结束

代码结构

bool isFight = false;  // 战斗状态

// 触发战斗
if (玩家在Boss周围 && 按下J键) {
    isFight = true;
}

// 战斗循环
if (isFight && 按下J键) {
    // 玩家攻击
    int playerAtk = getRandom(playerAtkMin, playerAtkMax);
    bossHp -= playerAtk;
    
    // Boss反击(如果还活着)
    if (bossHp > 0) {
        int bossAtk = getRandom(bossAtkMin, bossAtkMax);
        playerHp -= bossAtk;
    }
    
    // 判定结果
    if (playerHp <= 0) 游戏失败;
    if (bossHp <= 0) 战斗胜利;
}

设计要点

  • 战斗中禁止移动,通过 isFight 控制
  • 每次按键执行一回合,而非自动连续战斗
  • 伤害数值随机,增加游戏趣味性
  • 战斗信息实时显示在信息区域
答题示例

回合制战斗系统需要三个核心要素:战斗状态控制、伤害计算、结果判定。用布尔变量标识是否处于战斗中,战斗期间禁止移动。

战斗流程是:玩家在敌人相邻位置按键触发战斗,每按一次键执行一回合,双方各攻击一次。伤害值在攻击力范围内随机生成,扣血后判定是否有人死亡。战斗信息实时显示在屏幕上,让玩家了解战斗进程。

参考文章
  • 4.打怪兽拯救公主实践

深度题

1. 打怪兽拯救公主项目的制作思路

题目

如果让你从零开始制作「打怪兽拯救公主」这个控制台游戏,你会怎么规划和实现?

深入解析

这是一个典型的游戏开发流程问题,考察项目整体把握能力和开发流程规划。

项目概述

  • 目标:制作一个控制台回合制战斗游戏
  • 核心玩法:移动角色 → 击败Boss → 营救公主

模块划分

模块 职责
控制台基础 窗口设置、光标控制、颜色设置
输入处理 按键检测、特殊键处理
场景管理 开始/游戏/结束三个场景的切换
渲染系统 墙体绘制、角色绘制、信息显示
战斗系统 回合制战斗、伤害计算、结果判定
游戏逻辑 移动控制、碰撞检测、胜负判定

开发顺序

  1. 基础搭建:设置控制台大小、隐藏光标、测试颜色输出
  2. 输入系统:实现 _getch() 按键检测,测试方向键
  3. 角色移动:实现单个角色移动,处理边界问题
  4. 场景框架:搭建三场景切换的主循环
  5. 开始场景:标题显示、菜单选择
  6. 游戏场景:墙体绘制、角色放置、移动控制
  7. 战斗系统:触发条件、回合制逻辑、伤害计算
  8. 结束场景:结果显示、重玩选项
  9. 完善细节:公主出现、通关逻辑、信息显示

关键技术点

// 1. 控制台初始化
setConsoleSize(50, 30);
setCursorVisibility(false);

// 2. 场景切换主循环
int nowSceneID = 1;
while (true) {
    switch (nowSceneID) { ... }
}

// 3. 墙体绘制(循环打印)
setTextColor(4);  // 红色
for (int i = 0; i < w; i += 2) {
    setCursorPosition(i, 0);
    cout << "■";
}

// 4. 回合制战斗
if (isFight && input == 'J') {
    bossHp -= getRandom(playerAtkMin, playerAtkMax);
    playerHp -= getRandom(bossAtkMin, bossAtkMax);
}

难点与解决

难点 解决方案
角色闪烁 先擦除旧位置再绘制新位置
坐标系问题 横向移动2单位等于纵向1单位
场景数据传递 用全局变量传递游戏结果
战斗中禁止移动 isFight 布尔值控制
答题示例

这个项目我会分六个模块开发:控制台基础、输入处理、场景管理、渲染系统、战斗系统、游戏逻辑。

开发顺序是:先搭建控制台基础和输入系统,确保能接收按键;然后实现角色移动和边界处理;接着搭建三场景切换框架;再逐个实现开始、游戏、结束场景;最后加入战斗系统和通关逻辑。

关键技术点包括:用状态机实现场景切换,用布尔值控制战斗状态,用循环绘制墙体,用随机数生成攻击力。难点是处理角色闪烁和坐标系问题,解决方案是先擦后绘、横向移动加倍。

参考文章
  • 1.必备知识点-控制台相关方法
  • 2.必备知识点-随机数
  • 3.必备知识点-项目调试
  • 4.打怪兽拯救公主实践


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏