用200行C语言代码写出一个贪吃蛇——1.0(基本版)

1.设计思路

总的来说,贪吃蛇这个小游戏涉及到的东西不多,但是对逻辑思维是比较吃基本功的。

贪吃蛇,显示给我们看的有三部分:蛇、食物、地图边界

我们可以用一个二维数组来标记这些部分:

例如这里我创建了一个 5*10 的二维数组,其中 -1 表食物, 1 表蛇头,2、3、4、5表蛇身,0表示空地。

如果我们想要蛇移动起来,只需要将 蛇尾置0 ,其余部分+1 就行了。

另外需要说明的是,我们使用 a s d w 来控制方向,这四个方向对应的整数分别是:3、2、1、0。

2.具体流程

3.源文件(主函数)main.c

#include "head.h"
int main()
{
	int map[SIZE][SIZE] = { 0 };//定义二维数组
	int len = 0;//定义长度
	int state = 0;//定义游戏状态
	int direc = 0;//定义方向
	Init_map(map, &len, &direc);//初始化地图
	while (1)
	{
		direc = get_direc(direc);//键盘读入方向
		state = move(map, direc, &len);//蛇的移动,在函数内部判断蛇头状态并返回值
		if (state == 0)//返回0表游戏结束
			break;
		else//继续游戏
			print(map);//打印
		Sleep(100);
	}
	return 0;
}

4.头文件head.h

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

#define SIZE 19

void Init_map(int map[SIZE][SIZE], int* len, int* direc);
int get_direc(int direc);
int move(int map[SIZE][SIZE], int direc, int* len);
void print(int map[SIZE][SIZE]);

5.源文件(函数内部)func.c

void Init_map(int map[SIZE][SIZE], int* len, int* direc)
{
	*len = 3;//初始化长度
	*direc = 2;//初始化方向

	map[5][5] = -1;//初始化食物
	
	//初始化蛇身
	map[3][3] = 3;
	map[4][3] = 2;

	map[5][3] = 1;//初始化蛇头
}

int get_direc(int direc)
{
	int tmp = -1;//定义一个用来接收键盘值的变量
	
	if (_kbhit())//如果键盘被敲击,kbhit()返回一个非0值
	{
		switch (_getch())//从键盘读入
		{
		case 'W':case 'w':tmp = 0; break;
		case 'D':case 'd':tmp = 1; break;
		case 'S':case 's':tmp = 2; break;
		case 'A':case 'a':tmp = 3; break;
		}
		//读入的键盘只能是 w、d、s、a,并且蛇不能掉头
		if (tmp != -1 && abs(direc - tmp) != 2)//abs函数是求绝对值
			direc = tmp;
	}
	return direc;
}

int move(int map[SIZE][SIZE], int direc, int* len)
{
	int i = 0;
	int j = 0;

	//定义蛇头位置
	int head_x = 0;
	int head_y = 0;

	//循环遍历数组
	for (i = 0; i < SIZE; i++)
	{
		for (j = 0; j < SIZE; j++)
		{
			if (map[i][j] == *len)//如果是蛇尾
				map[i][j] = 0;

			if (map[i][j] > 1)//如果是蛇身
				map[i][j] += 1;

			if (map[i][j] == 1)//如果是蛇头
			{
				map[i][j] += 1;

				//此时蛇头+1了,已经没有蛇头了,现在就要找到一个新的蛇头
				// 
				//找到原蛇头的原位置
				head_x = i;
				head_y = j;

				//找到蛇头移动后的位置
				switch (direc)
				{
				case 0:head_x = i - 1; head_y = j; break;
				case 1:head_x = i; head_y = j + 1; break;
				case 2:head_x = i + 1; head_y = j; break;
				case 3:head_x = i; head_y = j - 1; break;
				}
			}
		}
	}

	if (map[head_x][head_y] == -1)//如过蛇头位置是食物
	{
		*len = *len + 1;//吃掉食物,长度+1
		map[head_x][head_y] = 1;//吃掉食物,食物变成蛇头

		//重新生成食物
		while (1)
		{
			i = rand() % SIZE;
			j = rand() % SIZE;
			if (map[i][j] == 0)
			{
				map[i][j] = -1;
				break;
			}
		}
	}
	//如果蛇头碰到自己或墙
	else if (map[head_x][head_y] > 0 || head_x < 0 || head_x == SIZE || head_y < 0 || head_y == SIZE)
		return 0;//返回0
	else
		map[head_x][head_y] = 1;//没碰到食物、墙壁、自己

	return 1;//没碰到食物、墙壁、自己

}

