步骤:

1、建立蛇对象、食物对象

坐标:

struct  COOR{

 int  X;  

 int  Y;

};


//蛇对象

struct SANKE{

 struct COOR snake[MAXSIZE];

 int size;

}snake;


//食物对象

struct FOOD{

 struct COOR food;

}food;

 

//定义分数

int score=0;


2、初始化蛇、初始化食物


//初始化蛇

void InitSnake()

{

 snake.size=2;

 //蛇头

 snake.snake[0].X=WIDE/2;

 snake.snake[0].Y=HEIGHT/2;

 //蛇身

 snake.snake[1].X=WIDE/2-1;

 snake.snake[1].Y=HEIGHT/2;

}


//初始化食物

void InitFood()

{

 food.food.X = rand() % HEIGHT;

 food.food.Y = rand() % WIDE;

}


//修改控制台光标的位置 把光标移动到蛇头的位置   同理可以修改光标到食物的位置

COORD coord;

coord.X=snake.snake[0].X;

coord.Y=snake.snake[0].Y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);


3、控制流程


1)结束条件:蛇头碰墙     蛇头和蛇身相碰

 

//蛇头碰墙    如果已经碰墙则不执行后序操作

while(

           snake.snake[0].X >=0 && snake.snake[0].X<WIDE  

 &&

           snake.snake[0].Y >=0 && snake.snake[0].Y<height

         )

 

//蛇头碰蛇身

for(int i=1;i<snake.size;i++)

{

 if(snake.snake[0].X==snake.snake[i].X && snake.snake[0].Y==snake.snake[i].Y )

  return;

}


2)蛇头和食物碰撞:

 蛇身增长   食物消失产生新的食物    分数增加    移动速度增加

 

if(snake.snake[0].X==food.food.X && snake.snake[0].Y==food.food.Y)

{

 //蛇身增长

 snake.size++;

 //食物消失产生新的食物  

 InitSnake();

 //分数增加

 score+=10;

 //移动速度增加

   

}

3)蛇的移动: 自动移动    控制移动

 

void SnakeMove()

{

 if(_kbhit())  //检查是否有输入 有则执行

 {

  char key=_getch();

 }

 switch (key)

 {

 case 'w':kx = 0; ky = -1; break;//上

 case 's':kx = 0; ky = +1 ; break;//下

 case 'd':kx = +1; ky = 0; break;//右

 case 'a':kx = -1; ky = 0; break;//左

 default:

  break;

 }

 //移动 前一个给后一个

 for (int i = snake.size - 1; i > 0; i--)

 {

  snake.snake[i].X = snake.snake[i - 1].X;

  snake.snake[i].Y = snake.snake[i - 1].Y;

 }

 snake.snake[0].X += kx;

 snake.snake[0].Y += ky;

}

4)显示分数 : 排行榜


void ShowScore()

{

 COORD coord;

 coord.X = 0;

 coord.Y = HEIGHT + 2;

 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

 printf("Game Over!!!\n");

 printf("最终得分为:%d\n", score);

 return;

}

4、图形界面  

//设置墙

void SnakeWall()

{

 for (int i = 0; i <= HEIGHT; i++)

 {

  for (int j = 0; j <= WIDE; j++)

  {


   if (j == WIDE)

   {

    printf("|");

   }

   else if (i == HEIGHT)

   {

    printf("_");

   }

   else

    printf(" ");

  }

  printf("\n");

 }

}



扩展知识:

1、SetConsoleCursorPosition函数

头文件:#include<conio.h>

             #include<Windows.h>

typedef struct _COORD{

 SHORT X;

 SHORT Y;

}COORD;//是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标

 

COORD coord;//定义结构体变量

//设置坐标

coord.X=10;  

coord.Y=20

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);


2、getch() 从控制台无回显的取一个字符

返回值:读取字符的ASCII码

头文件:#include<conio.h>

用法:char key=_getch();


3、kbhit() 以非阻塞方式,检查当前是否有键盘输入

用法:if(kbhit()){……}

返回值:有则为非零值,无则为假0

头文件:#include<conio.h>

编译出错尝试 :_kbhit();


4、SetConsoleCursorInfo() //放到main()函数中

typedef struct _CONSOLE_CURSOR_INFO

{

 DWORD dwSize;//大小

 BOOL bVisible;//是否可见

}CONSOLE_CURSOR_INFO;//描述光标信息  隐藏光标位置

用法:

CONSOLE_CURSOR_INFO cci;

cci.dwSize=sizeof(cci);

cci.bVisible=FALSE;

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci)


综合代码:

头文件snake.h中:

#ifndef __OJ_H__

#define __OJ_H__


#include<stdlib.h>

#include<string.h>

#include<stdio.h>

#include<assert.h>

