C++控制台下的贪吃蛇
这是我大一第一个学期无聊写的一个小游戏,我记得当时写这个的时候还是挺激动的,现在大二了,回过头来看看这些代码,太笨拙了,但是毕竟时间有限,而且这个是我写的第一个游戏,不想去改了,就这样了吧。贴个代码留做纪念吧!高手勿喷啊!!
//2014.12.12日Mr.Xiong 制作
#include <iostream>
#include <cstdio>
#include <string>
#include <iomanip>
#include <conio.h>
#include <ctime>
#include <windows.h>
#define ESC 27 /*ESC 的ASCII码*/
using namespace std;
const int G_MAPX = 23;//宽度
const int G_MAPY = 24;//长度
int G_MAP[G_MAPX][G_MAPY] = { 0 };
const int Blank = 0;
const int Obstacle = 1;
const int Snake = 2;
const int Food = 3;
int Lenght = 4;
double Settime = 9;
double Speed = 3000 / Settime;//初始值为0.3
int i, j; //循环变量
bool FoodExist = false;//用于判断失误存在与否
enum G_Direction { UP, DOWN, LEFT, RIGHT };
G_Direction NowDirec = DOWN;//记录本次移动的方向
G_Direction PrevDirec;//记录上一次的方向
void SetBackground();//设置背景
void ShowBackground();//背景输出
void gotoxy(int x, int y); //移动光标的函数到指定的位置的的函数
void Hidden();//光标隐藏
void GameOver();
void ShowTime();//显示系统时间
class SnakeNode {
private:
SnakeNode *front, *next;
public:
int x, y;
void AddSnakeHead(int xx, int yy);
void DelSnakeTail();
int GetSnakeX() {
return x;
}
int GetSnakeY() {
return y;
}
void Release();
}*Head = NULL, *Tail = NULL;
void SnakeNode::AddSnakeHead(int xx, int yy) {
SnakeNode *prt = new SnakeNode;
prt->x = xx;
prt->y = yy;
if(Head != NULL) {
prt->next = Head;
Head->front = prt;
Head = prt;
} else {
Head = Tail = prt;
Tail->next = NULL;
}
gotoxy(prt->x, prt->y);
cout << setw(2) << "●";
}
void SnakeNode::DelSnakeTail() {
SnakeNode *Temp = Tail;
Tail = Temp->front;
Tail->next = NULL;
gotoxy(Temp->x, Temp->y);
cout << setw(2) << " ";
delete Temp;
}
void SnakeNode::Release() { //释放所有空间
SnakeNode *p = Head;
while(p->next == NULL) {
p = p->next;
delete p->front;
}
delete Head;
Head = NULL;
Tail == NULL;
}
class FOOD {
public:
int FoodX, FoodY;
void CreateFood();
int GetFoodX() {
return FoodX;
}
int GetFoodY() {
return FoodY;
}
} FD;
void FOOD::CreateFood() {
srand((unsigned)time(NULL));
FoodX = rand() % (G_MAPX - 1) + 1;
FoodY = rand() % (G_MAPY - 3) + 1; //》》》》》》》》》》??????此处可以改进??????????
gotoxy(FoodX, FoodY);
G_MAP[FoodX][FoodY] = Food;//多余的话
FoodExist = true;
cout << setw(2) << "★";
}
class Move {
private:
char Key;
public:
int x1, y1, FFoodX, FFoodY;
G_Direction GetGirection();
void Moving();
bool Hitwall();
bool OppositeDirec();//容错性,判断是否用户是否错误输入了运动相反的方向
} SK;
bool Move::OppositeDirec() {
if((PrevDirec == UP && NowDirec == DOWN) || (PrevDirec == DOWN && NowDirec == UP) || (PrevDirec == LEFT && NowDirec == RIGHT) || (PrevDirec == RIGHT && NowDirec == LEFT))
return true;
else
return false;
}
bool Move::Hitwall() { //判断是否撞墙
if (x1 == 0 || x1 == G_MAPY - 1 || y1 == 0 || y1 == G_MAPX - 1)
return true;
else
return false;
}
G_Direction Move::GetGirection() {
if(_kbhit()) {
PrevDirec = NowDirec;
Key = _getch();
switch (Key) {
case 0x48:
NowDirec = UP;
break;
case 0x50:
NowDirec = DOWN;
break;
case 0x4b:
NowDirec = LEFT;
break;
case 0x4d:
NowDirec = RIGHT;
break;
default:
break;
}
fflush(stdin);
if(OppositeDirec())//容错性。如果用户输入方向错误,则不执行
NowDirec = PrevDirec;
} else
Moving();
}
void Move::Moving() {
x1 = Head->GetSnakeX();
y1 = Head->GetSnakeY();
switch (NowDirec) {
case UP:
y1--;
break;
case DOWN:
y1++;
break;
case LEFT:
x1--;
break;
case RIGHT:
x1++;
break;
default:
break;
}
Head->AddSnakeHead(x1, y1);
Tail->DelSnakeTail();
ShowTime();
if(!FoodExist) {
FD.CreateFood();
}
FFoodX = FD.GetFoodX();
FFoodY = FD.GetFoodY();
if(x1 == FFoodX && y1 == FFoodY) {
Lenght++;
Speed -= 50;
FoodExist = false;
Head->AddSnakeHead(x1, y1); //加一个节点
}
if (Hitwall() == true)
GameOver();
Sleep(Speed);
GetGirection();
}
int main() {
Hidden();
SetBackground();
ShowBackground();//描绘背景图
Head->AddSnakeHead(2, 3); //设置蛇的初始长度与位置
Head->AddSnakeHead(2, 4);
Head->AddSnakeHead(2, 5);
Head->AddSnakeHead(2, 6);
while(1) {
SK.GetGirection();
SK.Moving();
}
return 0;
}
/*****************************功能函数区*******************************/
void SetBackground() {
for(i = 0; i < G_MAPX; i++) {
for(j = 0; j < G_MAPY; j++) {
if(i == 0 || i == G_MAPX - 1 || j == 0 || j == G_MAPY - 1)
G_MAP[i][j] = Obstacle;
}
}
}
void ShowBackground() {
system("color 2e"); //设置背景颜色
cout << "\n\n\n\n\n\n\t\t\t****兴旺贪吃蛇****";
cout << ",就";
Sleep(700);
cout << "是";
Sleep(700);
cout << "不";
Sleep(700);
cout << "yi";
Sleep(700);
cout << "样~~~";
cout << "\n\n\n\n\n\n\t\t\t\t\t\t\tTip:↑↓←→控制方向";
cout << "\n\n\n\n\n\n\n\n\n\t\t\t\t\t\t\t\tLoading";
cout << ".";
Sleep(300);
cout << ".";
Sleep(300);
cout << ".";
Sleep(900);
system("cls");
for (i = 0; i < G_MAPX; i++) {
for (j = 0; j < G_MAPY; j++) {
if (G_MAP[i][j] == Obstacle)
cout << setw(2) << "▉";
else cout << setw(2) << " ";
}
if (i == 2) cout << " >>>兴旺贪吃蛇<<<";
else if (i == G_MAPX - 5) cout << "\t当前速度:";
else if (i == G_MAPX - 3)cout << "\t当前时间:";
cout << endl;
}
}
void gotoxy(int x, int y) { //移动光标的函数到指定的位置的的函数
COORD loc = { 2 * x, y };
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput, loc);
}
void Hidden() { //光标隐藏
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO hidden;
GetConsoleCursorInfo(hOut, &hidden);
hidden.bVisible = 0;
SetConsoleCursorInfo(hOut, &hidden);
}
void GameOver() {
Sleep(3000);
Head->Release();
system("cls");
cout << "\n\n\n\t\t******************************\n";
cout << "\t\t\tGAME OVER!\n";
cout << "\t\t******************************\n";
Sleep(2000);
exit(0);
}
void ShowTime() {
gotoxy(G_MAPX + 2, G_MAPY - 3); // 显示当前时间
SYSTEMTIME m_time;
GetLocalTime(&m_time);
int a = m_time.wHour;
int b = m_time.wMinute;
int c = m_time.wSecond;
cout << "\t\t\t" << setw(2) << a << ":" << b << ":" << c << endl;
}
运行效果就这样吧,丑了些而已!~~