本次全程跟着b站视频教学,感谢互联网,感谢感谢。
//移动格子
void move()
{
//获取键盘按键 72上 80下 75左 77右
int key = _getch();
switch (key)
{
case 'W':
case 'w':
case 72:
moveUp();
break;
case 'S':
case 's':
case 80:
moveDown();
break;
case 'A':
case 'a':
case 75:
moveLeft();
break;
case 'D':
case 'd':
case 77:
moveRight();
break;
}
printf("%d\n", key);
}
int main()
{
//窗口, EX_SHOWCONSOLE显示控制台界面
initgraph(COL*GRID_SIZE+(COL+1)*INTERVAL, ROW*GRID_SIZE+(ROW+1)*INTERVAL, EX_SHOWCONSOLE);
init();
while (true)//一直的移动,一直的绘制
{
draw();
move();
}
getchar();//防止窗口闪退
return 0;
}
完整代码
//头文件
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<easyx.h>
#include<math.h>
#include<conio.h>
/*
* 2048game
* 1.数据可以使用二维数组存储
* 2.随机数 srand rand函数在stdlib
* 3.把数据转成图形界面
*/
#define ROW 4 //引用方便
#define COL 4 //4为个数
#define GRID_SIZE 100 //100是像素,格子的宽度和高度
#define INTERVAL 15 //格子间的间隔
enum Color//枚举格子颜色
{
zero=RGB(205,193,180),//0de color
twoTo1=RGB(238,228,218),//2
twoTo2=RGB(237,224,200),//4
twoTo3=RGB(242,177,121),//8
twoTo4=RGB(245,149,99),//16
twoTo5=RGB(246,124,95),//32
twoTo6=RGB(246,94,59),//64
twoTo7=RGB(242,177,121),//128
twoTo8=RGB(237,204,97),//256
twoTo9=RGB(255,0,128),//512
twoTo10=RGB(145,0,72),//1024
twoTo11=RGB(242,17,158),//2048
back=RGB(187,173,160),
};
//定义数组
Color colors[13] = { zero,twoTo1,twoTo2,twoTo3,twoTo4,twoTo5,twoTo6,twoTo7,twoTo8,twoTo9,twoTo10,twoTo11 };
//存储数据的数组
int map[ROW][COL];
//随机产生2or4
int createNumber()
{
//控制概率
if (rand() % 10 != 0)
{
return 2;
}
else
{
return 4;
}
}
//给数组空白处填充数
void mapFillNumber()
{
//随机产生一个数并且放到数组,可以引用rand
//一开始需要产生两个数
while(true)
{
//多次产生下标的时候,可能会重复 0 1 0 1
int r = rand() % ROW;//0 1 2 3
int c = rand() % COL;//0 1 2 3
if (map[r][c] == 0)
{
map[r][c] = createNumber();
return;
//只有正确生成了数字,才i++
}
}
}
//初始化
void init()
{
//设置随机数种子
srand(time(NULL));
//因为每次运行程序系统时间不一样
//随机产生一个数,,并且放到数组里
for (int i = 0; i < 2; i++)
{
mapFillNumber();
}
//map[0][0] = 2048;测试数据
//map[0][0] = 512;
}
//绘制
void draw()
{
setbkcolor(RGB(187, 173, 160));//设置背景颜色
cleardevice();//用设置的背景颜色填充整个屏幕
for (int i = 0; i < ROW; i++)
{
for (int k = 0; k < COL; k++)
{
//把每个格子左上角坐标求出来
int x = k * GRID_SIZE + (k + 1) * INTERVAL;
int y = i * GRID_SIZE + (i + 1) * INTERVAL;
//RGB 205 193 180
//map[i][k] 2048 2^11=2048 2^?=0未定义会造成程序无法运行
int index = map[i][k] ? log2(map[i][k]) : 0;
setfillcolor(colors[index]);
solidroundrect(x, y, x + GRID_SIZE, y + GRID_SIZE, 10, 10);
if (map[i][k])//为真不显示0
{
//先把数字转成字符串
// ASCII
char numberStr[5] = { 0 };
sprintf(numberStr, "%d", map[i][k]);
//绘制文字,把map的i和k绘制
//设置字体颜色
settextcolor(RGB(119, 110, 101));
settextstyle(50, 0, "微软雅黑");
setbkmode(TRANSPARENT);//设置背景颜色为透明
//文字居中显示
int hspace = (GRID_SIZE - textwidth(numberStr)) / 2;//水平间距
int vspace = (GRID_SIZE - textheight(numberStr)) / 2;
//printf不可以做到,因为它是输入输出到控制台的
//而我们需要的是输入输出到图形窗口,则可以使用outtextxy,把文本输出到指定坐标
outtextxy(x + hspace, y + vspace, numberStr);//该函数只能是字符或字符串,数字不会报错,但对游戏的实现有影响
}
}
printf("\n");
}
}
//向上移动,从上往下遍历
void moveUp()
{
bool isMoved = false;
for (int c = 0; c < ROW; c++)//遍历列
{
int temp = COL - 1;//从第一个元素开始
for (int begin = COL - 2; begin >= 0; begin--)//遍历行
{
//判断begin处是否为0
if (map[begin][c] != 0)
{
if (map[temp][c] == 0)
{
map[temp][c] = map[begin][c];
map[begin][c] = 0;
isMoved = true;
}
else if (map[temp][c] == map[begin][c])
{
map[temp][c] *= 2;
map[begin][c] = 0;
temp--;
isMoved = true;
}
else
{
map[temp - 1][c] = map[begin][c];
if (temp - 1 != begin)
{
map[begin][c] = 0;
isMoved = true;
}
temp--;
}
}
}
}
if (isMoved)
{
mapFillNumber();
}
}
//向下移动,从下往上遍历,行
void moveDown()
{
bool isMoved = false;
for (int c = 0; c < COL; c++)//遍历列
{
int temp = ROW - 1;
for (int begin = ROW - 2; begin >= 0; begin--)//遍历行
{
//判断begin处是否为0
if (map[begin][c] != 0)
{
if (map[temp][c] == 0)
{
map[temp][c] = map[begin][c];
map[begin][c] = 0;
isMoved = true;
}
else if (map[temp][c] == map[begin][c])
{
map[temp][c] *= 2;
map[begin][c] = 0;
temp--;
isMoved = true;
}
else
{
map[temp - 1][c] = map[begin][c];
if (temp - 1 != begin)
{
map[begin][c] = 0;
isMoved = true;
}
temp--;
}
}
}
}
if (isMoved)
{
mapFillNumber();
}
}
//向左移动
void moveLeft()
{
bool isMoved = false;
for (int c = 0; c < ROW; c++)//遍历列
{
int temp = 0;//从第一个元素开始
for (int begin = 1; begin < COL; begin++)//遍历行
{
//判断begin处是否为0
if (map[begin][c] != 0)
{
if (map[temp][c] == 0)
{
map[temp][c] = map[begin][c];
map[begin][c] = 0;
isMoved = true;
}
else if (map[temp][c] == map[begin][c])
{
map[temp][c] *= 2;
map[begin][c] = 0;
temp++;
isMoved = true;
}
else
{
map[temp + 1][c] = map[begin][c];
if (temp + 1 != begin)
{
map[begin][c] = 0;
isMoved = true;
}
temp++;
}
}
}
}
if (isMoved)
{
mapFillNumber();
}
}
//向右移动
void moveRight()
{
bool isMoved = false;
for (int c = 0; c < ROW; c++)//遍历列
{
int temp = COL - 1;//从第一个元素开始
for (int begin = COL - 2; begin >= 0; begin--)//遍历行
{
//判断begin处是否为0
if (map[begin][c] != 0)
{
if (map[temp][c] == 0)
{
map[temp][c] = map[begin][c];
map[begin][c] = 0;
isMoved = true;
}
else if (map[temp][c] == map[begin][c])
{
map[temp][c] *= 2;
map[begin][c] = 0;
temp--;
isMoved = true;
}
else
{
map[temp - 1][c] = map[begin][c];
if (temp - 1 != begin)
{
map[begin][c] = 0;
isMoved = true;
}
temp--;
}
}
}
}
if (isMoved)
{
mapFillNumber();
}
}
//移动格子
void move()
{
//获取键盘按键 72上 80下 75左 77右
int key = _getch();
switch (key)
{
case 'W':
case 'w':
case 72:
moveUp();
break;
case 'S':
case 's':
case 80:
moveDown();
break;
case 'A':
case 'a':
case 75:
moveLeft();
break;
case 'D':
case 'd':
case 77:
moveRight();
break;
}
printf("%d\n", key);
}
int main()
{
//窗口, EX_SHOWCONSOLE显示控制台界面
initgraph(COL*GRID_SIZE+(COL+1)*INTERVAL, ROW*GRID_SIZE+(ROW+1)*INTERVAL, EX_SHOWCONSOLE);
init();
while (true)//一直的移动,一直的绘制
{
draw();
move();
}
getchar();//防止窗口闪退
return 0;
}
都是为了c语言课程设计啊-_-