首页 > 编程 > C > 正文

C语言贪吃蛇经典小游戏

2020-01-26 13:46:53
字体:
来源:转载
供稿:网友

一、贪吃蛇小游戏简介:

用上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,也不能咬到自己的身体,等到了一定的分数,就能过关。

二、函数框架

三、数据结构

typedef struct Snake {  size_t x; //行  size_t y; //列  struct Snake* next; }Snake, *pSnake; 

定义蛇的结构体,利用单链表来表示蛇,每个结点为蛇身体的一部分。

四、代码实现(vs2010  c语言)

1.Snake.h

#ifndef __SNAKE_H__ #define __SNAKE_H__  #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <time.h> #include <malloc.h> #include <assert.h> //标识地图大小 #define ROW_MAP 10 //地图的行 #define COL_MAP 20 //地图的列 #define SUCCESS_SCORE 10//通关分数 enum Direction //蛇行走的方向 {  R, //右  L, //左  U, //上  D //下 }Direction;  enum State {  ERROR_SELF, //咬到自己  ERROR_WALL, //撞到墙  NORMAL,  //正常状态  SUCCESS  //通关 }State;  typedef struct Snake {  size_t x; //行  size_t y; //列  struct Snake* next; }Snake, *pSnake;   void StartGame(); void RunGame(); void EndGame();  #endif 

2.Snake.c

#include "Snake.h"  pSnake head = NULL; //定义蛇头指针 pSnake Food = NULL; //定义食物指针  int sleeptime = 500;//间隔时间,用来控制速度 int Score = 0; //总分 int everyScore = 1; //每步得分  //定义游戏中用到的符号 const char food = '#'; const char snake = '*';  void Pos(int x, int y) //控制输出光标 {  COORD pos; //pos为结构体  pos.X = x; //控制列  pos.Y = y; //控制行  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);//读取标准输出句柄来控制光标为pos }  void Face() {  system("color 0C");  printf("*******************************************************/n");  printf("*    Welcome to Snake Game!    */n");  printf("*              */n");  printf("*    ->开始游戏请按 enter键     */n");  printf("*    ->退出游戏请按 esc键     */n");  printf("*    ->暂停游戏请按 space键     */n");  printf("*    ->通过上下左右键来控制蛇的移动   */n");  printf("*    ->通过F1键减速  F2键加速   */n");  printf("*******************************************************/n"); } void Map() //初始化地图 {  int i = 0;  for(i = 0; i<COL_MAP; i+=2) //打印上下边框(每个■占用两列)  {   Pos(i, 0);   printf("■");   Pos(i, ROW_MAP-1);   printf("■");  }  for(i = 0; i<ROW_MAP; i++) //打印左右边框  {   Pos(0, i);   printf("■");   Pos(COL_MAP-2, i);   printf("■");  } } void PrintSnake() //打印蛇 {  pSnake cur = head;  while(cur)  {   Pos(cur->y, cur->x);   printf("%c", snake);   cur = cur->next;  } } void InitSnake() //初始化蛇身 {  int initNum = 3;  int i = 0;  pSnake cur;  head = (pSnake)malloc(sizeof(Snake));  head->x = 5;  head->y = 10;  head->next = NULL;   cur = head;  for(i = 1; i < initNum; i++)  {   pSnake newNode = (pSnake)malloc(sizeof(Snake));   newNode->x = 5+i;   newNode->y = 10;   newNode->next = NULL;   cur->next = newNode;   cur = cur->next;  }   PrintSnake(); }  void CreateFood() //在地图上随机产生一个食物 {  pSnake cur = head;  Food = (pSnake)malloc(sizeof(Snake));   //产生x~y的随机数 k=rand()%(Y-X+1)+X;  srand((unsigned)time(NULL));  Food->x = rand()%(ROW_MAP-2 - 1 + 1)+1;  Food->y = rand()%(COL_MAP-3 - 2 + 1)+2;  Food->next = NULL;  while(cur) //检查食物是否与蛇身重合  {   if(cur->x == Food->x && cur->y == Food->y)   {    free(Food);    Food = NULL;    CreateFood();    return;   }   cur = cur->next;  }  Pos(Food->y, Food->x);  printf("%c", food); }  void StartGame() //游戏开始的所有设置 {  Face();  system("pause");   if(GetAsyncKeyState(VK_RETURN))  {   system("cls");   Pos(COL_MAP+5, 1);   printf("当前分数/通关分数:");   Pos(COL_MAP+20, 1);   printf("%d/%d", Score, SUCCESS_SCORE);   Pos(COL_MAP+5, 2);   printf("当前分每步得分:");   Pos(COL_MAP+20, 2);   printf("%d", everyScore);   Pos(COL_MAP+5, 3);   printf("/n");   Pos(COL_MAP+5, 4);   printf("速度越快 得分越高哦!!/n");    Map();   InitSnake();   CreateFood();  }  else if(GetAsyncKeyState(VK_ESCAPE))  {   exit(0);  } }  int IsCrossWall()    //判断是否碰到墙 {  if(head->x <= 0 || head->x >= ROW_MAP-1   ||head->y <= 1 || head->y >= COL_MAP-2)  {   State = ERROR_WALL;   return 0;  }  return 1; }  int IsEatSelf(pSnake newHead) //判断是否咬到自己 {  pSnake cur = head;  assert(newHead);  while(cur)  {   if(cur->x == newHead->x && cur->y == newHead->y)   {    State = ERROR_SELF;    return 0;   }   cur = cur->next;  }  return 1; }  int IsFood(pSnake pos) //判断该位置是不是食物 {  assert(pos);  if(pos->x == Food->x && pos->y == Food->y)  {   return 1;  }  return 0; }  void SnakeMove() //蛇移动一次 {  pSnake newHead = NULL;  newHead = (pSnake)malloc(sizeof(Snake));   if(Direction == R)  {   newHead->x = head->x;   newHead->y = head->y+1;   newHead->next = head;  }  else if(Direction == L)  {   newHead->x = head->x;   newHead->y = head->y-1;   newHead->next = head;  }  else if(Direction == U)  {   newHead->x = head->x-1;   newHead->y = head->y;   newHead->next = head;    }  else if(Direction == D)  {   newHead->x = head->x+1;   newHead->y = head->y;   newHead->next = head;  }   if(IsFood(newHead))  {   head = newHead;   PrintSnake();   CreateFood();   Score += everyScore;   Pos(COL_MAP+20, 1);   printf("%d/%d", Score, SUCCESS_SCORE);   if(Score >= SUCCESS_SCORE)   {    State = SUCCESS;   }  }  else   {    if(IsCrossWall() && IsEatSelf(newHead))    {     pSnake cur = NULL;     head = newHead;     cur = head;     //删除蛇尾并打印     while(cur->next->next != NULL)     {      Pos(cur->y, cur->x);      printf("%c", snake);      cur = cur->next;     }          Pos(cur->y, cur->x);     printf("%c", snake);     Pos(cur->next->y, cur->next->x);     printf(" "); //打印空格来覆盖频幕上的蛇尾     free(cur->next);     cur->next = NULL;    }    else    {     free(newHead);     newHead = NULL;    }  } }  void Pause() {  while(1)  {   Sleep(sleeptime);   if(GetAsyncKeyState(VK_SPACE))   {    break;   }  } }  void ControlSnake() //用键盘控制游戏 {  if(GetAsyncKeyState(VK_UP) && Direction!=D)  {   Direction = U;  }  else if(GetAsyncKeyState(VK_DOWN) && Direction!=U)  {   Direction = D;  }  else if(GetAsyncKeyState(VK_LEFT) && Direction!=R)  {   Direction = L;  }  else if(GetAsyncKeyState(VK_RIGHT) && Direction!=L)  {   Direction = R;  }  else if(GetAsyncKeyState(VK_F1))  {   if(sleeptime != 500)   {    sleeptime = 500;    everyScore = 1;    Pos(COL_MAP+20, 2);    printf("%d", everyScore);   }  }  else if(GetAsyncKeyState(VK_F2))  {   if(sleeptime != 300)   {    sleeptime = 300;    everyScore = 2;    Pos(COL_MAP+20, 2);    printf("%d", everyScore);   }  }  else if(GetAsyncKeyState(VK_SPACE))  {   Pause();  }  else if(GetAsyncKeyState(VK_ESCAPE))  {   exit(0);  } }  void StateGame() //判断游戏失败或成功 {  if(State == ERROR_SELF)  {   system("cls");   printf("很遗憾,蛇咬到自己,游戏失败!/n");  }  else if(State == ERROR_WALL)  {   system("cls");   printf("很遗憾,蛇碰到墙壁,游戏失败!/n");  }  else if(State == SUCCESS)  {   system("cls");   printf("恭喜您,已通关!!!/n");  }   } void RunGame() {  Direction = R; //蛇初始行走方向为右  State = NORMAL;//游戏初始为正常状态  while(1)  {   ControlSnake();   SnakeMove();   if(State != NORMAL)   {    StateGame();    break;   }   Sleep(sleeptime);  } }  void EndGame() //释放链表并恢复默认值 {  pSnake cur = head;  while(cur)  {   pSnake del = cur;   cur = cur->next;   free(del);   del = NULL;  }  head = NULL;  if(Food != NULL)  {   free(Food);   Food = NULL;  }  Score = 0;  everyScore = 1;  sleeptime = 500; } 

3.Test.c

#include "Snake.h"  int main() {  while(1)  {   StartGame();   RunGame();   EndGame();  }  system("pause");  return 0; } 

五、运行界面展示

1.欢迎界面

 

2.游戏界面

小小的c语言项目,用来练手,仅供参考哦!!

谢谢阅读,如有问题,欢迎提出。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选