C语言入门项目篇:贪吃蛇
可直接运行。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
/*大一上的时候C语言入门学的一个小游戏。还是挺有意思的,有兴趣的同学可以继续优化下:比如蛇头碰到蛇身就判定为输 /给蛇身加点颜色等。
*/
//1.2食物结构体
#define MAPHEIGHT 25
#define MAPWIDTH 60
#define SNAKESIZE 50 //蛇的最大节数
struct FOOD
{int x;int y;
}food;#define SNAKESIZE 50 //蛇的最大节数
struct
{ //每一节蛇的坐标int x[SNAKESIZE];int y[SNAKESIZE];int len; //蛇长int speed; //
}snake;
///全局变量
int key='w';//初始化移动方向
int changFlag = 0;//蛇变化标记
//模块化设计
//
//1.画地图
void gotoxy(int x,int y); //实现的函数声明
void drawMap();
void createFood();
int snakeStatus();
void drawMap(){srand((unsigned)time(NULL)); //随机函数种子//1.圈地//1.1 左右边框for(int i=0;i<=MAPHEIGHT;i++){gotoxy(0,i);printf("■");gotoxy(MAPWIDTH,i);printf("■");}for(int i=0;i<=MAPWIDTH;i+=2) //上下 ■占用两个字符{gotoxy(i,0);printf("■");gotoxy(i,MAPHEIGHT);printf("■");}//2.画蛇 ■//2.1确定蛇的属性snake.len=3;snake.speed =100;snake.x[0]=MAPWIDTH/2; //开始蛇头放屏幕中间snake.y[0]=MAPHEIGHT/2;//2.2画蛇头gotoxy(snake.x[0],snake.y[0]);printf("■"); //一节 x=2//画身体for(int k =1;k<snake.len;k++){snake.x[k]=snake.x[k-1]+2;snake.y[k]=snake.y[k-1];gotoxy(snake.x[k],snake.y[k]);printf("■");}//3.画食物 ● //3.1确定坐标food.x=rand()%(MAPWIDTH-4)+2; //边框的宽度是2 占用两个字符 两边边框就是4food.y=rand()%(MAPHEIGHT-2)+1; //上下各占一个if(food.x%2!=0){food.x=food.x+1;}//3.2 画出来就可以gotoxy(food.x,food.y);printf("●");}
//2.food
void createFood()
{//蛇头坐标等于食物坐标,就是吃了if(snake.x[0]==food.x && snake.y[0]==food.y){srand((unsigned int)time(NULL));//产生的食物不能在蛇的身上,并且坐标要是偶数 因为蛇头的宽度是偶数while(1){int flag=1;food.x=rand()%(MAPWIDTH-4)+2;food.y=rand()%(MAPHEIGHT-2)+1;//产生的食物不能在蛇身上for(int k=0;k<snake.len;k++){if(snake.x[k]==food.x&&snake.y[k]==food.y){flag = 0; //不合适的标志break;}}if(flag&&food.x%2==0){break;}}gotoxy(food.x,food.y);//产生新的食物printf("●");snake.len++;changFlag =1;//蛇的标记是1}
//gotoxy(food.x,food.y);//产生新的食物// printf("●");}
void keyDown() //3.按键操作
{
//无按键的处理 原方向
if(_kbhit())
{//有按键fflush(stdin);key=_getch();
}
//擦除
if(!changFlag)
{gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);printf(" ");//两个空格擦掉尾巴。
}
//后面的蛇身
for(int i =snake.len-1;i>0;i--)
{snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];}
//移动方向的处理
switch(key)
{
case 'W': //往上走 y--
case 'w':snake.y[0]--;break;
case 'S':
case 's':snake.y[0]++;break;
case 'A':
case 'a':snake.x[0]-=2;break;
case 'd':
case 'D':snake.x[0]+=2;break;}//画蛇头gotoxy(snake.x[0],snake.y[0]);printf("■");changFlag=0;gotoxy(MAPHEIGHT+2,0); //移动不能一直看着光标
}
int snakeStatus() //4.蛇的状态:判断是否结束游戏
{
if (snake.x[0]==0||snake.x[0]==MAPWIDTH||snake.y[0]==0||snake.y[0]==MAPHEIGHT){return 0;//蛇头不能撞自己for(int k=1;k<snake.len;k++){if(snake.x[0]== snake.x[k]&& snake.y[k]==snake.y[0])return 0;}}
return 1;
}
void gotoxy(int x,int y) //5.光标移动
{//调用win32 API去设置控制台的光标位置//1.找到控制台的这个窗口HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//2.光标的结构体COORD coord;//3.设置光标coord.X =x;coord.Y =y;//4.同步到控制台 Set Console Cursor PositionSetConsoleCursorPosition(handle,coord);
}int main(){drawMap();while(1){createFood();Sleep(snake.speed);//延时keyDown();if(!snakeStatus()){break;}}gotoxy(MAPWIDTH/2,MAPHEIGHT/2);printf("You lose!");system("pause"); //return 0;
}