现在的位置: 首页 > 综合 > 正文

基于控制台的贪吃蛇小游戏

2012年03月31日 ⁄ 综合 ⁄ 共 5945字 ⁄ 字号 评论关闭
#include <windows.h>
#include <time.h>
#include <stdio.h>

#define MAX			100
#define UP				1
#define DOWN		2
#define LEFT			3
#define RIGHT		4
#define MOVING	5
#define STOP			0

HANDLE hMain_Out = NULL;
HANDLE hMain_In = NULL;
struct Pos
{
	int x;
	int y;
};
struct Body
{
	int state;
	int len;
	int Direction;
//	int ZZZZ;
//	int HHHH;
	Pos pos[MAX];
};

Pos NewPos[MAX];
Pos Food;
SMALL_RECT Wall;
int count = 0;
int grade = 0;
int level = 1;
int amount = 0;
int speed = 200;

void Init(Body &b);
void Print(const Body &b);
void Print(int x,int y);
void Move(Body &b);
void Clean(int x,int y);
void Clean(const Body &b);
void ShowInfo();
int GetDirection(Body &b);
void TurnRound(int Direction,Body &b);
void PosCopy(Body &b,Pos NewPos[]);
void MoveBody(Body &b);
void HideCursor();
void CreateWall();
void CreateFood();
bool IsKnock_Food(const Body &b);
bool IsKnock_Wall(const Body &b);
void AddBody(Body &b);

int main()
{
	Body b;
	Init(b);
	Print(b);

	HideCursor();

	while(TRUE)
	{
		Sleep(speed);
		Move(b);

		GetDirection(b);
	}

	return 0;
}

