命令行之贪吃蛇
(可能有BUG,时间有限,只能写成这样了)
游戏截图 :
#include
#include
#include
#include
#include
#define Coord_x 15
#define Coord_y 15
#define Height 20
#define Width 18
using namespace std;
enum dir{u,d,l,r};
class Snake{
public:
int x;
int y;
int score;
int level;
int snake_speed;
Snake *prior, *next;
int vis[100][100];
char map[100][100];
int food_x;
int food_y;
int init_x;
int init_y;
dir point;
public:
Snake(int s = 0, int l = 1, int ss = 200);
void init_snake();
void add_head(int x, int y);
void delete_tail();
bool make_food();
void change_point(char);
void move();
void Display();
}S, *head = NULL, *tail = NULL;
class Console{
public:
void gotoxy(HANDLE hOut, int x, int y);
void enter_game();
void initialize_window();
void start_game();
void end_game();
friend class Snake;
}C;
void Console::gotoxy(HANDLE hOut, int x, int y)
{
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(hOut, pos);
}
void Console::enter_game()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
system("title 贪吃蛇 by Tc");
gotoxy(hOut,Coord_x+Width+1,Coord_y-11);
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
cout << "欢迎进入贪吃蛇";
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN);
gotoxy(hOut,Coord_x+Width-25,Coord_y-8);
cout << " * * * * * * * * * * * * " << endl;
gotoxy(hOut,Coord_x+Width-25,Coord_y-7);
cout << " * * ** * * * * * * " << endl;
gotoxy(hOut,Coord_x+Width-25,Coord_y-6);
cout << " * * * * * * * * * " << endl;
gotoxy(hOut,Coord_x+Width-25,Coord_y-5);
cout << " * * * * * * * * * * * * * " << endl;
gotoxy(hOut,Coord_x+Width-25,Coord_y-4);
cout << " * * * * * * * * * * * * " << endl;
gotoxy(hOut,Coord_x+Width-25,Coord_y-3);
cout << " * * * * * * * * * " << endl;
gotoxy(hOut,Coord_x+Width-25,Coord_y-2);
cout << " * * * ** * * * * * " << endl;
gotoxy(hOut,Coord_x+Width-25,Coord_y-1);
cout << " * * * * * * * * * * * * * " << endl;
gotoxy(hOut,Coord_x+Width,Coord_y+3);
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED);
cout << "按回车键进入游戏\n"<< endl;;
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN);
while(1)
{
char c;
if(kbhit())
{
c = getch();
if(c == 13)
{
system("CLS");
C.initialize_window();
C.start_game();
}
}
cout << "O" ;
Sleep(200);
}
if(getch() == 27)
{
C.end_game();
}
else
{
C.enter_game();
}
}
void Console::end_game()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
system("CLS");
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
gotoxy(hOut,Coord_x+Width+5,Coord_y-10);
cout << "游戏结束";
gotoxy(hOut,Coord_x+Width+5,Coord_y-7);
cout << "最终得分 : " << S.score << endl;
gotoxy(hOut,Coord_x+Width+5,Coord_y-5);
exit(0);
}
void Console::initialize_window()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
system("title 贪吃蛇 by Tc");
system("color 0C");
gotoxy(hOut,Coord_x+Width-4,Coord_y-2);
cout << "********";
gotoxy(hOut,Coord_x+Width-3,Coord_y-3);
cout << "贪吃蛇";
gotoxy(hOut,Coord_x+Width-4,Coord_y-4);
cout << "********";
gotoxy(hOut,Coord_x+2*Width+3,Coord_y-2);
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-18);
cout << "得分 : " << S.score << " 等级 : " << S.level;
gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-12);
cout << "w键 : 上 " << "s键 : 下";
gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-10);
cout << "a键 : 左 " << "d键 : 右";
gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-8);
cout << "空格键 :暂停";
gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-6);
cout << "Esc :退出";
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN);
for(int i = 0;i < 2 * Width - 1; i++)
{
S.vis[Coord_x + i][Coord_y - 1] = 2;
}
for(int i = 0;i < 2 * Width - 1; i++)
{
S.vis[Coord_x + i][Coord_y + Height] = 2;
}
for(int i = 0;i < 2 * Width-1; i += 2)
{
gotoxy(hOut,Coord_x + i,Coord_y - 1);
cout << "*";
}
for(int i = 0;i < 2 * Width-1; i += 2)
{
gotoxy(hOut,Coord_x + i,Coord_y + Height);
cout << "*";
}
for(int i = 0;i < Height;i++)
{
gotoxy(hOut,Coord_x,Coord_y+i);
cout << "*";
S.vis[Coord_x][Coord_y+i] = 2;
}
for(int i = 0;i < Height;i++)
{
gotoxy(hOut,Coord_x+2*Width-2,Coord_y+i);
cout << "*";
S.vis[Coord_x+2*Width-2][Coord_y+i] = 2;
}
}
Snake::Snake(int s, int l, int ss)
{
score = s;
level = l;
snake_speed = ss;
}
void Snake::add_head(int x, int y)
{
Snake *node = new Snake;
node -> x = x;
node -> y = y;
node -> next = head;
node -> prior = NULL;
if(head)
head -> prior = node;
head = node;
if(!tail)
tail = head;
S.map[x][y] = 'O';
S.vis[x][y] = 1;
}
void Snake::delete_tail()
{
Snake *t = tail;
S.map[ tail -> x ][ tail -> y ]= ' ';
S.vis[ tail -> x ][ tail -> y ] = 0;
if(tail == head)
tail = head = NULL;
else
{
tail = tail -> prior;
tail -> next = NULL;
}
delete t;
}
void Snake:: init_snake()
{
srand((unsigned) time(NULL));
S.init_x = Coord_x + 2 + rand() % 20;
S.init_y = Coord_y + 2 + rand() % 15;
}
void Snake::move()
{
int a, b;
a = head -> x;
b = head -> y;
switch(point)
{
case u: --b; break;
case d: ++b; break;
case l: --a; break;
case r: ++a; break;
}
if(S.vis[a][b] == 1 || S.vis[a][b] == 2)
{
C.end_game();
}
if(vis[a][b] == 3)
{
head -> add_head(a,b);
S.vis[a][b] = 1;
score += 10;
if(score % 50 == 0)
{
level++;
snake_speed -= 20;
}
while(!S.make_food());
}
else
{
head -> add_head(a,b);
head -> delete_tail();
}
}
void Snake::change_point(char keydown)
{
switch(keydown)
{
case 'w': point = u; break;
case 's': point = d; break;
case 'a': point = l; break;
case 'd': point = r; break;
}
}
bool Snake::make_food()
{
srand((unsigned int) time(NULL));
food_x = Coord_x + 1 + rand() % 34;
food_y = Coord_y + 1 + rand() % 18;
if(S.vis[food_x][food_y] == 0)
{
S.map[food_x][food_y] = 'O';
S.vis[food_x][food_y] = 3;
return true;
}
return false;
}
void Snake:: Display()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
for(int i = Coord_x + 1; i < Coord_x + 2 * Width - 2; i++)
{
for(int j = Coord_y; j < Coord_y + Height; j++)
{
C.gotoxy(hOut,i,j);
if(i == head -> x && j == head -> y)
{
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED);
cout << S.map[i][j];
}
else
{
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);
cout << S.map[i][j];
}
}
}
SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);
C.gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-18);
cout << "得分 : " << score << " 等级 : " << level;
}
void Console::start_game()
{
S.init_snake();
head -> add_head(S.init_x,S.init_y);
head -> add_head(S.init_x+1,S.init_y);
head -> add_head(S.init_x+2,S.init_y);
while(!S.make_food());
S.Display();
char keydown = '\0';
while(true)
{
char temp = keydown;
keydown = getch();
if(keydown == 27)
{
C.end_game();
}
S.change_point(keydown);
if(keydown == ' ')
{
S.Display();
while(true)
{
if(kbhit())
{
char ch = getch();
if(ch == ' ')
{
goto Loop;
}
}
}
}
if(temp == 'w' && keydown == 's')
{
S.point = u;
keydown = 'w';
}
else if(temp == 's' && keydown == 'w')
{
S.point = d;
keydown = 's';
}
else if(temp == 'a' && keydown == 'd')
{
S.point = l;
keydown = 'a';
}
else if(temp == 'd' && keydown == 'a')
{
S.point = r;
keydown = 'd';
}
Loop:
while(!kbhit())
{
S.move();
S.Display();
Sleep(S.snake_speed);
}
}
}
int main()
{
memset(S.vis,0,sizeof(S.vis));
memset(S.map,0,sizeof(S.map));
C.enter_game();
return 0;
}