鱼C论坛

 找回密码
 立即注册
查看: 2154|回复: 0

[技术交流] C语言,2048游戏文字版,流程逻辑思路,代码详解(上)

[复制链接]
发表于 2021-5-12 15:33:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 Stubborn 于 2021-5-12 16:15 编辑

C语言,2048游戏,流程逻辑思路,代码详解(上)



首先,贴上游戏的运行流程图例,以及运行时候的界面


流程.png

界面1.png

界面3.png

界面2.png




  1. // ---------------头文件---------------
  2. #include "stdbool.h"
  3. #include <stdio.h>
  4. #include "stdlib.h"
  5. #include "time.h"
  6. #include "conio.h"
  7. #include <windows.h>


  8. struct Game{
  9.     size_t length;
  10.     short arr[16];    // 游戏数据
  11.     size_t move;      //已执行步数
  12.     size_t score;     //存储游戏分数
  13.     size_t max;       //合并的最大值
  14.     time_t StartTime; //游戏运行时间
  15. };


  16. /*******函  数  声  明*******/

  17. /*******功 能 函 数*******/
  18. void GetCursorPosition(short, short);  //获取屏幕光标位置
  19. int SetTypefaceColor(short);           //设置文字颜色
  20. int randint(size_t);                      //返回一个随机值
  21. /*******绘 制 相 关 函 数*******/
  22. void DrawTitle();                      //绘制标题2048
  23. void DrawGameGuide();                  //绘制游戏引导
  24. void DrawTheGameBox(struct Game);      //绘制游戏界面
  25. void DrawKeyRule();                    //绘制游戏规则以及按键说明
  26. int DrawNumbersColor(int);             //绘制数字颜色
  27. int DrawWin(struct Game);              // 绘制胜利界面
  28. int DrawLoser(struct Game *);          // 绘制失败界面
  29. int _Loser(struct Game);
  30. /*******游 戏 逻 辑 函 数*******/
  31. void StartGame();                                    //开始游戏
  32. bool JudgmentInput(int, struct Game *);               //判断键盘操作是否在可执行范围内
  33. bool GeneratingRandomNumbers(struct Game *);         //随机在在Game.arr里产生一个数字
  34. bool _MoveUp(struct Game *);
  35. bool MoveUp(struct Game *);                         // 上下左右移动操作
  36. bool _MoveLeft(struct Game *);
  37. bool MoveLeft(struct Game *);
  38. bool _MoveRight(struct Game *);
  39. bool MoveRight(struct Game *);
  40. bool _MoveDown(struct Game *);
  41. bool MoveDown(struct Game *);


  42. int main(){
  43.     DrawGameGuide();
  44.     return 0;
  45. }

  46. void GetCursorPosition(short x, short y){
  47.     /*获取屏幕光标位置,从某个特定位置打印字符*/
  48.     COORD coo = {x, y};
  49.     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coo);
  50. }

  51. int SetTypefaceColor(short c) {
  52.     /*设置字体颜色*/
  53.     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
  54.     return 0;
  55. }


复制代码


以上是关于一些头文件,和系统函数。正文开始。
首先就是实现流程图中①的部分了。由于只是绘制,所以没有什么逻辑可言,依照自己风格绘制即可。

①-void DrawTitle();绘制一个2048的标题
  1. void DrawTitle(){
  2.     /*输出2048字符画*/
  3.     system("cls");
  4.     SetTypefaceColor(11); //浅淡绿色
  5.     GetCursorPosition(19, 2);
  6.     printf("■■■   ■■■■   ■  ■     ■■■■");
  7.     GetCursorPosition(19, 3);
  8.     printf("    ■   ■    ■   ■  ■     ■    ■");
  9.     GetCursorPosition(19, 4);
  10.     printf("■■■   ■    ■   ■  ■     ■■■■");
  11.     GetCursorPosition(19, 5);
  12.     printf("■       ■    ■   ■■■■   ■    ■");
  13.     GetCursorPosition(19, 6);
  14.     printf("■■■   ■■■■       ■     ■■■■");
  15. }
复制代码



①-DrawGameGuide;绘制整个的游戏欢迎界面。注意switch 分哪里,此时具体函数未实现,可以不调用函数,等实现之后在修改。
  1. void DrawGameGuide(){
  2.     system("cls");
  3.     DrawTitle();
  4.     int n;
  5.     GetCursorPosition(32, 8);
  6.     SetTypefaceColor(13);
  7.     printf("挑 战 2048");
  8.     SetTypefaceColor(14);
  9.     for (short k = 9; k < 21; k++) {
  10.         for (short l = 15; l < 61; l++) {
  11.             GetCursorPosition(l, k);
  12.             if (k == 9 || k == 20)printf("=");
  13.             else if (l == 15 || l == 60)printf("||");
  14.         }
  15.     }
  16.     SetTypefaceColor(12);                              //红色字体
  17.     GetCursorPosition(25, 12);                        //设置显示位置
  18.     printf("1.开始游戏");
  19.     GetCursorPosition(40, 12);
  20.     printf("2.游戏规则");
  21.     GetCursorPosition(25, 16);
  22.     printf("3.挑战模式");
  23.     GetCursorPosition(40, 16);
  24.     printf("4.退出");
  25.     GetCursorPosition(21, 22);
  26.     SetTypefaceColor(5);                             //深紫色字体
  27.     printf("请选择[1 2 3 4]:");
  28.     scanf("%d", &n);
  29.     switch (n) {                          //分支选择
  30.         case 1:                          //输入数字“1”
  31.             StartGame();
  32.             break;
  33.         case 2:                        //输入数字“2”
  34.             DrawKeyRule();
  35.             break;
  36.         case 3:                          //输入数字“3”
  37.             system("cls");
  38.             GetCursorPosition(20,12);
  39.             printf("挑战模式未实现,没有version.2.0\n");
  40.             GetCursorPosition(20,16);
  41.             printf(" ̄へ ̄\tQAQ\n");
  42.             GetCursorPosition(20,22);
  43.             printf("按任意键返回欢迎界面");
  44.             getch();
  45.             system("cls");
  46.             DrawGameGuide();
  47.         case 4:                          //输入数字“4”
  48.             exit(0);                        //退出游戏
  49.     }
  50. }
