常见项目——C语言实现2048小游戏(附源码和可执行文件)

发布时间 2023-05-28 22:03:48作者: Billsheng

1. 实现效果展示

1.1 界面图片

说明:进入下面各页面后均可通过按键“q”来退出。

1)菜单页

2)开始游戏页

3)游戏规则页

4)按键说明页

5)退出游戏页

1.2 视频展现

戳此处查看视频演示

1.3 游戏源码及可执行文件(exe)下载

支持作者,请关注公众号“优秀物联人”回复“2048小游戏”获取下载地址(包含.c源码和.exe可执行文件)

2. 介绍一些功能的实现方法

2.1 游戏中所使用的头文件

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <math.h>
#include <time.h>

2.2 光标定位

/* 获取屏幕光标位置 */
void gotoxy(int x, int y)
{
    COORD c;
    c.X = x;
    c.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

通过该函数,即可实现对cmd控制台的打印位置控制,以便后续对页面进行精确绘制。

2.3 设置文字颜色

int color(int c)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

c是颜色的代号,数值不同,颜色不同。同时,cmd窗口部分颜色代号是带有背景颜色填充的,所以可以实现对不同数值背景色块不一样。

2.4 标题2048的绘制

标题2048绘制代码就用到了上面的光标定位,代码如下:

void number()
{
    color(11);
    gotoxy(19, 2);
    printf("■ ■ ■ ■    ■ ■ ■ ■         ■      ■ ■ ■ ■");
    gotoxy(19, 3);
    printf("         ■    ■       ■     ■  ■      ■       ■");
    gotoxy(19, 4);
    printf("■ ■ ■ ■    ■       ■   ■ ■ ■ ■   ■ ■ ■ ■");
    gotoxy(19, 5);
    printf("■             ■       ■         ■      ■       ■");
    gotoxy(19, 6);
    printf("■ ■ ■ ■    ■ ■ ■ ■         ■      ■ ■ ■ ■");
}

绘制效果:

2.5 游戏界面的绘制

void drawTheGameBox()
{
    number();
    color(14);
    gotoxy(19, 8);
    printf("游戏制作者:Billsheng  当前分数:%-6d  最高分:%-6d", score, best);
    gotoxy(19, 9);
    printf("------------------------------------------------------");
    gotoxy(19, 11);
    printf("┌────────────┬────────────┬────────────┬────────────┐");
    gotoxy(19, 12);
    printf("│            │            │            │            │");
    gotoxy(19, 13);
    printf("├────────────┼────────────┼────────────┼────────────┤");
    gotoxy(19, 14);
    printf("│            │            │            │            │");
    gotoxy(19, 15);
    printf("├────────────┼────────────┼────────────┼────────────┤");
    gotoxy(19, 16);
    printf("│            │            │            │            │");
    gotoxy(19, 17);
    printf("├────────────┼────────────┼────────────┼────────────┤");
    gotoxy(19, 18);
    printf("│            │            │            │            │");
    gotoxy(19, 19);
    printf("└────────────┴────────────┴────────────┴────────────┘");
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            if (board[i][j] != 0)
            {
                if (board[i][j] == 2048)
                {
                    game_win = 1;
                    return;
                }
                for (int k = 1; k < 12; k++)
                {
                    if (board[i][j] == pow(2, k))
                    {
                        zimoxu = k - 1;
                        break;
                    }
                }
                gotoxy(lieweixu[j], hangweixu[i]);
                color(zimo[zimoxu]);
                printf("%4d", board[i][j]);
                color(0);
            }
        }
    }
}

1)首先通过gotoxy定位光标,精确绘制好基础的4*4的格子,格子当中数值通过二维数组board来存储。

2)每次数据更新需要逐一遍历该二维数组,采用两个for循环完成,0表示格子当中无数值,当格子数值当中出现2048时游戏胜利。

3)数字的色块代码是通过一维数组zimo来存储的,因为数值为2的x次幂,所以通过x可以控制不同数值色块颜色的变化。

4)因为4*4格子中数值显示位置是固定的,所以x和y可以通过两个一维数组来存储列数和行数。

2.6 逻辑判断

对于用户输入的向左、向右、向上、向下,二维数组board该做如何对应的变换?这是实现2048游戏的重点。下面以向左为例,给出代码和注释,以作分享。

void move_left()
{
    for (int i = 0; i < 4; i++) // 逐行查看
    {
        for (int j = 1, k = 0; j < 4; j++) // 逐列检查
        {
            if (board[i][j] != 0)
            {
                if (board[i][k] == board[i][j]) // 左右相等,可以合并
                {
                    score += board[i][k++] *= 2;
                    board[i][j] = 0;
                    add_num_flag = 1; // 合并则需要添加随机数
                }
                else if (board[i][k] == 0) // 左侧为0,直接移过去
                {
                    board[i][k] = board[i][j];
                    board[i][j] = 0;
                    add_num_flag = 1; // 合并则需要添加随机数
                }
                else // 左右两侧均不相等,发生碰撞
                {
                    board[i][++k] = board[i][j];
                    if (j != k) // 两个不相邻,则j位置置0
                    {
                        board[i][j] = 0;
                        add_num_flag = 1;
                    }
                }
            }
        }
    }
}

3. 其它需要思考的点

1)如何通过生成随机数,实现在空白格子的随机位置中随机添加一个2或4?

提示:需要统计空白格子数,并生成随机数,随机数对空白格子数取余,再去遍历到余数值,填充数字即可。

2)如何判断游戏结束了?

提示:当二维数组填满了数字且任一位置的上下左右均不与该位置值相同即为结束

3)如何保存用户的最高分,以实现下次打开应用时,最高分仍不变?当打破最高分后记录新的高分怎么操作?

提示:涉及文件的读入、写入操作。

具体实现代码可参见源码文件中各函数

游戏源码及可执行文件(exe)下载

辛苦各位,支持作者,请关注公众号“优秀物联人”回复“2048小游戏”获取下载地址(包含.c源码和.exe可执行文件)