首页 > 代码库 > 简单的贪吃蛇

简单的贪吃蛇

最近都在忙着复习考试,忙里偷闲,抽出时间写了个贪吃蛇,没时间写详细的思路了,代码里有比较详细的注释,有兴趣的同学可以自己看看。(感觉写的相对来说还是比较简短的,如果有什么写的不好或是不对的地方,欢迎各位指出)。在写这个贪吃蛇时,我省去了很多不必要的功能,只实现了最基本的功能,界面也比较粗糙,游戏功能也不见得很完善,只是为了用尽量少的代码来实现主体功能,大家可以在这个基础上进行修改和完善。




/*--------------------------------------------------------------
名称: 简单的贪吃蛇
开发环境:VC++ 6.0
类型:控制台应用程序
完成时间:2014.06.20
开发原则:大道至简,只实现了最基本的功能,没有添加什么复杂的功能
作者:风语
运用的技术:双缓存,防止闪屏
---------------------------------------------------------------*/
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

#define CMD_UP			1
#define CMD_DOWN		2
#define CMD_LEFT		4
#define CMD_RIGHT		8
#define CMD_QUIT		16

const int MAXN = 1000;
bool flag, tag;
int num, dir, score, a[MAXN];//num表示蛇节点的数目,dir表示蛇前进方向(0,1,2,3)(上下左右)
POINT d[4] = {{0, -10}, {0, 10}, {-10, 0}, {10, 0}};//方向向量
POINT food, node[MAXN];//node蛇的节点坐标
POINT wall[10] = {{20, 10}, {460, 10}, {460, 350}, {20, 350}, {20, 10},
				{39, 29}, {441, 29}, {441, 331}, {39, 331}, {39, 29}};//墙
HDC hdc = NULL, mdc = NULL;//mdc内存dc
HWND hwnd = FindWindow("ConsoleWindowClass", NULL);//窗口句柄
HBRUSH hbrush;//画刷
HPEN hpen;//画笔
HBITMAP	bmp;//位图

void CreateFood()		//产生食物
{
	if(tag) return; //tag == true,表明食物存在
	while(!tag)//直到产生的食物在有效位置为止
	{
		food.x = 10 * (rand() % 40) + 40;
		food.y = 10 * (rand() % 30) + 30;
		Rectangle(mdc, food.x, food.y, food.x + 10, food.y + 10);
		tag = true;
		//检测食物是否产生在蛇身上,如果在,标记食物为不存在
		for(int i = 0; i < 4 * num; i++)
		{
			if(food.x == node[i].x && food.y == node[i].y)
			{
				tag = false;
				break;
			}
		}
		
	}
}