复制代码



现在①部分的欢迎界面都编写完成,开始编写②部分绘制函数
  1. void DrawKeyRule(){
  2.     int i,j = 1;
  3.     system("cls");
  4.     SetTypefaceColor(13);
  5.     GetCursorPosition(34,3);
  6.     printf("游戏规则");
  7.     SetTypefaceColor(2);
  8.     for (i = 6; i <= 18; i++)            //输出上下边框===
  9.     {
  10.         for (j = 15; j <= 70; j++)  //输出左右边框||
  11.         {
  12.             GetCursorPosition(j, i);
  13.             if (i == 6 || i == 18) printf("=");
  14.             else if (j == 15 || j == 69) printf("||");
  15.         }
  16.     }
  17.     SetTypefaceColor(3);
  18.     GetCursorPosition(18,7);
  19.     printf("tip1: 玩家可以通过↑ ↓ ← →方向键来移动方块");
  20.     SetTypefaceColor(10);
  21.     GetCursorPosition(18,9);
  22.     printf("tip2: 按ESC退出游戏");
  23.     SetTypefaceColor(14);
  24.     GetCursorPosition(18,11);
  25.     printf("tip3: 玩家选择的方向上,若有相同的数字则合并");
  26.     SetTypefaceColor(11);
  27.     GetCursorPosition(18,13);
  28.     printf("tip4: 每移动一步,空位随机出现一个2或4");
  29.     SetTypefaceColor(4);
  30.     GetCursorPosition(18,15);
  31.     printf("tip5: 棋盘被数字填满,无法进行有效移动,游戏失败");
  32.     SetTypefaceColor(5);
  33.     GetCursorPosition(18,17);
  34.     printf("tip6: 棋盘上出现2048,游戏胜利。按任意键返回主界面");
  35.     getch();                    //按任意键返回欢迎界面
  36.     system("cls");
  37.     DrawGameGuide();
  38. }
复制代码


③部分的话,没有实现不想写了 ,④部分直接使用`exit(0); `退出即可
⑤部分的绘制游戏界面代码如下


  1. void DrawTheGameBox(struct Game data){
  2.     /**The game interface includes score time and game content*/
  3.     system("cls");
  4.     SetTypefaceColor(14);
  5.     /// 打印4 x 4棋盘
  6.     for (int i = 2; i < 22; i+=5) {
  7.         int n = 4, j=i;
  8.         GetCursorPosition(15,i);
  9.         printf("-----------------------------------------");
  10.         while (n!=0){
  11.             j += 1;
  12.             GetCursorPosition(15,j);
  13.             printf("|         |         |         |         | ");
  14.             n -=1;
  15.         }
  16.     }
  17.     GetCursorPosition(15,22);
  18.     printf("-----------------------------------------");
  19.     /// 打印data.arr数据
  20.     for (size_t index = 0; index < data.length; ++index) {
  21.         size_t value = data.arr[index];
  22.         if ( value == 0){
  23.             continue;
  24.         }
  25.         short x = (short)index/4;
  26.         short y = (short)index%4;
  27.         GetCursorPosition(20 + y*10, 5 + x*5);
  28.         DrawNumbersColor(value);
  29.         printf("%d", value);
  30.     }
  31.     /// 打印游戏数据,分数,执行步数,耗时
  32.     GetCursorPosition(16,1);
  33.     SetTypefaceColor(11);
  34.     printf("游戏分数: %d",data.score);
  35.     SetTypefaceColor(13);
  36.     GetCursorPosition(42,1);
  37.     printf("执行步数: %d\n",data.move);
  38.     GetCursorPosition(44,23);
  39.     SetTypefaceColor(10);
  40.     time_t  EndTime = time(NULL);
  41.     printf("已用时:%f s", difftime(EndTime,data.StartTime));
  42.     GetCursorPosition(20,26);
  43.     SetTypefaceColor(13);
  44.     printf("①、↑、↓、←、→方向键进行游戏操作!");
  45.     GetCursorPosition(20, 28);
  46.     printf("②、ESC键退出游戏");

  47. }
复制代码


⑤void StartGame();函数部分,这里稍微说一下,为什么从void DrawGameGuide(); 函数中跳转到StartGame的原因。而不是直接跳到绘制游戏DrawTheGameBox函数。首先,我们的绘制函数会在每一次操作后,跟新游戏状态。也是就说DrawTheGameBox应该只是一个单纯的绘制游戏界面函数,不应该有 其他的功能。其次我们重新开始一次新的游戏,游戏数据也应该重置。
  1. void StartGame(){
  2.     /**Start the game, run the logic of the game
  3.      * */
  4.     bool True = true;
  5.     struct Game data= {16, {0}, 0, 0, 0, time(NULL)};
  6.     struct Game *p = &data;
  7.     GeneratingRandomNumbers(p);
  8.     DrawTheGameBox(data);
  9. }
复制代码


以上就是关于绘制函数的实现,还有胜利和失败的游戏界面,在后面会继续介绍到。下一贴介绍游戏的主逻辑


2048游戏(中)
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-29 09:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表