[C语言] 实现简易2048小游戏

实现功能:

1.利用循环结构实现游戏基本功能,例如:重新开始,退出游戏,上下左右移动等。

2.采用文件流相关操作记录历史最高分,若玩家从未玩过,则默认最高分为0。

3.使用贴图操作完成相关界面(如下图所示,较为简陋)。

[C语言] 实现简易2048小游戏_第1张图片


 

实现代码:

#include
#include
#include
#include
#include

int shuzi[4][4] = { 0 };
int shifoujieshu = 1;//判断是否结束
int change = 1;//判断数组是否改变
long fenshu = 0;//本轮游戏分数
long lishizuijia = 0;//历史最高分
long zuidahechen;//最大合成数
int n;
IMAGE img[20];

void tupianxianshi(int i,int j,int n) {// 设置贴图
	int x = j * 106 + (j + 1) * 15;
	int y = i * 106 + (i + 1) * 15+160;// 坐标
	switch (n) {// 根据数值显示对应贴图
	case 2:
		loadimage(&img[1], "block_2.jpg");
		putimage(x, y, &img[1]);
		break;
	case 4:
		loadimage(&img[2], "block_4.jpg");
		putimage(x, y, &img[2]);
		break;
	case 8:
		loadimage(&img[3], "block_8.jpg");
		putimage(x, y, &img[3]);
		break;
	case 16:
		loadimage(&img[4], "block_16.jpg");
		putimage(x, y, &img[4]);
		break;
	case 32:
		loadimage(&img[5], "block_32.jpg");
		putimage(x, y, &img[5]);
		break;
	case 64:
		loadimage(&img[6], "block_64.jpg");
		putimage(x, y, &img[6]);
		break;
	case 128:
		loadimage(&img[7], "block_128.jpg");
		putimage(x, y, &img[7]);
		break;
	case 256:
		loadimage(&img[8], "block_256.jpg");
		putimage(x, y, &img[8]);
		break;
	case 512:
		loadimage(&img[9], "block_512.jpg");
		putimage(x, y, &img[9]); 
		break;
	case 1024:
		loadimage(&img[10], "block_1024.jpg");
		putimage(x, y, &img[10]);
		break;
	case 2048:
		loadimage(&img[11], "block_2048.jpg");
		putimage(x, y, &img[11]);
		break;
	case 4096:
		loadimage(&img[12], "block_4096.jpg");
		putimage(x, y, &img[12]);
		break;
	case 8192:
		loadimage(&img[13], "block_8192.jpg");
		putimage(x, y, &img[13]);
		break;
	case 16384:
		loadimage(&img[14], "block_16384.jpg");
		putimage(x, y, &img[14]);
		break;
	case 32768:
		loadimage(&img[15], "block_32768.jpg");
		putimage(x, y, &img[15]);
		break;
	case 65536:
		loadimage(&img[16], "block_65536.jpg");
		putimage(x, y, &img[16]);
		break;
	case 131072:
		loadimage(&img[17], "block_131072.jpg");
		putimage(x, y, &img[17]);
		break;
	}
}
int lishizuigao(long* lishizuijia) {
	FILE* fp;   //文件指针
	fopen_s(&fp, "fenshu.txt", "r");//打开文件,以只读的方式r
	if (fp == NULL)//如果文件不存在,打开文件,以写入的方式w
	{
		fopen_s(&fp, "fenshu.txt", "w");
		fprintf(fp, "%-10d", *lishizuijia);
	}
	else
		fscanf_s(fp, "%10d", lishizuijia);
	fclose(fp);//关闭文件
	return 0;
}
int zuidahech(long* zuidahechen) {
	FILE* fp1 ;   
	fopen_s(&fp1, "zuidahechen.txt", "r");
	if (fp1 == NULL)
	{
		fopen_s(&fp1, "zuidahechen.txt", "w");
		fprintf(fp1, "%-10d", *zuidahechen);
	}
	else
		fscanf_s(fp1, "%10d", zuidahechen);
	fclose(fp1);//关闭文件
	return 0;
}
void storeHighScore(long lishizuijia)
{
	FILE* fp;
	fopen_s(&fp, "fenshu.txt", "w");
	fprintf(fp, "%-10d", lishizuijia);
	fclose(fp);
}
void store(long zuidahechen)
{
	FILE* fp1;
	fopen_s(&fp1, "zuidahechen.txt", "w");
	fprintf(fp1, "%-10d", zuidahechen);
	fclose(fp1);
}
void jiemian() {
	system("CLS");
	int i, j, nn;
	initgraph(500, 660);// 设置界面
	loadimage(&img[18], "gamelogo.jpg", 239, 162);
	putimage(0, 0, &img[18]);
	loadimage(&img[19], "scorebg.jpg");
	putimage(239, 0, &img[19]);
	loadimage(&img[0], "background.jpg", 500, 500);
	putimage(0, 160, &img[0]);
	if (change == 1) {//生成随机数(2或4),且仅当数组改变时生成
		do {
			i = (unsigned)rand() % 4;
			j = (unsigned)rand() % 4;
		} while (shuzi[i][j] != 0);
		nn = (unsigned)rand() % 2;
		if (nn == 0)
			shuzi[i][j] = 2;
		else
			shuzi[i][j] = 4;
	}
	lishizuigao(&lishizuijia);
	if (fenshu > lishizuijia) {//判断分数是否超过历史最佳
			lishizuijia = fenshu;
			storeHighScore(lishizuijia);
     }
	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			if (shuzi[i][j]) //遍历数组,显示不为0的数字
				tupianxianshi(i, j, shuzi[i][j]);
			zuidahech(&zuidahechen);
			if (shuzi[i][j] > zuidahechen) {//寻找当前最大合成数
				zuidahechen = shuzi[i][j];
				store(zuidahechen);
			}
		}
	}
	char str[10], str1[15],str2[10];//在画布上显示分数
	setbkmode(TRANSPARENT);//设置背景为透明
	settextstyle(30, 0, _T("楷体"));
	sprintf_s(str, _T("%ld"), lishizuijia);
	outtextxy(350, 15, str);
	sprintf_s(str1, _T("%ld"), fenshu);
	outtextxy(350, 62, str1);
	sprintf_s(str2, _T("%ld"), zuidahechen);
	outtextxy(350, 110, str2);
}
int up() {//上移
	int i, j, k;
	for (j = 0; j < 4; j++) {// 判断上下数字是否相同,且中间是否存在间隔
		for (i = 0; i < 3; i++) {
			k = i + 1;
			while (shuzi[i][j] != 0) {//元素不为零时进行比较
				if (shuzi[i][j] == shuzi[k][j]) {
					change = 1;
					fenshu += shuzi[k][j]*2;
					shuzi[i][j] = shuzi[i][j] * 2;
					shuzi[k][j] = 0;
					break;
				}
				else {
					if (shuzi[k][j] != 0)//判断相同元素间是否存在间隔
						break;
					if (++k == 4)//判断完一行后,直接退出当前循环
						break;
				}
			}
		}
	}
	for (i = 0; i < 3; i++) {//合并数字后,上移
		for (j = 0; j < 4; j++) {
			k = i + 1;
			while(shuzi[i][j] == 0) {
				if (shuzi[k][j] != 0) {
					change = 1;
					shuzi[i][j] = shuzi[k][j];
					shuzi[k][j] = 0;
					break;
				}
				else {
					if (++k == 4)
						break;
				}
			}
		}
	}
	return change;
}
int down() {//下移
	int i, j, k;
	for (j = 0; j < 4; j++) {
		for (i = 3; i > 0; i--) {
			k = i - 1;
			while (shuzi[i][j] != 0) {
				if (shuzi[i][j] == shuzi[k][j]) {
					change = 1;
					fenshu += shuzi[k][j]*2;
					shuzi[i][j] = shuzi[i][j] * 2;
					shuzi[k][j] = 0;
					break;
				}
				else {
					if (shuzi[k][j] != 0)
						break;
					if (--k == -1)
						break;
				}
			}
		}
	}
	for (i = 3; i > 0; i--) {//合并数字后,下移
		for (j = 0; j < 4; j++) {
			k = i - 1;
			while (shuzi[i][j] == 0) {
				if (shuzi[k][j] != 0) {
					change = 1;
					shuzi[i][j] = shuzi[k][j];
					shuzi[k][j] = 0;
					break;
				}
				else {
					if (--k == -1)
						break;
				}
			}
		}
	}
	return change;
}
int left() {//左移
	int i, j, k;
	for (i = 0; i < 4; i++) {//判断左右数字是否相同,且中间是否存在间隔
		for (j = 0; j < 3; j++) {
			k = j + 1;
			while (shuzi[i][j] != 0) {
				if (shuzi[i][j] == shuzi[i][k]) {
					change = 1;
					fenshu += shuzi[i][k]*2;
					shuzi[i][j] = shuzi[i][j] * 2;
					shuzi[i][k] = 0;
					break;
				}
				else {
					if (shuzi[i][k] != 0)
						break;
					if (++k == 4)
						break;
				}
			}
		}
	}
	for (j = 0; j < 3; j++) {//数字合并后,左移
		for (i = 0; i < 4; i++) {
			k = j + 1;
			while (shuzi[i][j] == 0) {
				if (shuzi[i][k] != 0) {
					change = 1;
					shuzi[i][j] = shuzi[i][k];
					shuzi[i][k] = 0;
					break;
				}
				else {
					if (++k == 4)
						break;
				}
			}
		}
	}
	return change;
}
int right() {//右移
	int i, j, k;
	for (i = 0; i < 4; i++) {
		for (j = 3; j > 0; j--) {
			k = j - 1;
			while (shuzi[i][j] != 0) {
				if (shuzi[i][j] == shuzi[i][k]) {
					change = 1;
					fenshu += shuzi[i][k]*2;
					shuzi[i][j] = shuzi[i][j] * 2;
					shuzi[i][k] = 0;
					break;
				}
				else {
					if (shuzi[i][k] != 0)
						break;
					if (--k == -1)
						break;
				}
			}
		}
	}
	for (j = 3; j > 0; j--) {//数字合并后,右移
		for (i = 0; i < 4; i++) {
			k = j - 1;
			while (shuzi[i][j] == 0) {
				if (shuzi[i][k] != 0) {
					change = 1;
					shuzi[i][j] = shuzi[i][k];
					shuzi[i][k] = 0;
					break;
				}
				else {
					if (--k == -1)
						break;
				}
			}
		}
	}
	return change;
}
int cs() {//键盘操作移动
		char ch; change = 0;//int n=0;   //n用于判断是否退出游戏
		ch = _getch();
		switch (ch) {
		case 'w':
		case 'W':up();
			break;
		case'a':
		case'A':left();
			break;
		case's':
		case'S':down();
			break;
		case'd':
		case'D':right();
			break;
		case'n'://直接退出
			n = 1;
			shifoujieshu = 0;
			break;
		case'y'://重新开始
			n = 2;
			break;
		}
	return n;
}
int jieshu() {//判断是否结束
	int i, j;
	shifoujieshu = 0;
	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			if (shuzi[i][j] == 0) {//判断是否有空余位置
				shifoujieshu = 1;
			}
			if (i > 1) {
				if (shuzi[i][j] == shuzi[i - 1][j]) {//判断上下是否有相同的数相连
					shifoujieshu = 1;
				}
			}
			if (j > 1) {
				if (shuzi[i][j] == shuzi[i][j - 1]) {//判断左右是否有相同的数相连
					shifoujieshu = 1;
				}
			}
		}
	}
	if (shifoujieshu == 0) {
		loadimage(&img[12], "gameOver.jpg");
		putimage(100, 230, &img[12]);
	}
	return 0;
}
int main() {
    //int n;
	srand((unsigned)time(NULL));
	while (shifoujieshu == 1) {
		
		jiemian();
		if (n != 1) {
			n = cs();
		}
		if (n == 0) {
			jieshu();
			if (shifoujieshu == 0) {//判断是否进入下一局
				char ch = _getch();
				if (ch == 'y') {
					for (int i = 0; i < 4; i++) {
						for (int j = 0; j < 4; j++) {
							shuzi[i][j] = 0;
						}
					}
					shifoujieshu = 1;
					change = 1;
					fenshu = 0;
				}
			}
		}
		else if(n == 1) {//判断是否直接结束
			break;
		}
		else if (n == 2) {//判断是否重新开始
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 4; j++) {
						shuzi[i][j] = 0;
				}
			}
			change = 1;
			fenshu = 0;
		}
	}
	return 0;
}

你可能感兴趣的:(c语言)