1100多行实现贪吃蛇,带颜色,有速度选择,有难度选择,有分数保存和读取等。
#include <iostream>
#include <windows.h>
#include <conio.h>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <istream>
#include <fstream>
using namespace std;
void hide_cursor()
{
CONSOLE_CURSOR_INFO cci = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}
//enum Direction{UP,LEFT,DOWN,RIGHT}D,D_temp;
//int i,j;
//int speed;//空格键ASCII 32 回车 13 Esc 27
//int diff;
void gotoxy(int x,int y)
{
COORD loc={x,y};
HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput,loc);
}
class Interface
{
public:
void Display();//开始界面
void Empty();//清空界面
void Dis_Help();//帮助界面
int Move();//移动箭头
int Speed_();//速度选择界面
int Difficulty();//难度选择界面
void Colour(int c);//颜色
int R_Speed();//返回速度数值
int R_Diff();//返回难度数值
private:
int r,l;
char ch;
int Speed,Diff;
};
int Interface::R_Speed()
{
return Speed;
}
int Interface::R_Diff()
{
return Diff;
}
void Interface::Colour(int c)
{
switch(c)
{
case 1:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);//红色
break;
case 2:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);//绿色
break;
case 3:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);//蓝色
break;
case 4:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);//设置红色和绿色相加
break;
case 5:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);//设置红色和蓝色相加
break;
case 6:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);//设置绿色和蓝色相加
break;
default:
break;
}
}
void Interface::Empty()
{
for(int i=1;i<24;i++)
{
for(int j=1;j<79;j++)
{
gotoxy(j,i);
cout << " ";
}
}
}
void Interface::Display()
{
Empty();
Colour(4);
gotoxy(37,6);
cout << "贪 吃 蛇 ";
r = 10;
Sleep(100);
gotoxy(36,r);
cout << "开 始 游 戏 " ;
Sleep(100);
r = r + 2 ;
gotoxy(36,r);
cout << "游 戏 记 录 " ;
Sleep(100);
r = r + 2 ;
gotoxy(36,r);
cout << "游 戏 帮 助 " ;
Sleep(100);
r = r + 2;
gotoxy(36,r);
cout << "退 出 游 戏 " ;
}
void Interface::Dis_Help()
{
Empty();
Colour(5);
gotoxy(20,8);
cout << "W(w)S(s)A(a)D(d)来控制上下左右\n";
gotoxy(20,10);
cout << "空格(Space)来进行开始游戏或者暂停游戏\n";
gotoxy(20,12);
cout << "回车(Enter)来开始进行所选择的选项\n";
gotoxy(28,14);
cout << "按下Esc返回上层界面!";
ch = getch();
while(ch!=27)
{
ch = getch();
}
Empty();
}
int Interface::Move()
{
r = r - 6 ;
Colour(4);
gotoxy(34,r);
cout << ">" ;
gotoxy(48,r);
cout << "<" ;
ch = getch();
while(ch!=13)
{
switch(ch)
{
case 'w':
case 'W':
if(r==12 || r==14 || r==16)
{
gotoxy(34,r);
cout << " ";
gotoxy(48,r);
cout << " ";
r = r - 2 ;
gotoxy(34,r);
cout << ">";
gotoxy(48,r);
cout << "<";
break;
}
else
break;
case 's':
case 'S':
if(r==10 || r==12 || r==14)
{
gotoxy(34,r);
cout << " ";
gotoxy(48,r);
cout << " ";
r = r + 2;
gotoxy(34,r);
cout << ">";
gotoxy(48,r);
cout << "<";
break;
}
else
break;
default:
break;
}
ch = getch();
}
if(ch == 13)
{
return r;
}
}
int Interface::Speed_()
{
Empty();
int s;
Sleep(100);
gotoxy(33,5);
cout << "选 择 速 度";
r = 8;
Sleep(100);
gotoxy(36,r);
cout << "入 门 " ;
r = r + 2 ;
Sleep(100);
gotoxy(36,r);
cout << "初 级 " ;
r = r + 2 ;
Sleep(100);
gotoxy(36,r);
cout << "中 级 " ;
r = r + 2;
Sleep(100);
gotoxy(36,r);
cout << "高 级 " ;
r = r - 6 ;
gotoxy(34,r);
cout << ">" ;
gotoxy(42,r);
cout << "<" ;
ch = getch();
while(ch!=27 && ch!=13)
{
switch(ch)
{
case 'W':
case 'w':
if(r==10 || r==12 || r==14)
{
gotoxy(34,r);
cout << " ";
gotoxy(42,r);
cout << " ";
r = r - 2 ;
gotoxy(34,r);
cout << ">";
gotoxy(42,r);
cout << "<";
break;
}
else
break;
case 'S':
case 's':
if(r==8 || r==10 || r==12)
{
gotoxy(34,r);
cout << " ";
gotoxy(42,r);
cout << " ";
r = r + 2;
gotoxy(34,r);
cout << ">";
gotoxy(42,r);
cout << "<";
break;
}
else
break;
default:
break;
}
ch = getch();
}
if(ch==27)
{
return 2;
}
if(ch==13)
{
switch(r)
{
case 8:
Speed = 200;
return 1;
break;
case 10:
Speed = 150;
return 1;
break;
case 12:
Speed = 100;
return 1;
break;
case 14:
Speed = 50;
return 1;
break;
}
}
}
int Interface::Difficulty()
{
Empty();
int s;
Sleep(100);
gotoxy(33,5);
cout << "选 择 难 度";
r = 8;
Sleep(100);
gotoxy(36,r);
cout << "入 门 " ;
r = r + 2 ;
Sleep(100);
gotoxy(36,r);
cout << "初 级 " ;
r = r + 2 ;
Sleep(100);
gotoxy(36,r);
cout << "中 级 " ;
r = r + 2;
Sleep(100);
gotoxy(36,r);
cout << "高 级 " ;
r = r - 6 ;
gotoxy(34,r);
cout << ">" ;
gotoxy(42,r);
cout << "<" ;
ch = getch();
while(ch!=27 && ch!=13)
{
switch(ch)
{
case 'W':
case 'w':
if(r==10 || r==12 || r==14)
{
gotoxy(34,r);
cout << " ";
gotoxy(42,r);
cout << " ";
r = r - 2 ;
gotoxy(34,r);
cout << ">";
gotoxy(42,r);
cout << "<";
break;
}
else
break;
case 'S':
case 's':
if(r==8 || r==10 || r==12)
{
gotoxy(34,r);
cout << " ";
gotoxy(42,r);
cout << " ";
r = r + 2;
gotoxy(34,r);
cout << ">";
gotoxy(42,r);
cout << "<";
break;
}
else
break;
default:
break;
}
ch = getch();
}
if(ch==27)
{
return 2;
}
if(ch==13)
{
switch(r)
{
case 8:
Diff = 1;
return 1;
break;
case 10:
Diff = 2;
return 1;
break;
case 12:
Diff = 3;
return 1;
break;
case 14:
Diff = 4;
return 1;
break;
}
}
}
class Wall
{
public:
friend class Snake;
friend class Food;
void Display(Interface &I);//开始时界面
int Dis_(Interface &I);//进入游戏分割分数与游戏
void Dis_W(Interface &I);//按照各种难度输出墙
void Display1(Interface &I);//结束时界面
private:
int w[100][2];
int q;//不同难度数组个数不一样
};
int Wall::Dis_(Interface &I)
{
I.Empty();
for(int i=1;i<40;i++)
{
I.Colour(2);
gotoxy(i,4);
cout << "#";
gotoxy(79-i,4);
cout << "#";
Sleep(50);
}
}
void Wall::Display(Interface &I)
{
int i,j;
for(i=0;i<13;i++)//高0-24,宽0-79空白范围是1到23 1 到77
{
if(i==0 || i==12)
I.Colour(2);
if(i==1 || i==11)
I.Colour(5);
if(i==2 || i==10)
I.Colour(4);
if(i==3 || i==9)
I.Colour(3);
if(i==4 || i==8)
I.Colour(6);
if(i==5 || i==7)
I.Colour(1);
for(j=0;j<80;j++)
{
if(i%2==0 && i!=12)
{
gotoxy(j,i);
cout << "#";
gotoxy(79-j,24-i);
cout << "#";
}
if(i%2==1)
{
gotoxy(79-j,i);
cout << "#";
gotoxy(j,24-i);
cout << "#";
}
if(i == 12)
{
gotoxy(j,i);
cout << "#";
gotoxy(79-j,i);
cout << "#";
}
Sleep(5);
}
}
for(i=39;i>=1;i--)//39 40 为最中间
{
if(i == 39)
{
for(j=12;j>=1;j--)
{
gotoxy(39,j);
cout << " ";
gotoxy(39,24-j);
cout << " ";
gotoxy(40,j);
cout << " ";
gotoxy(40,24-j);
cout << " ";
Sleep(200);
}
}
else
{
for(j=1;j<=23;j++)
{
gotoxy(i,j);
cout << " ";
gotoxy(79-i,j);
cout << " ";
}
Sleep(100);
}
}
for(i=1;i<24;i++)
{
I.Colour(2);
gotoxy(0,i);
cout << "#";
gotoxy(79,24-i);
cout << "#";
Sleep(50);
}
}
void Wall::Dis_W(Interface &I)
{
int i,j,D;
D = I.R_Diff();
int a=1,b=78,c=5,d=23;
if(D == 1)
{
q=0;
}
if(D == 2)
{
I.Colour(2);
for(i=0;i<40;i++)
{
if(i<15)
{
w[i][0] = a++;
w[i][1] = 10;
}
if(i>=15 && i<20)
{
w[i][0] = 42;
w[i][1] = c++;
}
if(i>=20 && i<30)
{
w[i][0] = b--;
w[i][1] = 15;
}
if(i>=30)
{
w[i][0] = 30;
w[i][1] = d--;
}
}
}
if(D == 3)
{
I.Colour(2);
for(i=0;i<75;i++)
{
if(i<31)
{
w[i][0] = a++;
w[i][1] = 14;
}
if(i>=31 && i<38)
{
w[i][0] = 40;
w[i][1] = c++;
}
if(i>=38 && i<68)
{
w[i][0] = b--;
w[i][1] = 14;
}
if(i>=68)
{
w[i][0] = 40;
w[i][1] = d--;
}
}
}
if(D == 4)
{
I.Colour(2);
int c1=c,c2=c,d1=d,d2=d;
for(i=0;i<60;i++)
{
if(i<9)
{
w[i][0] = a++;
w[i][1] = 14;
}
if(i>=9 && i<18)
{
w[i][0] = b--;
w[i][1] = 14;
}
if(i>=18 && i<25)
{
w[i][0] = 40;
w[i][1] = c++;
}
if(i>=25 && i<32)
{
w[i][0] = 40;
w[i][1] = d--;
}
if(i>=32 && i<39)
{
w[i][0] = 20;
w[i][1] = c1++;
}
if(i>=39 && i<46)
{
w[i][0] = 20;
w[i][1] = d1--;
}
if(i>=46 && i<53)
{
w[i][0] = 60;
w[i][1] = c2++;
}
if(i>=53)
{
w[i][0] = 60;
w[i][1] = d2--;
}
}
}
if(D != 1)
{
if(D==2)
q = 40;
if(D==3)
q = 75;
if(D==4)
q = 60;
for(i=0;i<q;i++)
{
gotoxy(w[i][0],w[i][1]);
cout << "#";
}
}
}
void Wall::Display1(Interface &I)
{
int i,j;
for(i=1;i<=39;i++)//39 40 为最中间
{
I.Colour(2);
if(i == 39)
{
for(j=1;j<=12;j++)
{
gotoxy(39,j);
cout << "#";
gotoxy(39,24-j);
cout << "#";
gotoxy(40,j);
cout << "#";
gotoxy(40,24-j);
cout << "#";
Sleep(200);
}
}
else
{
for(j=1;j<=23;j++)
{
gotoxy(i,j);
cout << "#";
gotoxy(79-i,j);
cout << "#";
}
Sleep(100);
}
}
}
class Snake
{
public:
friend class Food;
void Grade();//游戏进行时动态输出成绩
void Init(Interface &I);//初始化信息,以及输出难度和速度
void Draw(Interface &I);//画出蛇
int Control();//控制
void Move_Snake();//根据指令移动蛇
int Death_Grow(const Wall &W);//判断蛇死亡
void Grade_S1(Interface &I);//死亡后输出成绩以及判断上榜
void Armory(Interface &I);//英雄榜
void R_File();
void W_File();
private:
int s[100][2];//0列 1行
int size_Snake,grade_Snake;
int G[3];
enum Direction{UP,LEFT,DOWN,RIGHT}D,D_temp;
};
void Snake::Grade_S1(Interface &I)
{
for(int i=8;i<18;i++)
{
for(int j=30;j<49;j++)
{
gotoxy(j,i);
cout << " ";
}
}
for(int i=8;i<18;i++)
{
I.Colour(1);
for(int j=30;j<49;j++)
{
if(i==8 || i==17 || j==30 || j==48)
{
gotoxy(j,i);
cout << "#";
}
}
}
int c=0,v=0;
if(grade_Snake>G[0])
{
v++;
G[2] = G[1];
G[1] = G[0];
G[0] = grade_Snake;
gotoxy(35,10);
cout << "新 纪 录 ";
gotoxy(35,12);
cout << "第 一 名 ";
gotoxy(32,14);
cout << "您 的 成 绩 :";
cout << grade_Snake;
c++;
}
if(grade_Snake>G[1] && grade_Snake<=G[0] && v==0)
{
v++;
G[1] = grade_Snake;
gotoxy(35,10);
cout << "新 纪 录 ";
gotoxy(35,12);
cout << "第 二 名 ";
gotoxy(32,14);
cout << "您 的 成 绩 :";
cout << grade_Snake;
c++;
}
if(grade_Snake>G[2] && grade_Snake<=G[1] && v==0)
{
G[2] = grade_Snake;
gotoxy(35,10);
cout << "新 纪 录 ";
gotoxy(35,12);
cout << "第 三 名 ";
gotoxy(32,14);
cout << "您 的 成 绩 :";
cout << grade_Snake;
c++;
}
if(c==0)
{
gotoxy(35,10);
cout << "GANE OVER!";
gotoxy(32,13);
cout << "您 的 成 绩 :";
cout << grade_Snake;
}
}
void Snake::Grade()
{
gotoxy(55,2);
cout << size_Snake;
gotoxy(72,2);
cout << grade_Snake;
}
void Snake::Init(Interface &I)
{
size_Snake = 3;
grade_Snake = 0;
D = RIGHT;
D_temp = RIGHT;
s[0][0] = 10;
s[0][1] = 8;
for(int i=1;i<size_Snake;i++)
{
s[i][0] = s[i-1][0] - 1;
s[i][1] = s[i-1][1];
}
s[3][0] = 0;
Draw(I);
gotoxy(28,2);
cout << " ";
I.Colour(5);
gotoxy(6,2);
cout << "速 度:";
int D,S;
D = I.R_Diff();
switch(D)
{
case 1:
cout << "入 门";
break;
case 2:
cout << "初 级";
break;
case 3:
cout << "中 级";
break;
case 4:
cout << "高 级";
break;
}
gotoxy(25,2);
cout << "难 度:";
S = I.R_Speed();
switch(S)
{
case 200:
cout << "入 门";
break;
case 150:
cout << "初 级";
break;
case 100:
cout << "中 级";
break;
case 50:
cout << "高 级";
break;
}
gotoxy(46,2);
cout << "蛇 长:" ;
gotoxy(64,2);
cout << "分 数:" ;
}
void Snake::Draw(Interface &I)
{
int i,c;
srand((unsigned)time(NULL));
c = 1 + rand() % 6;
I.Colour(c);
gotoxy(s[0][0],s[0][1]);//画出蛇头
cout << "@";
for(i=1;i<size_Snake;i++)//画出其他部分
{
gotoxy(s[i][0],s[i][1]);
cout << "*";
}
if(s[i][0] != 0)//将最后一节输出空格,不等于0是因为防止第二次游戏输出多余空格
{
gotoxy(s[i][0],s[i][1]);
cout << " ";
}
}
int Snake::Control()
{
char ch;
if(!_kbhit())
return 1;
ch = getch();
switch(ch)
{
case 'w':
case 'W':
D_temp = UP;
break;
case 's':
case 'S':
D_temp = DOWN;
break;
case 'a':
case 'A':
D_temp = LEFT;
break;
case 'd':
case 'D':
D_temp = RIGHT;
break;
case 32:
return 0;
break;
}
}
void Snake::Move_Snake()
{
for(int i=size_Snake-1;i>=0;i--)//记录没有移动前的位置
{
s[i+1][0] = s[i][0];
s[i+1][1] = s[i][1];
}
if(D != (D_temp+2)%4)//判断是否反向运动
{
D = D_temp;//改变方向
}
switch(D)//根据移动方向改变蛇头的位置
{
case UP:
s[0][1]--;
break;
case DOWN:
s[0][1]++;
break;
case LEFT:
s[0][0]--;
break;
case RIGHT:
s[0][0]++;
break;
}
}
int Snake::Death_Grow(const Wall &W)
{
//int q = W.R_q();
//int (*p)[2];
//p = W.R_w();
//int w[100][2];
if(s[0][0] >= 79 || s[0][0] <=0 || s[0][1] >=24 || s[0][1]<=4)
{
return 1;
}
for(int i=1;i<size_Snake;i++)
{
if(s[0][0]==s[i][0] && s[0][1]==s[i][1])
return 1;
}
for(int j=0;j<W.q;j++)
{
if(s[0][0]==W.w[j][0] && s[0][1]==W.w[j][1])
return 1;
}
}
void Snake::Armory(Interface &I)
{
char ch;
I.Empty();
I.Colour(6);
gotoxy(36,5);
cout << "英 雄 榜 ";
for(int i=0;i<3;i++)
{
gotoxy(36,8+3*i);
cout << "第" << i+1 << "名:";
cout << G[i];
}
ch = getch();
while(ch!=27)
{
ch = getch();
}
I.Empty();
}
void Snake::R_File()
{
ifstream infile("Armory.txt",ios::in);
if(!infile)
{
ofstream outfile("Armory.txt",ios::trunc);
for(int i=0;i<3;i++)
G[i] = 0;
for(int i=0;i<3;i++)
outfile << G[i] << " ";
}
else
{
for(int i=0;i<3;i++)
infile >> G[i];
}
}
void Snake::W_File()
{
ofstream outfile("Armory.txt",ios::out);
if(!outfile)
{
cout << "error!";
}
else
{
for(int i=0;i<3;i++)
outfile << G[i] << " ";
}
outfile.close();
}
class Food
{
public:
void Init_Food();//初始化
void Create_Food(const Snake &s,const Wall &w);//产生食物
void Judge_Food(Snake &s,Interface &I);//判断吃食物
void Draw_Food(Interface &I);//画出食物
private:
int f[1][2];
};
void Food::Init_Food()
{
f[0][0] = 0;
f[0][1] = 0;
}
void Food::Judge_Food(Snake &s,Interface &I)
{
int S,D;
S = I.R_Speed();
D = I.R_Diff();
if(f[0][0]==s.s[0][0] && f[0][1]==s.s[0][1])
{
s.size_Snake++;
switch(S)
{
case 200:
s.grade_Snake = s.grade_Snake + 1*D;
break;
case 150:
s.grade_Snake = s.grade_Snake + 2*D;
break;
case 100:
s.grade_Snake = s.grade_Snake + 3*D;
break;
case 50:
s.grade_Snake = s.grade_Snake + 4*D;
}
f[0][0] = 0;
f[0][1] = 0;
}
}
void Food::Create_Food(const Snake &s,const Wall &w)
{
int x=0;
srand((unsigned)time(NULL));
if(f[0][0]==0)
{
while(1)
{
f[0][0] = 1 + rand() % 78;
f[0][1] = 5 + rand() % 19;
for(int i=0;i<s.size_Snake;i++)
{
if(f[0][0]==s.s[i][0] && f[0][1]==s.s[i][1])
{
x = 1;
}
}
for(int i=0;i<w.q;i++)
{
if(f[0][0]==w.w[i][0] && f[0][1]==w.w[i][1])
{
x = 1;
}
}
if(x == 0)
break;
}
}
}
void Food::Draw_Food(Interface &I)
{
I.Colour(6);
gotoxy(f[0][0],f[0][1]);
cout << "&";
}
int main()
{
hide_cursor();
int c,s,m,n;
char ch;
Wall W;
Snake S;
S.R_File();
Food F;
Interface I;
W.Display(I);
while(1)
{
I.Display();
c = I.Move();
if(c == 10)//开始游戏
{
while(1)//选择难度
{
m = I.Difficulty();
if(m==2)
break;
while(1)
{
s = I.Speed_();//速度选择界面
if(s == 1)//选择速度后
{
W.Dis_(I);
S.Init(I);
F.Init_Food();
S.Grade();
ch = 1;
while(ch!=32 || ch!=27)
{
ch = getch();
if(ch==27)
{
break;
}
if(ch==32)
{
s = 3;
break;
}
}
}
if(s == 2)//返回
{
break;
}
if(s == 3)//选择开始
{
while(1)//游戏进行界面
{
if(s == 1)//游戏运行一次后
{
S.Grade_S1(I);
while(1)//能能按下Esc或者Space
{
ch = getch();
if(ch == 27 || ch==32)
break;
}
}
if(ch==27)//返回
break;
if(ch==32&&s==1)//再次进入游戏界面
{
W.Dis_(I);
S.Init(I);
F.Init_Food();
S.Grade();
while(1)//开始或者返回
{
ch = getch();
if(ch == 27 || ch==32)
break;
}
}
if(ch==27)
break;
while(1)//游戏运行
{
W.Dis_W(I);
F.Create_Food(S,W);//创建食物
F.Draw_Food(I);//画出食物
F.Judge_Food(S,I);//判断食物来增加蛇长度和分数
n = S.Control();//用户下达指令
if(n == 0)//暂停后
{
while(1)
{
ch = getch();
if(ch ==27 || ch ==32)
break;
}
if(ch == 27)
break;
}
S.Move_Snake();//根据指令移动蛇
s = S.Death_Grow(W);//判断蛇是否死亡
if(s==1)//死亡返回1 并推出
{
break;
}
S.Grade();//显示成绩
S.Draw(I);//画蛇
Sleep(I.R_Speed());//速度
}
}
}
}
}
}
if(c == 12)
{
S.Armory(I);
}
if(c == 14)
{
I.Dis_Help();
}
if(c == 16)
{
S.W_File();
W.Display1(I);
gotoxy(0,25);
exit(0);
}
}
return 0;
}