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 占用两个字符 两边边框就是4
food.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 Position
SetConsoleCursorPosition(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;
}