1.随机传送
2.鼠标选点传送
3.食物躲避蛇的追击
4.蛇自动搜索路径
5.贪吃蛇的基本操作
这是这个贪吃蛇的大概内容
代码如下:
/*
作者:黄铭杰
QQ:1024725390
最后修改日期:2018.6.19
*/
#include<time.h>
#include<stdio.h>
#include<string.h>
#include <conio.h>
#include<windows.h>
#include<iostream.h>
#define ontimer(C,MS,CODE) (clock()-C>(MS)&&((CODE),C=clock()))//定义计时器ontime(计时变量,间隔时间,需要执行的表达式)
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow (); //GetConsoleWindow ()函数声明
HWND hwnd=GetConsoleWindow(); //窗口句柄
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE); //输出句柄
HWND hwnd1=GetActiveWindow(); //绘图窗口句柄
UINT map[35][35]={0},tally[2]={0},x,y,x1,y1,x2,y2,x3,y3,a=100,b=100,c1=100,d1=100,score,speed,flag,ch=0,diffcult,time1[3]={0};
typedef struct she
{
int x,y;
char dir; //方向
she *next;
}snake;
snake *head = new snake,*tail = head;
void color(char a); //颜色函数
void __cdecl outtextxy(int x,int y,const char *str,...); //控制输出
void Hide(); //隐藏光标
void move(int x,int y); //蛇移动
void add(int x,int y); //蛇增长
void dead(); //死亡判断
void change(); //改变方向
void door(); //随机传送
void superdoor(); //鼠标选点传送
void AI(); //食物躲避蛇的追击判断
void AI2(); //鬼畜模式,食物随机移动,因为比例不同 食物更高几率大范围移动
void AI3(); //不可思议走位模式 为了游戏可玩性,限制食物的范围
int mima(); //管理员密码
void startgame(); //开始游戏
void window(); //窗口建立
void menu(); //主菜单
void end(); //死亡销毁链表
bool road(char ch); //代练路径
void AI6(); //代练
void POSE(); //暂停
void __cdecl outtextxy(int x,int y,const char *str,...) //控制输出
{
COORD pos={y*2,x}; //控制光标位置
SetConsoleCursorPosition(hOut,pos); //通过修改pos.X和pos.Y的值就可以实现光标的位置控制
va_list arg_ptr; //va_list 型变量
va_start(arg_ptr,str); //宏初始化该变量
//va_arg(arg_ptr,char); //对后面的变量进行处理
vprintf(str,arg_ptr); //输出
va_end(arg_ptr); //将存放可变参数字符串的变量清空
}
void color(char a)//颜色函数
{
if(a=='1')
SetConsoleTextAttribute(hOut,FOREGROUND_INTENSITY|FOREGROUND_RED); //是API设置字体颜色和背景色的函数,GetStdHandle是一个Windows API函数。它用于从一个特定的标准设备中取得一个句柄
if(a=='2')
SetConsoleTextAttribute(hOut,FOREGROUND_INTENSITY|FOREGROUND_GREEN);
if(a=='3')
SetConsoleTextAttribute(hOut,FOREGROUND_GREEN|FOREGROUND_BLUE);
}
void Hide() //隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
/*void locate()
{
LONG zx = -1;
LONG zy = -1;
POINT ptB = { 0, 0 };
while (1)
{
LPPOINT xy = &ptB; //位置变量
GetCursorPos(xy); //获取鼠标当前位置
ScreenToClient(hwnd1, &ptB); // 将鼠标指针位置转换为窗口坐标
//如果鼠标移动,(即当前的坐标改变则打印出坐标)打印出做坐标。
if ((zx != xy->x) || (zy != xy->y))
{
zx = xy->x;
zy = xy->y;
if(GetAsyncKeyState(VK_LBUTTON))
{
x3=(zy-30)/16;
y3=(zx-10)/16;
if(x3<35&&y3<35)break;
}
}
}
}*/
void move(int x,int y) //蛇移动
{
char di;
di=head->dir;
map[tail->x][tail->y]=0;
outtextxy(head->x,head->y,"■");
outtextxy(tail->x,tail->y," ");
head->next=tail;
head=head->next;
map[x][y]=1;
head->x=x;
head->y=y;
head->dir=di;
outtextxy(x,y,"◆");
tail=tail->next;
}
void add(int x,int y) //蛇增长
{
outtextxy(head->x,head->y,"■");
head->next=new snake;
head->next->dir=head->dir;
head=head->next;
head->x=x;
head->y=y;
map[x][y]=1;
outtextxy(x,y,"◆");
x1=rand()%35; /
y1=rand()%35;
map[x1][y1]=2;
outtextxy(x1,y1,"★");
outtextxy(8,42,"%d ",score+=50);
outtextxy(4,42,"%d ",speed>60?--speed:speed);
}
void dead() //死亡判断
{
if(head->dir=='W')
{
if(x>0 && map[x-1][y]==0)
move(--x,y);
else if(map[x-1][y]==2)
add(--x,y);
else
end();
}
else if(head->dir=='A')
{
if(y>0 && map[x][y-1]==0)
move(x,--y);
else if(map[x][y-1]==2)
add(x,--y);
else
end();
}
else if(head->dir=='S')
{
if(x<34 && map[x+1][y]==0)
move(++x,y);
else if(map[x+1][y]==2)
add(++x,y);
else
end();
}
else if(head->dir=='D')
{
if(y<34 && map[x][y+1]==0)
move(x,++y);
else if(map[x][y+1]==2)
add(x,++y);
else
end();
}
}
void change() //改变方向
{
if(GetAsyncKeyState('W')& 1)
{
if(head->dir!='S')
head->dir='W';
}
else if(GetAsyncKeyState('A')& 1)
{
if(head->dir!='D')
head->dir='A';
}
else if(GetAsyncKeyState('S')& 1)
{
if(head->dir!='W')
head->dir='S';
}
else if(GetAsyncKeyState('D')& 1)
{
if(head->dir!='A')
head->dir='D';
}
else if(GetAsyncKeyState('E'))
door();
else if(GetAsyncKeyState('R'))
superdoor();
else if(GetAsyncKeyState('P')& 1)
POSE();
if(c1!=100&&d1!=100)
{
outtextxy(c1,d1,"卍");
outtextxy(x3,y3,"卍");
if(tail->x==c1 && tail->y==d1)
{
outtextxy(c1,d1," ");
outtextxy(x3,y3," ");
c1=100;d1=100;
}
}
if(a!=100&&b!=100)
{
outtextxy(a,b,"卍");
outtextxy(x2,y2,"卍");
if(tail->x==a&&tail->y==b)
{
outtextxy(a,b," ");
outtextxy(x2,y2," ");
a=100;b=100;
}
}
dead();
}
void POSE()//暂停
{
while(1)
{
if(GetAsyncKeyState('P')& 1)break;
}
}
void door() //随机传送
{
if(score>=100)
{
while(1)
{
x2=rand()%35;
y2=rand()%35;
if(!map[x2][y2])
break;
}
a=x;b=y;
x=x2;y=y2;
outtextxy(8,42,"%d ",score-=100);
}
}
void superdoor() //鼠标选点传送
{
RECT rect;
GetWindowRect(hwnd,&rect); //获取窗口左上角坐标
int left = rect.left;
int top = rect.top;
LONG zx = -1;
LONG zy = -1;
POINT ptB = { 0, 0 };
if(score>=300)
{
//locate();
while (1)
{
LPPOINT xy = &ptB; //位置变量
GetCursorPos(xy); //获取鼠标当前位置
ScreenToClient(hwnd1, &ptB); // 将鼠标指针位置转换为窗口坐标
//如果鼠标移动,(即当前的坐标改变则打印出坐标)打印出做坐标。
/*if ((zx != xy->x) || (zy != xy->y))
{
zx = xy->x;
zy = xy->y;
if(GetAsyncKeyState(VK_LBUTTON))
{
x3=(zy-30)/16;
y3=(zx-10)/16;
if(x3<35&&y3<35)break;
}
} */
/*if(GetAsyncKeyState(VK_LBUTTON))
{
x3=(xy->y-23)/16;
y3=xy->x/16;
if(GetAsyncKeyState(VK_LBUTTON) && x3<35&&y3<35)break;
}*/
if(GetAsyncKeyState(VK_LBUTTON))
{
//outtextxy(5,42,"%d %d",xy->x,xy->y);
x3=(xy->y-30-top)/16;
y3=(xy->x-10-left)/16;
if(GetAsyncKeyState(VK_LBUTTON) && x3<35&&y3<35)break;
}
}
c1=x;d1=y;
x=x3;y=y3;
outtextxy(8,42,"%d ",score-=300);
}
}
void AI() //食物躲避蛇的追击判断
{
if(y1!=y&&x1<=x&&x1>0&&!map[x1-1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[--x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1!=y&&x1>=x&&x1<34&&!map[x1+1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[++x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1<=y&&y1>0&&!map[x1][y1-1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[x1][--y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1>=y&&y1<34&&!map[x1][y1+1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[x1][++y1]=2;
outtextxy(x1,y1,"★");
}
}
void AI2() //鬼畜模式,食物随机移动,因为比例不同 食物更高几率大范围移动
{
flag=rand()%11;
if(flag<2&&x1>0&&!map[x1-1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[--x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(flag<5&&y1>0&&!map[x1][y1-1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[x1][--y1]=2;
outtextxy(x1,y1,"★");
}
else if(flag<7&&x1<34&&!map[x1+1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[++x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(flag<11&&y1<34&&!map[x1][y1+1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[x1][++y1]=2;
outtextxy(x1,y1,"★");
}
}
void AI3() //不可思议走位模式 为了游戏可玩性,限制食物的范围
{
if(y1!=y&&x1<=x&&x1>6&&!map[x1-1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[--x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1!=y&&x1>=x&&x1<26&&!map[x1+1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[++x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1<=y&&y1>6&&!map[x1][y1-1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[x1][--y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1>=y&&y1<26&&!map[x1][y1+1])
{
map[x1][y1]=0;
outtextxy(x1,y1," ");
map[x1][++y1]=2;
outtextxy(x1,y1,"★");
}
}
int mima() //管理员密码
{
system("cls");
cout<<"\n\n\n\n\n\n"<<" 输入管理密码"<<endl;
/*char str[10];
cin>>str;
if(strcmp(str,"HUANG")==0)*/
char str;
str=_getch();
if(str=='H')
return 1;
else
return 0;
}
void startgame() //开始游戏
{
while(1)
{
if(GetKeyState(VK_SPACE)&0x80)//如果空格键是按下状态,将速度临时调整至60ms
ontimer(time1[0],60,change());
else
ontimer(time1[1],speed,change());//否则按照变量ms的速度运行游戏
if(diffcult=='2')
ontimer(time1[2],speed*3/2,AI());
else if(diffcult=='3')
ontimer(time1[2],speed*3/2,AI());
else if(diffcult=='4')
ontimer(time1[2],speed*6/5,AI());
else if(diffcult=='5')
ontimer(time1[2],110,AI3());
else if(diffcult=='6')
ontimer(time1[2],40,AI2());
else if(diffcult=='7')
AI6();
}
}
void window()//窗口建立
{
SetConsoleTitle("黄铭杰贪吃蛇");//设定窗口标题
//MoveWindow(hwnd,-10,-10,600,800,1);//窗口位置
system("mode con lines=35 cols=100");//设定窗口大小
Hide();
map[15][16]=1;
x=15;y=16;
head->x=15;
head->y=16;
if(diffcult=='3')
score=40000;
else score=400;
speed=260;
for(int i=0;i<35;++i)
outtextxy(i,35,"▓");
outtextxy(2,41,"游戏速度");
outtextxy(4,42,"%d",speed);
outtextxy(6,42,"得分");
outtextxy(8,42,"%d",score);
outtextxy(10,38,"P键暂停,继续再按一次");
outtextxy(12,41,"游戏规则");
outtextxy(15,39,"鼠标、方向键操作");
outtextxy(17,40," E、R键技能");
outtextxy(19,42,"W");
outtextxy(21,40," A S D");
outtextxy(23,39,"按下空格临时加速");
outtextxy(25,37,"E键随机传送消耗100积分");
outtextxy(28,37,"R键指定传送消耗300积分");
outtextxy(29,37,"指定操作 鼠标左键选点");
outtextxy(31,39,"作者:黄铭杰");
outtextxy(15,12,"按方向键开始游戏");
for(ch=getch();ch!='W'&&ch!='A'&&ch!='S'&&ch!='D';ch=getch());head->dir=ch;
outtextxy(15,10," ");
srand((unsigned) time(NULL));
x1=rand()%35;
y1=rand()%35;
map[x1][y1]=2;
outtextxy(x1,y1,"★");
outtextxy(15,16,"◆");
startgame();
}
void menu()//主菜单
{
system("cls");
cout<<"\n\n\n\n\n\n"<<" 输入你想要的模式\n\n"<<" 1->新手玩家\n\n"<<" 2->正常玩家\n\n"<<" 3->氪金玩家\n\n"<<" 4->困难模式(一区河蟹)\n\n"<<" 5->地狱模式(不可思议的走位)\n\n"<<" 6->鬼畜模式(这食物可能是刚放出来)\n\n"<<" 7->代练(卢老爷)"<<endl;
while(1)
{
diffcult=_getch();
if(diffcult>'0' && diffcult<'8')break;
}
if(diffcult=='7')
{
if(mima())
window();
else
{
menu();
window();
}
}
}
void end() //死亡销毁链表
{
while(tail!=head) //释放链表
{
she *temp=tail->next;
free(tail);
tail=temp;
}
memset(map,0,sizeof(map));
system("cls");
outtextxy(10,14," d888b .d8b. .88b d88. d88888b");
outtextxy(11,14,"88' Y8b d8' `8b 88'YbdP`88 88'");
outtextxy(12,14,"88 88ooo88 88 88 88 88ooooo");
outtextxy(13,14,"88 ooo 88~~~88 88 88 88 88~~~~~");
outtextxy(14,14,"88. ~8~ 88 88 88 88 88 88.");
outtextxy(15,14," Y888P YP YP YP YP YP Y88888P");
outtextxy(16,14,"\t\t .d88b. db db d88888b d8888b.");
outtextxy(17,14,"\t\t.8P Y8. 88 88 88' 88 `8D");
outtextxy(18,14,"\t\t88 88 Y8 8P 88ooooo 88oobY'");
outtextxy(19,14,"\t\t88 88 `8b d8' 88~~~~~ 88`8b");
outtextxy(20,14,"\t\t`8b d8' `8bd8' 88. 88 `88.");
outtextxy(21,14,"\t\t `Y88P' YP Y88888P 88 YD");
outtextxy(23,14,"按回车键重新开始游戏,按0返回主菜单");
while(1)
{
ch=getch();
if(ch==13)
window();
if(ch=='0')
{
menu();
window();
}
}
}
bool road(char ch) //代练路径
{
int i=x,j=y;
switch(ch)
{
case 'W':
while(i!=x1)
if (map[--i][y]==1)
return 0;
break;
case 'S':
while(i!=x1)
if (map[++i][y]==1)
return 0;
break;
case 'A':
while(j!=y1)
if (map[x][--j]==1)
return 0;
break;
case 'D':
while(j!=y1)
if (map[x][++j]==1)
return 0;
break;
}
return 1;
}
void AI6() //代练
{
while(1)
{
if(x>x1 && road('W'))
head->dir='W';
else if(x<x1&&road('S'))
head->dir='S';
else if(y>y1&&road('A'))
head->dir='A';
else if(y<y1&&road('D'))
head->dir='D';
ontimer(tally[1],30,dead());
ontimer(tally[2],40,AI3());
}
}
int main(void) //主函数
{
MoveWindow(hwnd,480,200,680,480,1);//窗口位置
Hide();
char a;
cout<<"\n\n\n\n\n\n"<<" 输入你想要的颜色\n\n"<<" 1->red\n\n"<<" 2->green\n\n"<<" 3->blue"<<endl;
while(1)
{
a=_getch();
if(a>'0' && a<'4')break;
}
color(a);
menu();
//SetConsoleTextAttribute(hOut,FOREGROUND_INTENSITY|FOREGROUND_GREEN);
window();
return 0;
}