C++基于控制台实现的贪吃蛇小游戏
本文实例讲述了C++基于控制台实现的贪吃蛇小游戏。分享给大家供大家参考。具体实现方法如下:
#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;
}
}
}
效果图如下所示:
希望本文所述对大家的C++程序设计有所帮助。
以上是 C++基于控制台实现的贪吃蛇小游戏 的全部内容, 来源链接: utcz.com/z/325897.html