赞
踩
consfun.h
- /* WINDOWS命令窗口编程常用功能实现
- 李乾宝,2010年12月
- */
- void consinit(short x,short y);
- void gotoxy(int,int);
- void clrscr(void);
- void textcolor(short newcolor);
- void textbackground(short newcolor);
- void textattr(short newattr);
- void HideCursor();
snake.c
- #include"consfun.h"
- #include<conio.h>
- #include<stdio.h>
- #include<Windows.h>
- #include<time.h>
- #define UP 72
- #define DOWN 80
- #define LEFT 75
- #define RIGHT 77
-
- int i,j;
- int mode=0; //游戏模式
- int n=4; //n=1,2,3,4分别表示用户控制蛇的方向
- int food_sum=0; //累计吃的食物
- int food=0; //食物
- int fx=5,fy=5; //事物的坐标
- int score=0; //分数
- int top_score[3]; //最高分
- int speed=200; //蛇的速度
- int Mode=1; //是否可以穿墙,1不可穿墙,2可以
- #define high 28
- #define width 45 //围墙的高和宽
- int x=high/2,y=width/2; //蛇头的坐标
- int snake[high][width+10]={0};//用来储存蛇,围墙,食物
- void gx() //蛇数组元素全部归0
- {
- for(i=1;i<high-1;i++)
- for(j=1;j<width-1;j++)
- snake[i][j]=0;
- }
- void chu_shi_hua() //每次重新开始,数据数据都要初始化
- {
-
- n=4; //n=1,2,3,4分别表示用户控制蛇的方向
- food_sum=0; //累计吃的食物
- food=0; //食物
- fx=5,fy=5; //食物的坐标
- score=0; //分数
- speed=300; //蛇的速度(这个越大越慢)
- Mode=1; //游戏模式
- x=high/2,y=width/2; //蛇头的坐标
- switch(mode)
- {
- case 1:for(j=5;j<width-5;j++)//基本围墙已经在page_1函数初始化,所以只需初始化新增的墙壁
- {
- snake[high/2-1][j]=-1;
- };break;
- case 2:for(j=10;j<=width-10;j++)//基本围墙已经在page_1函数初始化,所以只需初始化新增的墙壁
- {
- if(j<20||j>25)
- {
- snake[high/4][j]=-1;
- snake[3*high/4][j]=-1;
- }
- }
- for(i=high/4;i<=3*high/4;i++)
- {
- if(i<high/4+5||i>3*high/4-5)
- {
- snake[i][10]=-1;
- snake[i][width-10]=-1;
- }
- };break;
- case 3:for(j=3;j<=width-3;j++)//基本围墙已经在page_1函数初始化,所以只需初始化新增的墙壁
- {
- if((j>=3&&j<=6)||(j>=width-7&&j<=width-4))//初始化四个角的四个横
- {
- snake[6][j]=-1;
- snake[high-7][j]=-1;
- }
- if((j>=width/4&&j<=width/4+6)||(j>=3*width/4-8&&j<=3*width/4))//初始化‘F’的第一横和‘T’的横
- {
- snake[8][j]=-1;
- }
- if((j>=width/4&&j<=width/4+6))//初始化‘F’的第二横
- {
- snake[high/2-1][j]=-1;
- }
- }
- for(i=3;i<=high-3;i++)
- {
- if((i>=3&&i<=6)||(i>=high-6&&i<high-3))//初始化四个角的四个竖
- {
- snake[i][6]=-1;
- snake[i][width-7]=-1;
- }
- if(i>=8&&i<=high-8)//初始化‘F’的竖
- {
- snake[i][width/4]=-1;
- }
- if(i>=8&&i<=high-8&&i!=high/2)//初始化‘T’的竖
- {
- snake[i][3*width/4-4]=-1;
- }
- };break;
- case 4:for(j=3;j<=width-3;j++)//基本围墙已经在page_1函数初始化,所以只需初始化新增的墙壁
- {
- if((j>=3&&j<=6)||(j>=width-7&&j<=width-4))//初始化四个角的四个横
- {
- snake[6][j]=-1;
- snake[high-7][j]=-1;
- }
- }
- for(i=3;i<=high-3;i++)
- {
- if((i>=3&&i<=6)||(i>=high-6&&i<high-3))//初始化四个角的四个竖
- {
- snake[i][6]=-1;
- snake[i][width-7]=-1;
- }
- }
- for(i=0;i<high;i++)
- for(j=0;j<width;j++)
- {
- if(i==high/2+1&&(j==width/2-2||j==width/2))//鼻子
- {
- snake[i][j]=-1;
- }
- if(i==high/2-1&&j==width/2-1)//鼻子
- {
- snake[i][j]=-1;
- }
- if(i==high/2-4&&(j==width/2-3||j==width/2+1||j==width/2-6||j==width/2+4))//眉毛
- {
- snake[i][j]=-1;
- }
- if(i==high/2-5&&(j==width/2-4||j==width/2+2))
- {
- snake[i][j]=-1;
- }
- if(i==high/2-6&&(j==width/2-5||j==width/2+3))
- {
- snake[i][j]=-1;
- }
- if(i==high/2-7&&(j==width/2-6||j==width/2+4))
- {
- snake[i][j]=-1;
- }
- if(i==high/2-8&&(j==width/2-7||j==width/2+5||j==width/2-9||j==width/2+7))
- {
- snake[i][j]=-1;
- }
- if(i==high/2-9&&(j==width/2-8||j==width/2+6))
- {
- snake[i][j]=-1;
- }
- if(i==high/2+4&&j>=width/2-4&&j<=width/2+2)//嘴巴
- {
- snake[i][j]=-1;
- }
- if(i==high/2+5&&j>=width/2-2&&j<=width/2)//嘴巴
- {
- snake[i][j]=-1;
- }
- }
- ;break;
-
- }
- snake[high/2][width/2]=1; //以下将蛇头数值设为1
-
- for(i=1;i<5+food_sum;i++) //以下将蛇身数值设为>1
- snake[high/2][width/2-i]=1+i;
-
- }
-
- void page_1()首页,功能选择页
- {
- char input,*p[5]={" ","简单","困难","复杂","开挂"};
- gx();///将数组全部元素归0,因为在选择重新开始的时候要将游戏区内容清除
- for(j=0;j<width+10;j++) //以下将围墙数值设为-1
- {
- snake[0][j]=-1;
- snake[high-1][j]=-1;
- }
- for(i=0;i<high;i++)
- {
- snake[i][0]=-1;
- snake[i][width-1]=-1;
- snake[i][width+9]=-1;
- }
- while(1)
- {
- for(i=0;i<high;i++)
- for(j=0;j<width+10;j++)
- {
- if(snake[i][j]==-1) //画出围墙
- {
- textbackground(3);
- gotoxy(i,2*j);
- printf(" ");
- }
- if(i==high/2-6&&j==width/2-7)
- {textattr(06);
- gotoxy(i,2*j);
- printf("@@");
- textattr(32);
- printf(" ");}
- if(i==high/2-3&&j==width/2-5)
- {textattr(03);
- gotoxy(i,2*j);
- printf("欢迎来到贪吃蛇游戏!");}
- if(i==high/2-1&&j==width/2-2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("1.简单");}
- if(i==high/2&&j==width/2-2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("2.困难");}
- if(i==high/2+1&&j==width/2-2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("3.复杂");}
- if(i==high/2+2&&j==width/2-2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("4.开挂");}
- if(i==high/2+4&&j==width/2-5)
- {textattr(06);
- gotoxy(i,2*j);
- printf("你选择的模式是:%s",p[mode]);}
- if(i==high/2+6&&j==width/2-5)
- {textattr(03);
- gotoxy(i,2*j);
- printf("请按回车开始游戏");}
-
- }
-
- if(kbhit())//当按键时执行
- {
- input=getch();
- if(input=='1')
- {mode=1;}
- if(input=='2')
- {mode=2;}
- if(input=='3')
- {mode=3;}
- if(input=='4')
- {mode=4;}
- if(input==13)13是回车的ASCII码,按回车开始游戏
- {break;}
- }
- }
- }
-
- void draw() //画围墙、蛇、食物
- {
- while(food==0&&snake[fx][fy]!=0)//当食物生成的位置不是空位置,重新生成
- {
- fx=rand()%(high-1)+1;
- fy=rand()%(width-2)+2;
- }
- snake[fx][fy]=-2;
- food=1;
-
- for(i=0;i<high;i++)
- for(j=0;j<width+10;j++)
- {
-
- if(snake[i][j]==-1) //画出围墙
- {
- textbackground(3);
- gotoxy(i,2*j);
- printf(" ");
- }
- else if(snake[i][j]==0&&j<width) //画出空白的空间
- {
- textattr(03);
- gotoxy(i,2*j);
- printf(" ");
- }
- else if(snake[i][j]==1) //画出蛇头
- {
- textattr(06);
- gotoxy(i,2*j);
- printf("@@");
- }
- else if(snake[i][j]>1) //画出蛇身
- {
- textattr(06);
- textbackground(2);
- gotoxy(i,2*j);
- printf(" ");
- }
- else if(snake[i][j]==-2)
- {
- textcolor(06);
- gotoxy(fx,2*fy);
- printf("●");
- }
- if(i==2&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("w或↑键向上");}
- if(i==4&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("s或↓键向下");}
- if(i==6&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("a或←键向左");}
- if(i==8&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("d或→键向右");}
- if(i==10&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("空格键暂停");}
- if(i==12&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("p键:慢");}
- if(i==14&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("l键:中");}
- if(i==16&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("m键:快");}
- if(i==18&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("t键:模式1");
- }
- if(i==20&&j==width+1)
- {textattr(03);
- gotoxy(i,2*j);
- printf("y键:模式2(穿墙)");
- }
- if(i==22&&j==width+2)
- {textattr(07);
- gotoxy(i,2*j);
- printf("当前模式:%d",Mode);}
- if(i==24&&j==width+2)
- {textattr(03);
- gotoxy(i,2*j);
- printf("当前分数:");
- textattr(06);
- gotoxy(i,2*j+9);
- printf("%d",score);
- }
-
- }
- }
-
- void move()
- {
- FILE *fp; //文件指针,用于读取最高分和保存最高分
- int max=0;
- int oldTail_i,oldTail_j;//旧尾巴的位置
- int oldHead_i,oldHead_j;//旧蛇头的位置
- int newHead_i,newHead_j;//新蛇头的位置
- char input;
- for(i=1;i<high-1;i++) //让蛇的每一节数字加一
- for(j=1;j<width-1;j++)
- {
- if(snake[i][j]>0)
- {
- snake[i][j]++;
- if(max<snake[i][j])//让数字最大的一节变0
- {
- max=snake[i][j];
- //snake[i][j]=0;/
- oldTail_i=i;
- oldTail_j=j;
- }
- if(snake[i][j]==2)
- {
- oldHead_i=i;
- oldHead_j=j;
- }
- }
- }
-
- if(kbhit())//当按键时执行
- {
- input=getch();
- if((input=='w'||input==72)&&n!=2) //正在向上走,就不能执行向下
- {n=1;}
- if((input=='s'||input==80)&&n!=1)
- {n=2;}
- if((input=='a'||input==75)&&n!=4)
- {n=3;}
- if((input=='d'||input==77)&&n!=3)
- {n=4;}
- if(input=='p')
- {speed=200;}
- if(input=='l')
- {speed=100;}
- if(input=='m')
- {speed=0;}
- if(input=='t')
- {Mode=1;}
- if(input=='y')
- {Mode=2;}
- if(input==' ')
- {while(1)
- {
- if(kbhit()!=0)
- break;
- }
- }
- if(input==27)//27为Esc键的ASCII码
- {textattr(00);
- system("pause");
- }
- }
- if(n==1)
- {
- newHead_i=oldHead_i-1;newHead_j=oldHead_j;
- }
- if(n==2)
- {
- newHead_i=oldHead_i+1;newHead_j=oldHead_j;
- }
- if(n==3)
- {
- newHead_i=oldHead_i;newHead_j=oldHead_j-1;
- }
- if(n==4)
- {
- newHead_i=oldHead_i;newHead_j=oldHead_j+1;
- }
- if(snake[newHead_i][newHead_j]==-2) //如果没有吃到食物,蛇的最后一节变为0,否则不变(即蛇的长度+1)
- {
- food=0;
- food_sum++;
- score++;
- }
- else switch(Mode)
- {
- case 1:if(snake[newHead_i][newHead_j]>1||snake[newHead_i][newHead_j]==-1) //模式1,不能穿墙
- {
- fp=fopen("top_score.dat","wb+");
- fseek(fp,4*(mode-1),1);
- fread(&top_score[mode-1],sizeof(int),1,fp);
- if(score>top_score[mode-1])
- top_score[mode-1]=score;
- fwrite(&top_score[mode-1],sizeof(int),1,fp);
- while(1)
- {
- textattr(03);
- gotoxy(high/2,width-7);
- printf("GAME OVER!");
- gotoxy(high/2+1,width-8);
- printf("按r键重新开始");
- gotoxy(high/2+2,width-8);
- printf("按b键退出游戏");
- textattr(06);
- gotoxy(high/2+4,width-10);
- printf("历史最高分:%d 你的分数:%d",top_score[mode-1],score);
- if(kbhit())//当按键时执行
- {
- input=getch();
- if(input=='r')
- main();
- if(input=='b')
- {
- gotoxy(high/2+4,width-8);
- exit(0);
- }
- }
-
- }
- }
- else snake[oldTail_i][oldTail_j]=0;/如果没有吃到食物,蛇的最后一节变为0,否则不变(即蛇的长度+1)
- break;
- case 2:if(snake[newHead_i][newHead_j]==-1&&n==1) //模式2,可以穿墙
- {newHead_i=high-2;}
- else if(snake[newHead_i][newHead_j]==-1&&n==2)
- {newHead_i=1;}
- else if(snake[newHead_i][newHead_j]==-1&&n==3)
- {newHead_j=width-2;}
- else if(snake[newHead_i][newHead_j]==-1&&n==4)
- {newHead_j=1;}
- else if(snake[newHead_i][newHead_j]>1)
- {
- fp=fopen("top_score.dat","wb+");
- fseek(fp,4*(mode-1),1);
- fread(&top_score[mode-1],sizeof(int),1,fp);
- if(score>top_score[mode-1])
- top_score[mode-1]=score;
- fwrite(&top_score[mode-1],sizeof(int),1,fp);
- while(1)
- {
- textattr(03);
- gotoxy(high/2,width-7);
- printf("GAME OVER!");
- gotoxy(high/2+1,width-8);
- printf("按r键重新开始");
- gotoxy(high/2+2,width-8);
- printf("按b键退出游戏");
- textattr(06);
- gotoxy(high/2+4,width-10);
- printf("最高分:%d 你的分数:%d",top_score[mode-1],score);
- if(kbhit())//当按键时执行
- {
- input=getch();
- if(input=='r')
- main();
- if(input=='b')
- {
- gotoxy(high/2+4,width-8);
- exit(0);
- }
- }
- }
- }
- else snake[oldTail_i][oldTail_j]=0;/如果没有吃到食物,蛇的最后一节变为0,否则不变(即蛇的长度+1)
- break;
- }
- snake[newHead_i][newHead_j]=1;
- }
- int main()
- {
- system("cls");
- HideCursor();
- srand((unsigned int)time(0));
- system("title 贪吃蛇");
- system("mode con cols=110 lines=28");//设定窗口大小
- SetWindowLong(GetConsoleWindow(),GWL_STYLE,GetWindowLong(GetConsoleWindow(),GWL_STYLE) & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
- page_1(); //将page_1函数放在chu_shi_hua()函数前,待用户选择游戏模式再对数组进行初始化
- chu_shi_hua(); //数据初始化
- while(1)///游戏循环
- {
-
- Sleep(speed);
- draw();
- move();
- textattr(03);
-
- }
-
-
- return 0;
- }
consfun.c
- /* WINDOWS命令窗口编程常用功能
- 程序设计:李乾宝
- 修改时间:2010年12月--2017年1月
- */
-
- #include <windows.h>
- #include <wincon.h>
-
- /* 设置光标位置:使后续的输出从屏幕的x行y列输出
- 参数:x-行(从0开始)
- y-列(从0开始)
- */
- void gotoxy(int x, int y)
- {
- COORD Position;
- Position.X=y; Position.Y=x;
- SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),Position);
- }
-
- /* 功能:初始化命令窗口,设置窗口的行列数
- 参数:y-行数,x-列数
- */
- void consinit(short x, short y)
- {
- COORD scr={x,y};
- CONSOLE_SCREEN_BUFFER_INFO info;
- SMALL_RECT rect={0,0,x-1,y-1};
- HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
- GetConsoleScreenBufferInfo(stdOut,&info); //获取命令窗口信息
- //如果原屏缓冲区小必须先设置新的缓冲区大小,再调整窗口大小
- if(info.dwSize.X*info.dwSize.Y<x*y)
- { SetConsoleScreenBufferSize(stdOut,scr);
- SetConsoleWindowInfo(stdOut,TRUE,&rect);//缓冲区比需要的小时会出错
- }
- else
- { SetConsoleWindowInfo(stdOut,TRUE,&rect);
- SetConsoleScreenBufferSize(stdOut,scr); //设置值比窗口区域需要的小时会出错
- }
- gotoxy(0,0);
-
- }
-
- /* 清屏:用当前的背景颜色清除屏幕,并将光标定位在左上角(0,0)
- 参数:无
- */
- void clrscr(void)
- {
- COORD scr={0,0};
- DWORD num;
- HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(stdOut,&info);
- num=info.dwMaximumWindowSize.X*info.dwMaximumWindowSize.Y;
- FillConsoleOutputAttribute(stdOut,(WORD)info.wAttributes,num,scr,&num);
- FillConsoleOutputCharacter(stdOut,' ',num,scr,&num);
- gotoxy(0,0);
- }
-
- /* 设置字体颜色:使以后的输出字体前景颜色改为给定值
- 参数:newcolor-新的颜色值
- 颜色取值范围为:0x00 ~ 0x0f
- */
- void textcolor(short newcolor)
- {
- HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(stdOut,&info);
- SetConsoleTextAttribute(stdOut, (WORD)(newcolor|info.wAttributes & 0xF0));
- }
-
- /* 设置背景颜色:使以后的输出的背景颜色改为给定值
- 参数:newcolor-新的颜色值
- 颜色取值范围为:0x00 ~ 0x0f
- */
- void textbackground( short newcolor)
- {
- HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(stdOut,&info);
- SetConsoleTextAttribute(stdOut,(WORD)((newcolor<<4)|(info.wAttributes&0x0F)));
- }
-
- /* 设置文本属性:同时设定前景和背景颜色
- 参数:newattr-新的属性值
- 颜色取值范围为:0x00 ~ 0xff,低4位为前景颜色,高4位为背景颜色
- */
- void textattr(short newattr)
- {
- HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleTextAttribute(stdOut,newattr);
- }
-
-
- void HideCursor() //隐藏光标的函数,网上搜的,需加头文件<windows.h>
- {CONSOLE_CURSOR_INFO cursor_info={1,0};
- SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
- }
上面的头函数和窗口编程代码系汕大李乾宝老师所编写,我写的是snake.c 。snake.c 是大一期末熬一个通宵码的代码,比较冗长,不过勉强可以玩一下,我懒得改啦~,哈哈哈感兴趣的小伙伴可以对代码进行模块化以及相应的删改优化。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。