void Init(Body &b)
{
	b.len = 3;
	b.Direction = RIGHT;
	b.state = STOP;
	b.pos[0].x = 2;
	b.pos[0].y = 1;
	b.pos[1].x = 4;
	b.pos[1].y = 1;
	b.pos[2].x = 6;
	b.pos[2].y = 1;

	hMain_Out = GetStdHandle(STD_OUTPUT_HANDLE);
	hMain_In = GetStdHandle(STD_INPUT_HANDLE);

	CreateWall();
	CreateFood();

	ShowInfo();
}
void Print(const Body &b)
{
	COORD coord;
	
	for(int ix = b.len -1;ix >= 0;--ix)
	{
		coord.X = b.pos[ix].x;
		coord.Y = b.pos[ix].y;
		SetConsoleCursorPosition(hMain_Out,coord);
		printf("●");
	}

}
void Move(Body &b)
{
	ShowInfo();

	if(IsKnock_Wall(b))
	{
		MessageBox(NULL,"You are dead !","Oh my God",0);
		exit(0);
	}

	if(IsKnock_Food(b))
	{
		if(amount > 5)
		{
			++level;
			amount = 0;
			speed-= 50;

		}
		AddBody(b);

		grade += 10;
		++amount;
		Clean(Food.x,Food.y);

		CreateFood();
	}

	if(STOP == b.state)
	{
		if(RIGHT == b.Direction)
		{
			for(int ix = 0;ix < b.len;++ix)
			{
				Clean(b.pos[ix].x,b.pos[ix].y);
				b.pos[ix].x+=2;
			}
		}

		if(UP == b.Direction)
		{
			for(int ix = 0;ix < b.len;++ix)
			{
				Clean(b.pos[ix].x,b.pos[ix].y);
				b.pos[ix].y--;
			}
		}

		if(DOWN == b.Direction)
		{
			for(int ix = 0;ix < b.len;++ix)
			{
				Clean(b.pos[ix].x,b.pos[ix].y);
				b.pos[ix].y++;
			}
		}

		if(LEFT == b.Direction)
		{
			for(int ix = 0;ix < b.len;++ix)
			{
				Clean(b.pos[ix].x,b.pos[ix].y);
				b.pos[ix].x-=2;
			}
		}
		
	}

	if(MOVING == b.state)
	{
		PosCopy(b,NewPos);
		if(UP == b.Direction)
		{
			if(b.len == count)
			{
				b.state = STOP;
				b.Direction = UP;
				count = 0;
			}
			if(count < b.len && MOVING == b.state)
			{
				b.pos[b.len - 1].y--;
				Clean(b.pos[0].x,b.pos[0].y);
				MoveBody(b);
				Print(b);
			}
		
		}
		if(DOWN == b.Direction)
		{
			if(b.len == count)
			{
				b.state = STOP;
				b.Direction = DOWN;
				count = 0;
			}
			if(count < b.len && MOVING == b.state)
			{
				b.pos[b.len - 1].y++;
				Clean(b.pos[0].x,b.pos[0].y);
				MoveBody(b);
				Print(b);
			}
		}
		if(LEFT == b.Direction)
		{
			if(b.len == count)
			{
				b.state = STOP;
				b.Direction = LEFT;
				count = 0;
			}
			if(count < b.len && MOVING == b.state)
			{
				b.pos[b.len - 1].x-=2;
				Clean(b.pos[0].x,b.pos[0].y);
				MoveBody(b);
				Print(b);
			}
				
		}
		if(RIGHT == b.Direction)
		{
			if(b.len == count)
			{
				b.state = STOP;
				b.Direction = RIGHT;
				count = 0;
			}
			if(count < b.len && MOVING == b.state)
			{
				b.pos[b.len - 1].x+=2;
				Clean(b.pos[0].x,b.pos[0].y);
				MoveBody(b);
				Print(b);
			}	
		}
	}
	

	Print(b);
}
void Clean(int x,int y)
{
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition(hMain_Out,c);
	printf(" ");
}
void Clean(const Body &b)
{
	for(int ix = 0;ix < b.len;++ix)
	{
		Clean(b.pos[ix].x,b.pos[ix].y);
	}
}
int GetDirection(Body &b)
{
	if(GetAsyncKeyState(VK_UP))
	{
		count = 0;
		TurnRound(UP,b);
	}

	if(GetAsyncKeyState(VK_DOWN))
	{
		count = 0;
		TurnRound(DOWN,b);
	}

	if(GetAsyncKeyState(VK_LEFT))
	{
		count = 0;
		TurnRound(LEFT,b);
	}

	if(GetAsyncKeyState(VK_RIGHT))
	{
		count = 0;
		TurnRound(RIGHT,b);
	}

	return 0;
}
void TurnRound(int d,Body &b)
{
	switch(d)
	{
	case UP:
		if(RIGHT == b.Direction || LEFT == b.Direction)
		{
			PosCopy(b,NewPos);
			--b.pos[b.len -1].y;
			Clean(b.pos[0].x,b.pos[0].y);
			MoveBody(b);
			Print(b);
			b.Direction = d;
			b.state = MOVING;
		}
		break;
	case DOWN:
		if(RIGHT == b.Direction || LEFT == b.Direction)
		{
	
			PosCopy(b,NewPos);
			++b.pos[b.len -1].y;
			Clean(b.pos[0].x,b.pos[0].y);
			MoveBody(b);
			Print(b);
			b.Direction = d;
			b.state = MOVING;
		}
		break;
	case LEFT:
		if(UP == b.Direction || DOWN == b.Direction)
		{
			PosCopy(b,NewPos);
			b.pos[b.len -1].x-=2;
			Clean(b.pos[0].x,b.pos[0].y);
			MoveBody(b);
			Print(b);
			b.Direction = d;
			b.state = MOVING;
		}
		break;
	case RIGHT:
		if(UP == b.Direction || DOWN == b.Direction)
		{
			PosCopy(b,NewPos);
			b.pos[b.len -1].x+=2;
			Clean(b.pos[0].x,b.pos[0].y);
			MoveBody(b);
			Print(b);
			b.Direction = d;
			b.state = MOVING;
		}
		break;
	default:
		break;
	}
}
void PosCopy(Body &b,Pos NewPos[])
{
	for(int ix = 0;ix < b.len;++ix)
	{
		NewPos[ix].x=0;
		NewPos[ix].y=0;
	}
	for(int ix = 0;ix <b.len;++ix)
	{
		NewPos[ix] = b.pos[ix];
	}
}