void Gotoxy(int x,int y)    //设置光标的位置
{
      COORD coord;
      coord.X = x - 1;
	  coord.Y = y - 1;
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

void GameInit()		//游戏初始化
{
	srand(unsigned(time(NULL)));
	num = 6; dir = 3; score = 0;
	flag = true;//flag==true标记游戏可以进行
	tag  = false;
	system("color F0");//设置控制台背景和前景颜色

	hdc = GetDC(hwnd);
	mdc = CreateCompatibleDC(hdc);//创建兼容dc
	bmp	= CreateCompatibleBitmap(hdc, 640, 480);//创建兼容位图
	SelectObject(mdc, bmp);

	hbrush = CreateSolidBrush(RGB(0, 255, 0));  
	SelectObject(mdc, hbrush); 

	RECT rect;//将mdc背景色设置为白色
	GetClientRect(hwnd, &rect);	
	hbrush = CreateSolidBrush(RGB(255, 255, 255)); 
	FillRect(mdc, &rect, hbrush); 

	Polygon(mdc, wall, 10);//绘制墙

	Gotoxy(45, 25);

	int t = 4 * num - 1;//初始化蛇
	node[t].x   = 40; node[t].y   = 30;
	node[t-1].x = 40; node[t-1].y = 40;
	node[t-2].x = 50; node[t-2].y = 40;
	node[t-3].x = 50; node[t-3].y = 30;
	for(int i = t - 4; i >= 0; i--)
	{
		node[i].x = node[i + 4].x + 10;
		node[i].y = node[i + 4].y;
	}
	for(i = 0; i < MAXN; i++)
	{
		a[i] = 4;
	}
}

void GetDir()		//根据用户输入,获取蛇,新的移动方向
{  
    int c = 0;  
	if (GetAsyncKeyState(VK_UP)		& 0x8000)	c |= CMD_UP;  
    if (GetAsyncKeyState(VK_DOWN)	& 0x8000)	c |= CMD_DOWN;  
    if (GetAsyncKeyState(VK_LEFT)	& 0x8000)	c |= CMD_LEFT;  
    if (GetAsyncKeyState(VK_RIGHT)	& 0x8000)	c |= CMD_RIGHT;  
    if (GetAsyncKeyState(VK_ESCAPE)	& 0x8000)	c |= CMD_QUIT; 
	
	if (c & CMD_UP)		if(1 != dir) dir = 0;
    if (c & CMD_DOWN)	if(0 != dir) dir = 1;
    if (c & CMD_LEFT)	if(3 != dir) dir = 2;
    if (c & CMD_RIGHT)	if(2 != dir) dir = 3;
    if (c & CMD_QUIT)   flag = false; 
}

void Release()		//释放资源
{
	DeleteObject(hbrush);  
	DeleteObject(hpen);
	DeleteObject(bmp);
	DeleteDC(mdc);
	ReleaseDC(hwnd, hdc);
}

void MoveHead()		//蛇的头结点的移动
{
	for(int i = 0; i < 4; i++)
	{
		node[i].x += d[dir].x;
		node[i].y += d[dir].y;
	}
}

void Translate()//传递蛇身,前一个节点的位置是下一个节点下一步要到的位置
{
	for(int i = 4 * num - 1; i >= 4; i--)
	{
		node[i].x = node[i-4].x;
		node[i].y = node[i-4].y;
	}
}

void GameOver()		//游戏结束与否
{
	if(node[0].x > 440 || node[0].x < 50 || node[0].y > 320 || node[0].y < 30)
		flag = false;//撞墙
	for(int i = 4; i < 4 * num; i += 4)//咬自己
	{
		if(node[0].x == node[i].x && node[0].y == node[i].y && 
			node[2].x == node[i+2].x && node[2].y == node[i+2].y)
		{
			flag = false;
			return;
		}
	}
}

void PaintSnake()			//绘制出蛇
{
	PolyPolygon(mdc, node, a, num);
}

void EatFood()		//检测蛇是否吃到食物
{
	if(node[0].x == food.x + 10 && node[0].y == food.y)
	{
		tag = false;
		num++;
		score += 10;
	}
}

int main()
{
	GameInit();
	while(flag)
	{
		GetDir(); 
		Translate();
		MoveHead();	
		EatFood();

		GameOver();

		/*绘制出蛇*/
		hpen = (HPEN)GetStockObject(BLACK_PEN);
		SelectObject(mdc, hpen);
		hbrush = CreateSolidBrush(RGB(0, 0, 0));  
		SelectObject(mdc, hbrush);  

		CreateFood();
		PaintSnake();

		BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);//将图像从内存dc拷贝到当前窗口
		if(!flag) break;

		/*擦除蛇运动留下的阴影*/
		hpen = (HPEN)GetStockObject(WHITE_PEN);
		SelectObject(mdc, hpen);
		hbrush = CreateSolidBrush(RGB(255, 255, 255));  
		SelectObject(mdc, hbrush);
		PaintSnake();	

		char str[256];//绘制得分
		sprintf(str, "score : %d", score);
		TextOut(mdc, 465, 200, str, strlen(str));
		Sleep(80);
	}
	Gotoxy(40, 25);
	Sleep(3000);
	Release();
	return 0;
}