C++课程设计迷宫小游戏
温馨提示
程序语言:C、C++、C#、Python(红色字体表示本课设使用的程序设计语言)
图形功能选项:Win32控制台程序(黑框、文本界面)、Win32程序、MFC、WinForm、DirectX10(黑体标明表示本课设的程序图形类别,默认为非图形界面Win32控制台程序)
数据结构:基础类型、数组、链表、双向链表、搜索树(非平衡二叉树)、平衡二叉树、链表与平衡二叉树相结合、堆栈、队列、串、图(黑体标明表示本课设使用的数据结构)
~
C++语言项:STL库(黑体标明表示使用C++的STL库)
编译环境:Windows 7 64位旗舰版(Linux及其他环境请谨慎下载)
集成开发环境:Visual C++ 、DEVC++、CodeBlocks、Visual Studio 2015均可通过编译。(浅蓝色字体表示需要运行修改后的版本,请用户自行选择源代码测试)
分多头文件编译:否(所有代码基本都包含在一个文件内,如需试验头文件功能,请自行参考相关文献)
$
内容说明:
1、课设题目及预览内容将在第二页开始展示。
2、代码行数:525行
3、目录所示内容,本文基本涵盖,如无内容,会在本页进行说明。
4、附录绝对包含用户使用手册及程序完整源代码和详细注释。
5、如需下载其他头文件(例如DirectX需另行配置),本文会在此进行说明。
6、本文撰写内容仅供学习参考,另外,由于本人水平有限,编写之处难免存在错误
题目:基于C++控制台游戏的设计
】
任务要求:
1.代码量不低于300行,至少有5个函数,不得存在重复代码。
2.游戏设计具有一定可玩性,设计至少3关,界面和交互性友好,不得存在BUG。
3.每个人书写一份课程设计报告,报告中包含如下内容:
(1)题目简介(一段题目的简单介绍,一段题目开发的硬软要求)
(2)功能模块划分
(3)界面设计
(4)详细设计(流程图,或代码,每一部分代码要有相应的文字说明)(5)》
(6)遇到的问题及解决办法(5个问题以上)
(7)总结与展望
本课设文档基于迷宫游戏进行课程设计。
运行截图如下:
课程设计报告
课题:
学院:
专业:
学生姓名:
学号:
指导老师 :
20XX年XX月XX日
目录
1题目简介..................................................... 错误!未定义书签。2功能模块划分................................................. 错误!未定义书签。3界面设计..................................................... 错误!未定义书签。4详细设计..................................................... 错误!未定义书签。
数据结构.................................................. 错误!未定义书签。
函数说明.................................................. 错误!未定义书签。
函数设计流程图............................................ 错误!未定义书签。5遇到的问题及解决办法......................................... 错误!未定义书签。6总结与展望................................................... 错误!未定义书签。附录.......................................................... 错误!未定义书签。
1题目简介
人类建造迷宫已有5000年的历史。在世界的不同文化发展时期,这些奇特的建筑物始终吸引人们沿着弯弯曲曲、困难重重的小路吃力地行走,寻找真相。迷宫小游戏应运而生。在游戏中,迷宫被表现为寻找出口的一种益智小游戏。
本课设用★代表人物,○代表出口,■代表围墙,其他制表符(例如:━、┃、┳等)用来构造道路和阻挡玩家的去路。玩家要在游戏中,通过复杂的道路找到出口方可胜利。
本游戏一共设计3关,难度由低逐渐提升。
本课设开发基于Windows 7 64位系统,集成开发环境Visual Studio 2015 Pro。
2功能模块划分
本游戏一共分为四个功能模块,分别是开始界面的显示、进行游戏、下一关和通关界面的显示。
1、首先,打开程序的时候会进入一个欢迎界面,按任意键即可开始游戏。
2、玩家通过wsad控制人物(★)的上下左右。
3、每当玩家到达出口(○)会自动显示通过本关卡,并等待玩家按任意键进行下一关游戏。
4、当玩家通过所有的关卡时,将会显示一个通关界面。
具体的功能模块图如下:
开始界面
进行游戏
下一关
通关
功能模块图
3界面设计
本程序完全通过文本模式进行,根据上述四大功能模块,需要设计四类用户界面,分别是开始界面,游戏界面,下一个界面,游戏结束界面。
1、首先就是最基本的用户欢迎界面,也称开始界面,如下图所示。
图开始界面
2、其次,就是本程序的关键,也是这个游戏的核心所在,游戏交互界面,如下图所示。
图游戏交互界面3、接着,就是通过本关卡之后的界面,如图所示。
4、最后,就是通过所有关卡的游戏界面,如图所示。
图游戏通关界面
4详细设计
数据结构
该迷宫小游戏只需设计一个类即可控制整个游戏的运行,通过分析,迷宫小游戏需要一个构造函数Maze()对游戏数据进行初始化,一个显示开始界面的函数ShowUI(),一个绘制游戏界面的函数ShowGame(),一个初始化下一关数据的函数NextCheckpoint(),一个控制人物移动的函数Move(),其中通过Rand()管理各关卡的地图数据,一个游戏结束界面函数GameOver(),还需要一个Game()函数控制游戏的开始与结束逻辑。
在整个设计中,通过二维数组来映射各种文本字符(★、■等),其中映射数据通过宏定义来实现,这样方便管理与维护。
类的数据结构如下:
class Maze {
public :
Maze(); .... ┃┃" << endl; cout << "┃┃ ┃┃" << endl;
cout << "┃┃ ┃┃" << endl;
cout << "┃┃ ┃┃" << endl;
cout << "┃┗━━━━━━━━━━━━━━━━━━━━━┛┃" << endl;
cout << "┗━━━━━━━━━━━━━━━━━━━━━━━┛" << endl;
_getch(); }
void Maze ::Game()
{
do {
if (CHECKPOINT == checkpoint)
GameOver(); //游戏通关
else if (RAILING13 == map[y][x])
NextCheckpoint(); //下一关
else {
ShowGame(); //打印迷宫
Move(); //移动
}
} while (true ); }
是 否 否 是 Game()开始 判断游戏是否结束 是否进行下一关 初始化下一关数据NextCheckpoint() 调用GameOver() d 键
a 键 s 键 w 键 是wsad 键 非wsad 键 Move()开始 获取按键信息 判断wsad 按键
void Maze::ShowGame()
{
int i = 0, j = 0;
system("cls");
cout << endl;
for (i = 0; i < DIMENSION; i++)
for (j = 0; j < DIMENSION; j++) {
switch (map[i][j])
{
case ACCESS:cout <<" "; break;
case RAILING1:cout <<"━"; break;
case RAILING2:cout <<"┃"; break;
case RAILING3:cout <<"┏"; break;
case RAILING4:cout <<"┗"; break;
case RAILING5:cout <<"┓"; break;
case RAILING6:cout <<"┛"; break;
case RAILING7:cout <<"┣"; break;
case RAILING8:cout <<"┫"; break;
case RAILING9:cout <<"┳"; break;
case RAILING10:cout <<"┻"; break;
case RAILING11:cout <<"╋"; break;
case RAILING12:cout <<"★"; break;
case RAILING13:cout <<"○"; break;
case RAILING14:cout <<"■"; break;
default:
break;
}
if (DIMENSION - 1 == j) //换行
cout << endl;
}
cout << endl <<"\t按键WSAD依次对应着上下左右"<< endl; }
void Maze::GameOver()
{
system("cls");
cout << endl;
cout <<"┏━━━━━━━━━━━━━━━━┓"<< endl;
cout <<"┃┃"<< endl;
cout <<"┃┃"<< endl;
cout <<"┃┃"<< endl;
cout <<"┃恭喜你已经通关┃"<< endl;
cout <<"┃┃"<< endl;
cout <<"┃┃"<< endl;
cout <<"┃┃"<< endl;
cout <<"┃┃"<< endl;
cout <<"┗━━━━━━━━━━━━━━━━┛"<< endl;
_getch();
exit(0);
}
void Maze::Move()
{
switch (_getch()) {
case'w': //向上移动
case'W':
if (y > 0 && ACCESS == map[y - 1][x]) {
map[y][x] = ACCESS;
map[--y][x] = RAILING12;
}
else if (y > 0 && RAILING13 == map[y - 1][x]) //出口不覆盖数据--y;
break;
case's': //向下移动
case'S':
if (y < DIMENSION - 1 && ACCESS == map[y + 1][x]) {
map[y][x] = ACCESS;
map[++y][x] = RAILING12;
}
else if (y < DIMENSION - 1 && RAILING13 == map[y + 1][x])
++y;
break;
case'a': //向左移动
case'A':
if (x > 0 && ACCESS == map[y][x - 1]) {
map[y][x] = ACCESS;
map[y][--x] = RAILING12;
}
else if (x > 0 && RAILING13 == map[y][x - 1])
--x;
break;
case'D':
if (x < DIMENSION - 1 && ACCESS == map[y][x + 1]) {
map[y][x] = ACCESS;
map[y][++x] = RAILING12;
}
else if (x < DIMENSION - 1 && RAILING13 == map[y][x + 1])
++x;
break;
}
}
void Maze::NextCheckpoint()
{
checkpoint++;
if (checkpoint >= CHECKPOINT)
return;
Rand();
system("cls");
cout << endl << endl <<"\t恭喜您第"<< checkpoint <<"关已通关,请按任意键继续。"<< endl;
_getch();
}
void Maze::Rand()
{
int i = 0,j=0;
for (i = 0; i < DIMENSION; i++)
for (j = 0; j < DIMENSION; j++)
map[i][j] = ACCESS;
for (i = 0; i < DIMENSION; i++) { //初始化砖墙位置
map[i][0] = RAILING14;
map[i][DIMENSION - 1] = RAILING14;
map[0][i] = RAILING14;
map[DIMENSION - 1][i] = RAILING14;
}
switch (checkpoint) {
case 0: //第一关
map[9][0] = RAILING12; //人物位置
x = 0; //记录人物的x,y坐标y = 9;
// ┃
for (i = 3; i < 8; i++) {
map[i][2] = RAILING2;
map[i][8] = RAILING2;
map[i][10] = RAILING2;
map[i][17] = RAILING2;
}
// ┃
for (i = 11; i < 17; i++) { map[i][2] = RAILING2;
map[i][8] = RAILING2;
map[i][10] = RAILING2;
map[i][17] = RAILING2;
}
// ━
for (i = 3; i < 8; i++) {
map[2][i] = RAILING1;
map[8][i] = RAILING1;
map[10][i] = RAILING1;
map[17][i] = RAILING1;
}
// ━
for (i = 11; i < 17; i++) { map[2][i] = RAILING1;
map[8][i] = RAILING1;
map[10][i] = RAILING1;
map[17][i] = RAILING1;
}
//┏
map[2][2] = RAILING3;
map[10][2] = RAILING3;
map[2][10] = RAILING3;
map[10][10] = RAILING3;
//┗
map[8][10] = RAILING4;
map[17][10] = RAILING4;
//┓
map[2][8] = RAILING5;
map[10][8] = RAILING5;
map[2][17] = RAILING5;
map[10][17] = RAILING5;
//┛
map[8][8] = RAILING6;
map[8][17] = RAILING6;
map[17][8] = RAILING6;
map[17][17] = RAILING6;
break;
case 1: //第二关
map[8][0] = RAILING12; //人物位置
map[12][DIMENSION - 1] = RAILING13; //出口位置
x = 0; //记录人物的x,y坐标
y = 8;
for (i = 3; i < 17; i++) {
map[1][i] = RAILING1;
map[18][i] = RAILING1;
}
for (i = 2; i < 18; i++)
map[i][2] = RAILING2;
map[8][2] = ACCESS;
map[1][2] = RAILING3;
map[9][2] = RAILING3;
map[15][2] = RAILING7;
map[17][2] = RAILING7;
map[18][2] = RAILING4;
for (i = 2; i < 18; i++)
map[i][17] = RAILING2;
map[9][17] = ACCESS;
map[1][17] = RAILING5; map[18][17] = RAILING6;
for (i = 3; i < 5; i++) { map[i][4] = RAILING2;
map[i][11] = RAILING2; }
for (i = 5; i < 11; i++) { map[2][i] = RAILING1;
map[4][i] = RAILING1; }
map[4][7] = RAILING9;
map[4][10] = RAILING9;
map[2][4] = RAILING3;
map[4][4] = RAILING4;
map[2][11] = RAILING5; map[4][11] = RAILING6;
map[6][8] = RAILING1;
map[6][9] = RAILING9;
map[5][7] = RAILING2;
map[5][10] = RAILING2;
map[6][7] = RAILING4;
map[6][10] = RAILING8;
map[7][9] = RAILING8;
for (i = 7; i < 9; i++)
map[7][i] = RAILING1;
map[7][6] = RAILING10; map[7][4] = RAILING4;
map[6][4] = RAILING2;
map[6][6] = RAILING2;