哈喽大家好,我是iecne,本期为大家带来的是CPP/C++游戏设计教程的第④期—— 用颜色原理打印平面地图 ,包教包会,快来看看吧!
大家都知道,初学C++或者各种语言,面对枯燥无比的题目,脑子要爆的感觉是十分难受的,不妨会想设计一款游戏玩玩,但是由于能力不足、不知道如何设计而放弃。而这一专栏将会教会你们如何设计一款简单的Cpp游戏,快点赞收藏关注评论支持以下博主,蟹蟹
由粉丝保护小周ღ的建议,我们再出一期关于颜色的游戏设计教程
目录
一.颜色原理
上节课讲了SetConsoleTextAttribute函数,通过API设置字体颜色和背景色的函数。
正通过SetConsoleTextAttribute背景色的设置,我们可以做到简单的2D地图
C++游戏设计教程(3)—— 字体的颜色_iecne的博客-CSDN博客
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
int i,ss;
cout << " ";
for (i = 1; i <= 255; i++)
{
if (i <= 9) ss = 2 + 1;
else if (i >= 10 && i <= 99) ss = 2;
else ss = 1;
for (int j = 1; j < ss; j++)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), i);
cout << " ";
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), i);
cout << i;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0);
cout << " ";
if (i == 15) cout << endl;
else
{
if ((i+1) % 16 == 0 && i!=0)
{
cout << endl;
}
}
}
}
通过这行代码,我们可以得知下面的公式,能实现背景字体颜色SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),下方图片的编号);
如我们要黑底黑字
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0);
我们要白底黑字
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),240);
按照这个程序的结果来就行
二.应用位置
上一期,一大把一大把的代码,似乎并不是应用于字体,如以下
system("cls");
if (yes_or_no__return == true)
{
for (int i = 1; i <= Y; i++)
{
for (int j = 1; j <= X; j++)
{
if (map[i][j][3] == 1 && map[i][j][1] == 1)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 132);
cout << "X ";
}
else if (map[i][j][1] == 1 && map[i][j][3] == 0)//炸弹可能会被人物覆盖,所以放在前面
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 132);
cout << "●" ;
}
else if (map[i][j][2] == 0 && map[i][j][0] == 0 && map[i][j][1] == 0)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 136); //通过颜色的不同虚拟地图
cout << "□"; //输出一个中文大小的位置变换符号成为地图,直接表示出来
//这里选择中文而不表示是因为十进制中的SetConsoleTextAttribute函数字体与单个背景相同
}
else if (map[i][j][0] > 0)
{
if (map[i][j][2] == 0)
{
if (map[i][j][0] == 9) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 119); //字体和背景一样,不显示数字
else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 112 + map[i][j][0]); //通过颜色的不同虚拟地图
}
if (map[i][j][2] == 1)
{
if (map[i][j][0] >= 9) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 155); //字体和背景一样,不显示数字
else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240); //通过颜色的不同虚拟地图
}
cout << " " << map[i][j][0]; //输出一个中文大小的位置变换符号成为地图,直接表示出来
//这里选择中文而不表示是因为十进制中的SetConsoleTextAttribute函数字体与单个背景相同
}
else
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0); //调制为初始颜色,否则颜色会溢出,导致满屏
}
}
cout << endl;
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0); //调制为初始颜色,否则颜色会溢出,导致满屏 这条代码为二层保护
main();
}
以上代码由作者原创小游戏扫雷_iecne 1.0中的设置地图的代码
满满的注释,复杂的代码 这个背后却十分简单
三.使用方式
首先在打印地图的时候,我们需要做到一个标准的数组
1.二维数组
2.多维数组
二维数组主要引用与基本的地图打印,实际应用效果不佳,这里直接多维数组走起
1.多维数组
看到这一篇的大佬们,应该都会多维数组吧,很简单的内容,可以摸索出来
如我们定义一个三维数组map
long long int map[40][40][4] = { 0 };
注意:全局变量
众所周知,三维数组的含义如下:
但是在地图中,实际不是
而是普通的二维数组,而像结构体的二维数组
2.生成地图
从第一行开始遍历,双重循环for。比如我们要生成雷,则设定随机数,若到达一定的几率,就生成雷,到达一定数目退出。比如生存游戏,则生成矿物、树木……
srand((unsigned)time(NULL)); //将时间设为种子
for (int i = 1; i <= x; i++) //遍历地图
{
for (int j = 1; j <= y; j++)
{
RAND = rand() % 100; //直接取0-100,取0-10,11%的几率生成雷
if (RAND <= 10)
{
map[i][j][1] = 1; //可以使用bool,但是0/1没区别吧?
anslei++; //统计当前的雷数
}
if (anslei == boon)
{
breakk = true; //标记,因为是void,无法直接return走
break;
}
}
if (breakk == true) break;//由于双重循环还需要再次break退出
}
//统计完之后没有值可以返回,就放着
以上代码由作者原创小游戏扫雷_iecne 1.0中的设置地图的代码
我们将三维数组分为这样
map [ 纵向坐标 ] [ 横向坐标 ] [ 种类 ]
比如我是这样定义的: map[i][j][1](1表示地雷)=1 (有雷) / 0 (没有雷)
3.打印地图
等我们生成好了就一个函数到打印的函数
双重循环+特判
若map[i][j][1]==1(有雷)
{
输出
}
else
{
输出
}
整体逻辑如上
再看如图:
我们找字体和背景同颜色的编号,再模拟地图,同时输出的是一个中文或者特殊符号,占一定的空间!
(这种方法打印很基础dev/vs都可以实现)
由于字体和背景一样,我们输出一个中文或者两个空格,就可以模拟出一个空间,但是颜色相同模拟出一个地图的样子
4.效果
下面我们用一个非常基础的实验品来看看效果
定义生成好后,输出代码如下
for (int i = 1; i <= 30; i++)
{
cout << endl;
for (int j = 1; j <= 65; j++)
{
if (dt[dtcs][i][j] == 1 )
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 136);
cout << "石";
}
else if (dt[dtcs][i][j] == 0)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),102);
cout << "土";
}
else if (dt[dtcs][i][j] == 100)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 112);
cout << "你";
}
else if (dt[dtcs][i][j] == 11)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 170);
cout << "树";
}
}
}
以上代码由作者原创小游戏survival 1.0中的画地图的代码
结果如下:
这样就模拟出来了,如果有特殊符号则可以做到图标了。这个是最简单的做法,大佬不喜勿喷,此图片为试验品,丑但是有效果
四.总结
文末有投票,参与一下哈
本节课主要是讲解了SetConsoleTextAttribute函数实现的打印地图,至此SetConsoleTextAttribute的思想博主已经真真切切彻彻底底分享完了,相信大家对这个逻辑有了一定的理解,大家可以自己动手敲敲代码,感受一下
包教包会,帅的人已然点赞收藏关注,而丑的人还在犹豫,被犹豫了,快三连吧!
系列文章目录
本期收录于博主的专栏——C++游戏设计教程,感兴趣的朋友们可以订阅,查看其它专栏。
C++游戏设计教程(1) 随机数
C++游戏设计教程(2) Sleep睡眠与常用system
C++游戏设计教程(3) 字体的颜色
C++游戏设计教程(4) 用颜色原理打印平面地图
感谢每一个观看本篇文章的朋友,更多精彩敬请期待:iecne的博客_CSDN博客-C++保姆级入门教程领域博主
文章存在借鉴,如有侵权请联系修改删除!