#include<stdbool.h>

#include<math.h>

#include<time.h>

#include<conio.h>

#include<Windows.h>


#define MAXSIZE 10

#define WIDE 60

#define HEIGHT 20


struct  COOR {

int  X;

int  Y;

};

//蛇对象

struct SANKE {

struct COOR snake[MAXSIZE];

int size;

}snake;

//食物对象

struct FOOD {

struct COOR food;

}food;


//初始化蛇

void InitSnake();

//初始化食物

void InitFood();

void SnakeMove();

void SnakeWall();

void InitCursorPosition();

void ShowScore();


#endif // !__OJ_H__


text.c 中:

#include"oj.h"


int main()

{

//隐藏光标

CONSOLE_CURSOR_INFO cci;

cci.dwSize = sizeof(cci);

cci.bVisible = FALSE;

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);

_kbhit();

srand((unsigned int)time(NULL));

SnakeWall();

InitSnake();

InitFood();

InitCursorPosition();

SnakeMove();

 

return 0;

}


snake.c中 : 

#define _CRT_SECURE_NO_WARNINGS

#include"oj.h"


//成绩

int score = 0;


//移动后的坐标

int kx = 0;

int ky = 0;


//记录蛇尾坐标

int lastX = 0;

int lastY = 0;


//速度

int sleepSpeed = 400;

//初始化蛇

void InitSnake()

{

snake.size = 2;

//蛇头

snake.snake[0].X = WIDE / 2;

snake.snake[0].Y = HEIGHT / 2;

//蛇身

snake.snake[1].X = WIDE / 2 - 1;

snake.snake[1].Y = HEIGHT / 2;

}

//初始化食物

void InitFood()

{

food.food.X = rand() % WIDE;

food.food.Y = rand() % HEIGHT;

}


//设置坐标在控制台的位置

void InitCursorPosition()

{

COORD coord = { 0 };

for (int i = 0; i < snake.size; i++)

{

 coord.X = snake.snake[i].X;

 coord.Y = snake.snake[i].Y;

 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

 if (i == 0)

 {

  putchar('@');

 }

 else

  putchar('*');

}

//除去蛇尾

coord.X = lastX;

coord.Y = lastY;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

putchar(' ');


//食物的坐标

coord.X = food.food.X;

coord.Y = food.food.Y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

putchar('#');

}


//设置墙

void SnakeWall()

{

for (int i = 0; i <= HEIGHT; i++)

{

 for (int j = 0; j <= WIDE; j++)

 {


  if (j == WIDE)

  {

   printf("|");

  }

  else if (i == HEIGHT)

  {

   printf("_");

  }

  else

   printf(" ");

 }

 printf("\n");

}

}


//蛇移动

void SnakeMove()

{

char key = 'd';//默认往右走

while (snake.snake[0].X >= 0 && snake.snake[0].X < WIDE

 &&

 snake.snake[0].Y >= 0 && snake.snake[0].Y < HEIGHT)

{

 //SnakeWall();

 InitCursorPosition(); //重画蛇身

 if (_kbhit())  //检查是否有输入 有则执行

 {

  key = _getch();

 }

 switch (key)

 {

 case 'w':kx = 0; ky = -1; break;//上

 case 's':kx = 0; ky = +1; break;//下

 case 'd':kx = +1; ky = 0; break;//右

 case 'a':kx = -1; ky = 0; break;//左

 default:

  break;

 }


 //蛇头碰蛇身

 for (int i = 1; i < snake.size; i++)

 {

  if (snake.snake[0].X == snake.snake[i].X && snake.snake[0].Y == snake.snake[i].Y)

  {

   ShowScore();

   return;

  }

   

 }


 //蛇头和食物碰撞

 if (snake.snake[0].X == food.food.X && snake.snake[0].Y == food.food.Y)

 {

  //蛇身增长

  snake.size++;

  //食物消失产生新的食物  

  InitFood();

  //分数增加

  score += 10;

  //移动速度增加

  sleepSpeed -= 50;

 }

 //存储蛇尾

 lastX = snake.snake[snake.size - 1].X;

 lastY = snake.snake[snake.size - 1].Y;

 //移动 前一个给后一个

 for (int i = snake.size - 1; i > 0; i--)

 {

  snake.snake[i].X = snake.snake[i - 1].X;

  snake.snake[i].Y = snake.snake[i - 1].Y;

 }

 snake.snake[0].X += kx;

 snake.snake[0].Y += ky;

 //视觉上让蛇移动

 Sleep(sleepSpeed);

 //system("cls");

}

ShowScore();

}


void ShowScore()

{

COORD coord;

coord.X = 0;

coord.Y = HEIGHT + 2;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

printf("Game Over!!!\n");

printf("最终得分为:%d\n", score);

return;

}