• C++游戏设计教程(4)—— 用颜色原理打印平面地图


    哈喽大家好,我是iecne,本期为大家带来的是CPP/C++游戏设计教程的第④期—— 用颜色原理打印平面地图 ,包教包会,快来看看吧!

    大家都知道,初学C++或者各种语言,面对枯燥无比的题目,脑子要爆的感觉是十分难受的,不妨会想设计一款游戏玩玩,但是由于能力不足、不知道如何设计而放弃。而这一专栏将会教会你们如何设计一款简单的Cpp游戏点赞收藏关注评论支持以下博主,蟹蟹

    由粉丝保护小周ღ的建议,我们再出一期关于颜色的游戏设计教程


    目录

    一.颜色原理

    二.应用位置

    三.使用方式

    1.多维数组

    2.生成地图

    3.打印地图

    4.效果

    四.总结

     系列文章目录


    一.颜色原理

    上节课讲了SetConsoleTextAttribute函数,通过API设置字体颜色和背景色的函数。

    正通过SetConsoleTextAttribute背景色的设置,我们可以做到简单的2D地图

    C++游戏设计教程(3)—— 字体的颜色_iecne的博客-CSDN博客

    1. #include
    2. #include
    3. using namespace std;
    4. int main()
    5. {
    6. int i,ss;
    7. cout << " ";
    8. for (i = 1; i <= 255; i++)
    9. {
    10. if (i <= 9) ss = 2 + 1;
    11. else if (i >= 10 && i <= 99) ss = 2;
    12. else ss = 1;
    13. for (int j = 1; j < ss; j++)
    14. {
    15. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), i);
    16. cout << " ";
    17. }
    18. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), i);
    19. cout << i;
    20. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0);
    21. cout << " ";
    22. if (i == 15) cout << endl;
    23. else
    24. {
    25. if ((i+1) % 16 == 0 && i!=0)
    26. {
    27. cout << endl;
    28. }
    29. }
    30. }
    31. }

    通过这行代码,我们可以得知下面的公式,能实现背景字体颜色SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),下方图片的编号);

    如我们要黑底黑字

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0);

    我们要白底黑字

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),240);

    按照这个程序的结果来就行


    二.应用位置

    上一期,一大把一大把的代码,似乎并不是应用于字体,如以下

    1. system("cls");
    2. if (yes_or_no__return == true)
    3. {
    4. for (int i = 1; i <= Y; i++)
    5. {
    6. for (int j = 1; j <= X; j++)
    7. {
    8. if (map[i][j][3] == 1 && map[i][j][1] == 1)
    9. {
    10. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 132);
    11. cout << "X ";
    12. }
    13. else if (map[i][j][1] == 1 && map[i][j][3] == 0)//炸弹可能会被人物覆盖,所以放在前面
    14. {
    15. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 132);
    16. cout << "●" ;
    17. }
    18. else if (map[i][j][2] == 0 && map[i][j][0] == 0 && map[i][j][1] == 0)
    19. {
    20. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 136); //通过颜色的不同虚拟地图
    21. cout << "□"; //输出一个中文大小的位置变换符号成为地图,直接表示出来
    22. //这里选择中文而不表示是因为十进制中的SetConsoleTextAttribute函数字体与单个背景相同
    23. }
    24. else if (map[i][j][0] > 0)
    25. {
    26. if (map[i][j][2] == 0)
    27. {
    28. if (map[i][j][0] == 9) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 119); //字体和背景一样,不显示数字
    29. else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 112 + map[i][j][0]); //通过颜色的不同虚拟地图
    30. }
    31. if (map[i][j][2] == 1)
    32. {
    33. if (map[i][j][0] >= 9) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 155); //字体和背景一样,不显示数字
    34. else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240); //通过颜色的不同虚拟地图
    35. }
    36. cout << " " << map[i][j][0]; //输出一个中文大小的位置变换符号成为地图,直接表示出来
    37. //这里选择中文而不表示是因为十进制中的SetConsoleTextAttribute函数字体与单个背景相同
    38. }
    39. else
    40. {
    41. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0); //调制为初始颜色,否则颜色会溢出,导致满屏
    42. }
    43. }
    44. cout << endl;
    45. }
    46. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0); //调制为初始颜色,否则颜色会溢出,导致满屏 这条代码为二层保护
    47. main();
    48. }

    以上代码由作者原创小游戏扫雷_iecne 1.0中的设置地图的代码

    满满的注释,复杂的代码  这个背后却十分简单


    三.使用方式

    首先在打印地图的时候,我们需要做到一个标准的数组

    1.二维数组

    2.多维数组

    二维数组主要引用与基本的地图打印,实际应用效果不佳,这里直接多维数组走起

    1.多维数组

    看到这一篇的大佬们,应该都会多维数组吧,很简单的内容,可以摸索出来

    如我们定义一个三维数组map

    long long int map[40][40][4] = { 0 };  

    注意:全局变量

    众所周知,三维数组的含义如下:

     但是在地图中,实际不是

    而是普通的二维数组,而像结构体的二维数组


    2.生成地图

     从第一行开始遍历,双重循环for。比如我们要生成雷,则设定随机数,若到达一定的几率,就生成雷,到达一定数目退出。比如生存游戏,则生成矿物、树木……

    1. srand((unsigned)time(NULL)); //将时间设为种子
    2. for (int i = 1; i <= x; i++) //遍历地图
    3. {
    4. for (int j = 1; j <= y; j++)
    5. {
    6. RAND = rand() % 100; //直接取0-100,取0-10,11%的几率生成雷
    7. if (RAND <= 10)
    8. {
    9. map[i][j][1] = 1; //可以使用bool,但是0/1没区别吧?
    10. anslei++; //统计当前的雷数
    11. }
    12. if (anslei == boon)
    13. {
    14. breakk = true; //标记,因为是void,无法直接return走
    15. break;
    16. }
    17. }
    18. if (breakk == true) break;//由于双重循环还需要再次break退出
    19. }
    20. //统计完之后没有值可以返回,就放着

    以上代码由作者原创小游戏扫雷_iecne 1.0中的设置地图的代码

    我们将三维数组分为这样

    map [ 纵向坐标 ] [ 横向坐标 ] [ 种类 ]

    比如我是这样定义的:  map[i][j][1](1表示地雷)=1 (有雷) / 0 (没有雷)


    3.打印地图

    等我们生成好了就一个函数到打印的函数

    双重循环+特判

    若map[i][j][1]==1(有雷)

    {

    输出

    }

    else

    {

    输出

    }

    整体逻辑如上

    再看如图:

    我们找字体和背景同颜色的编号,再模拟地图,同时输出的是一个中文或者特殊符号,占一定的空间!

    (这种方法打印很基础dev/vs都可以实现)

    由于字体和背景一样,我们输出一个中文或者两个空格,就可以模拟出一个空间,但是颜色相同模拟出一个地图的样子


    4.效果

    下面我们用一个非常基础的实验品来看看效果

    定义生成好后,输出代码如下

    1. for (int i = 1; i <= 30; i++)
    2. {
    3. cout << endl;
    4. for (int j = 1; j <= 65; j++)
    5. {
    6. if (dt[dtcs][i][j] == 1 )
    7. {
    8. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 136);
    9. cout << "石";
    10. }
    11. else if (dt[dtcs][i][j] == 0)
    12. {
    13. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),102);
    14. cout << "土";
    15. }
    16. else if (dt[dtcs][i][j] == 100)
    17. {
    18. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 112);
    19. cout << "你";
    20. }
    21. else if (dt[dtcs][i][j] == 11)
    22. {
    23. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 170);
    24. cout << "树";
    25. }
    26. }
    27. }

    以上代码由作者原创小游戏survival 1.0中的画地图的代码

    结果如下:

     这样就模拟出来了,如果有特殊符号则可以做到图标了。这个是最简单的做法,大佬不喜勿喷,此图片为试验品,丑但是有效果


    四.总结

    文末有投票,参与一下哈

    本节课主要是讲解了SetConsoleTextAttribute函数实现的打印地图,至此SetConsoleTextAttribute的思想博主已经真真切切彻彻底底分享完了,相信大家对这个逻辑有了一定的理解,大家可以自己动手敲敲代码,感受一下

    包教包会,帅的人已然点赞收藏关注,而丑的人还在犹豫,被犹豫了,快三连吧!


     系列文章目录

     本期收录于博主的专栏——C++游戏设计教程,感兴趣的朋友们可以订阅,查看其它专栏。

    C++游戏设计教程_iecne的博客-CSDN博客

    C++游戏设计教程(1) 随机数

    C++游戏设计教程(2) Sleep睡眠与常用system

    C++游戏设计教程(3) 字体的颜色

    C++游戏设计教程(4) 用颜色原理打印平面地图


      感谢每一个观看本篇文章的朋友,更多精彩敬请期待:iecne的博客_CSDN博客-C++保姆级入门教程领域博主

    文章存在借鉴,如有侵权请联系修改删除!

  • 相关阅读:
    wqs二分+斜率优化:1019T4 / P9338
    JavsScript系列-Promise的错误捕获
    我是如何快速从python小白达到20k?
    C++中不能重载为友元函数的四个运算符
    Selenium入门(二)Java整合Selenium实现模拟登录
    RFID电力资产全周期智能化管理应用解决方案
    RabbitMQ从入门到入土
    为什么信息图会帮助你的SEO
    C#调用python脚本教程使用pythonnet方式
    公司如何防止源代码外泄,保护开发部门代码安全呢?
  • 原文地址:https://blog.csdn.net/CSDN_linyanchen/article/details/126128880