void print(int map[SIZE][SIZE])
{
	//打印边框、食物、蛇用的符号根据自己的喜好来,是自由不受限制的
	system("cls");
	int i = 0;
	int j = 0;

	//打印上边框
	for (i = 0; i <= SIZE; i++)
	{
		if (i == 0)
			printf("┏");
		else if (i == SIZE)
			printf(" ┓");
		else
			printf(" ━");

	}
	printf("\n");

	//打印左、右边框,打印蛇头、蛇身、食物
	for (i = 0; i < SIZE; i++)
	{
		for (j = 0; j < SIZE; j++)
		{
			if (j == 0)
				printf("┃ ");
			else if (map[i][j] == -1)
				printf("★");
			else if (map[i][j] > 0)
				printf("○");
			else if (map[i][j] == 1)
				printf("●");
			else
				printf("  ");
			if (j == SIZE - 1)
				printf("┃");
		}
		printf("\n");
	}

	//打印下边框
	for (i = 0; i <= SIZE; i++)
	{
		if (i == 0)
			printf("┗");
		else if (i == SIZE)
			printf(" ┛");
		else
			printf(" ━");
	}
	printf("\n");
}

6.结束语

可以看到,我们除去无用的换行、注释部分,真正的代码不到200行。这只是一个有基本功能的贪吃蛇小游戏。希望大家在这个版本的基础上添加一些花里胡哨的功能。 

最后附上游戏效果截图。

 

  • 42
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论
用windows api 做的贪吃蛇 #include #include"resource.h" #include"Node.h" #include #include TCHAR szAppname[] = TEXT("Snack_eat"); #define SIDE (x_Client/80) #define x_Client 800 #define y_Client 800 #define X_MAX 800-20-SIDE //点x的范围 #define Y_MAX 800-60-SIDE //点y的范围 #define TIME_ID 1 #define SECOND 100 #define NUM_POINT 10 //点的总个数 #define ADD_SCORE 10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd; //窗口句柄 MSG msg; //消息 WNDCLASS wndclass; //窗口类 HACCEL hAccel;//加速键句柄 wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口的水平和垂直尺寸被改变时,窗口被重绘 wndclass.lpfnWndProc = WndProc; //窗口过程为WndProc函数 wndclass.cbClsExtra = 0; //预留额外空间 wndclass.cbWndExtra = 0; //预留额外空间 wndclass.hInstance = hInstance; //应用程序的实例句柄,WinMain的第一个参数 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //设置图标 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //载入预定义的鼠标指针 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置画刷 wndclass.lpszMenuName = szAppname; //设置菜单 wndclass.lpszClassName = szAppname; //设置窗口类的名字 if (!RegisterClass(&wndclass))//注册窗口类 { MessageBox(NULL, TEXT("这个程序需要windows NT!"), szAppname, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppname, TEXT("Snack_eat"),//CreateWindow函数调用时,WndProc将受到WM_CREATE WS_OVERLAPPEDWINDOW&~WS_THICKFRAME& ~WS_MAXIMIZEBOX,//普通的层叠窗口&禁止改变大小&禁止最大化 CW_USEDEFAULT, //初始x坐标(默认) CW_USEDEFAULT, //初始y坐标 x_Client, //初始x方向尺寸 770 y_Client, //初始y方向尺寸 750 NULL, //父窗口句柄 NULL, //窗口菜单句柄 hInstance, //程序实例句柄 WinMain函数中第二个参数 NULL); //创建参数 ShowWindow(hwnd, iCmdShow);//显示窗口,iCmdShow是WinMain的第四个参数,决定窗口在屏幕中的初始化显示形式,例:SW_SHOWNORMAL表示正常显示 UpdateWindow(hwnd);//使窗口客户区重绘,通过向WndProc发送一条WM_PAINT消息而完成的 hAccel = LoadAccelerators(hInstance, szAppname);//加载加速键 while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(hwnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }/* while (GetMessage(&msg, NULL, 0, 0))//GetMessage函数从消息队列中得到消息,填充msg。如果msg.message等于WM_QUIT,返回0,否则返回非0 { TranslateMessage(&msg);//将msg返回给windows已进某些键盘消息的转换 DispatchMessage(&msg);//将msg再次返回给windows }*/ return msg.wParam;//msg.wParam是PostQuitMessage函数的参数值,通常是0 } ...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小龙向钱进

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值