void MoveBody(Body &b)
{
	for(int ix = b.len - 1;ix > 0;--ix)
	{
		b.pos[ix - 1] = NewPos[ix];
	}

	++count;
	PosCopy(b,NewPos);
}

void HideCursor()
{
	CONSOLE_CURSOR_INFO info;
	GetConsoleCursorInfo(hMain_Out,&info);
	info.bVisible = FALSE;
	SetConsoleCursorInfo(hMain_Out,&info);
}

void CreateWall()
{
	CONSOLE_SCREEN_BUFFER_INFO info;
	GetConsoleScreenBufferInfo(hMain_Out,&info);
	info.srWindow.Right-=19;
	info.srWindow.Bottom-=5;
	Wall = info.srWindow;


	for(int i = 0;i <= info.srWindow.Right;i+=2)
	{
		Print(i,info.srWindow.Top);
		Print(i,info.srWindow.Bottom);
	}
	for(int y = 0;y <= info.srWindow.Bottom;++y)
	{
		Print(0,y);
		Print(info.srWindow.Right,y);
	}

}

void Print(int x,int y)
{
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition(hMain_Out,c);

	printf("■");
}

void CreateFood()
{
	srand(unsigned(time(NULL)));
	unsigned x_t = RAND_MAX  / Wall.Right;
	unsigned y_t = RAND_MAX  / Wall.Bottom;

	while(true)
	{
		int x = rand() / x_t;
		int y = rand() / y_t;

		Food.x = x - 4;
		Food.y = y - 4;

		if((0 == Food.x % 2)  &&  (0 == Food.y % 2))
		{
			if(Food.x < 5)
			{
				Food.x+=8;
			}
			if(Food.y<5)
			{
				Food.y+=8;
			}

			Print(Food.x,Food.y);
			break;
		}
	}

}

bool IsKnock_Food(const Body &b)
{
	if(b.pos[b.len - 1].x == Food.x && b.pos[b.len - 1].y== Food.y)
	{
		return true;
	}
	else
	{
		return false;
	}
}

bool IsKnock_Wall(const Body &b)
{
	if(0 == b.pos[b.len - 1].x || 0 == b.pos[b.len - 1].y || Wall.Right == b.pos[b.len - 1].x || Wall.Bottom == b.pos[b.len - 1].y)
	{
		return true;
	}

	Pos Head = b.pos[b.len - 1];
	for(int ix = 0;ix <= b.len - 3;++ix)
	{
		if(Head.x == b.pos[ix].x && Head.y == b.pos[ix].y)
		{
			return true;
		}
	}

	return false;
}

void ShowInfo()
{
	COORD c;
	c.X = Wall.Right + 2;
	c.Y = 3;

	SetConsoleCursorPosition(hMain_Out,c);
	printf("   分数:%d",grade);

	c.Y+=10;
	SetConsoleCursorPosition(hMain_Out,c);
	printf("   难度等级:%d",level);

}

void AddBody(Body &b)
{
	if(b.len < MAX)
	{
		if(UP == b.Direction)
		{
			b.pos[b.len].y = b.pos[b.len - 1].y - 1;
			b.pos[b.len].x = b.pos[b.len - 1].x;
			++b.len;
		}
		if(DOWN == b.Direction)
		{
			b.pos[b.len].y = b.pos[b.len - 1].y + 1;
			b.pos[b.len].x = b.pos[b.len - 1].x;
			++b.len;
		}
		if(LEFT == b.Direction)
		{
			b.pos[b.len].x = b.pos[b.len - 1].x - 2;
			b.pos[b.len].y = b.pos[b.len - 1].y;
			++b.len;
		}
		if(RIGHT == b.Direction)
		{
			b.pos[b.len].x = b.pos[b.len - 1].x + 2;
			b.pos[b.len].y = b.pos[b.len - 1].y;
			++b.len;
		}

	}
}

 效果图:

 

 

 

 

抱歉!评论已关闭.