怎么用C语言写一个贪吃蛇小游戏

发布时间:2021-08-11 14:46:10 作者:chen
来源:亿速云 阅读:192

本篇内容主要讲解“怎么用C语言写一个贪吃蛇小游戏”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用C语言写一个贪吃蛇小游戏”吧!

编译环境:vs2019

需求:

统计游戏开始后的时间,控制贪吃蛇;吃到食物蛇身加长,得分加一;碰墙或蛇头碰到身体减一条生命;生命消耗完则结束游戏。

思路:

使用wasd键控制蛇的移动方向,蛇头碰到食物得分加一,并在地图上随机产生一个食物,累加得分,碰墙或碰自己减一条生命,并初始化整条蛇,生命值为0时结束游戏。

做法:

使用单链表控制贪吃蛇移动的核心思想就是:链表存储贪吃蛇所有坐标,每次循环贪吃蛇不断向一个方向插入一个新的结点作为新的蛇头,按下按键控制新蛇头产生的位置,然后从新蛇头处遍历链表输出蛇身到上一个蛇尾,清除上一个蛇尾的痕迹,并释放相关结点。

每次向链表插入新节点后,判断新节点的坐标是否和食物的坐标重合,如果重合本轮循环不释放清除蛇尾结点,反之释放清除上一个蛇尾的结点。

另外,在写蛇生命相关代码的时候,还需要注意一下哪些值应该初始化,哪些值不应该初始化。只要明白了贪吃蛇运动的核心思想,整个程序其实就不难写出来。

难点:

wsad控制贪吃蛇上下左右移动,并清除蛇尾。

说明:

使用单链表实现贪吃蛇的核心思想是我一开始没有想到的,部分相关代码我学习并借鉴了一些网络上搜索到的代码,如果有违反了相关版权协议,请告知我修改相关代码。

注意:

由于编译器原因程序中_kbhit()和_getch()函数可能在其他编译器上编译会出现错误,解决办法是去掉函数前面的“_”。

运行效果:

代码实现:

#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <time.h>#include <windows.h>void HideCursor();    //光标隐藏void gotoxy(int x, int y);  //光标定位typedef struct snake{ int x; int y; struct snake* next;}snake;#define WIDTH 100   //控制台窗口宽度#define HEIGHT 30   //控制台窗口高度#define SNAKEN 4   //贪吃蛇初始长度#define LIFE 3    //初始生命次数#define SPEED 200   //游戏速度、循环休眠时间#define U 1     //使用宏代替需要数字代替的蛇的行动方向#define D 2     //宏名含义是各方向英文单词首字母#define L 3     //蛇的状态,U:上 ;D:下;L:左 R:右#define R 4     void dtxxcsh()    //输出地图{ for (int i = 1; i < WIDTH-1; i++)  //输出上下面墙 {  gotoxy(i, 26);  printf("-");  gotoxy(i, 0);  printf("-"); } for (int i = 0; i < HEIGHT-3; i++) //输出左右两面墙 {  gotoxy(0, i);  printf("|");  gotoxy(99, i);  printf("|"); } gotoxy(24, 28); printf("得分: 0   生命: %d   时间: 0   ",LIFE);  //xy 30,28可用得分数值  14个空格}int foodx, foody;   //食物位置坐标void sjcsswhs()    //随机产生一个食物{ srand(time(NULL));   foodx = rand() % (WIDTH - 4) + 2;  //使用宏运算随机数最大值需要加括号 while (foodx % 2)      //如果食物的x坐标不是偶数,再获取一个x坐标 {  foodx = rand() % (WIDTH - 4) + 2; //宽度 } foody = rand() % (HEIGHT - 7) + 3;  //高度 gotoxy(foodx, foody); printf("★");}snake* head;  //蛇头指针void cshs()     //初始化蛇的位置{  snake *tail;   //蛇尾指针 int i; tail = (snake*)malloc(sizeof(snake)); tail->next = NULL; tail->x = HEIGHT-6; tail->y = 8; //贪吃蛇初始长度5 SNAKEN for (i = 1; i <= SNAKEN; i++)    //在蛇尾处创建链表 {  head = (snake*)malloc(sizeof(snake));  head->next = tail;  head->x = 24 + i * 2;     //head->x这个数必须为偶数,和食物坐标偶数对应  head->y = 8;  tail = head;       //此时蛇尾指针指向蛇头 } while (tail) {  gotoxy(tail->x, tail->y);  printf("■");  tail = tail->next; }}int status = R;   //蛇前进状态snake* p = NULL;  //工作指针snake* nexthead;  //下一个蛇头int score = 0;   //得分void snakemove()  //蛇前进,上U,下D,左L,右R{ nexthead = (snake*)malloc(sizeof(snake)); if (status == U) {  nexthead->y = head->y - 1; //确定新蛇头的下一个坐标 x,y  nexthead->x = head->x; } if (status == D)    //下 {  nexthead->y = head->y + 1;  nexthead->x = head->x; } if (status == L)    //左 {  nexthead->x = head->x - 2;  nexthead->y = head->y; } if (status == R)    //右 {  nexthead->x = head->x + 2;  nexthead->y = head->y; } nexthead->next = head; head = nexthead; p = head; if (p->x == foodx && p->y == foody) //判断蛇头的位置是否和食物的位置重合 {  while (p)      //输出尾结点  {   gotoxy(p->x, p->y);   if (p == head)    printf("●");   else    printf("■");   p = p->next;    //因为每次运动都是新创建一个头结点再删除一个尾结点,  }        //所以要增加一节身体,只需要这次循环不释放尾结点,并输出一次尾结点就好了    //sjcsswhs();     //碰到食物则再产生一个食物  score++;  gotoxy(32, 28);  printf("%d", score); } else {  while (p->next->next)   //不输出尾结点  {   gotoxy(p->x, p->y);   if (p == head)    printf("●");   else    printf("■");   p = p->next;  }  gotoxy(p->next->x, p->next->y);  printf(" ");  free(p->next);  p->next = NULL; } p = head; while (p)      //如果食物的坐标刷新到了蛇身上则再产生一个食物 * {  if (p->x == foodx && p->y == foody)   sjcsswhs();  p = p->next; }}void czfxhs()     //操作方向函数,接收从键盘输入的按键,控制贪吃蛇行进方向{ char ch = _getch(); switch (ch) {  case 'w':    if(status != D)    status = U; break;  case 's':    if (status != U)    status = D; break;  case 'a':    if (status != R)    status = L; break;  case 'd':    if (status != L)    status = R; break;  case ' ':    _getch(); break;  //空格暂停 }}int yxjstjjsmz_1()     //生命掉落条件1咬自己{ snake* self = head->next;  //self为蛇身上的一个结点 while (self) {  if (self->x == head->x && self->y == head->y) //head和self的成员作比较,蛇头一直存在,这里遍历的是蛇身  {   return 1;  }  self = self->next; } return 0;}int yxjstjjsmz_2()     //生命掉落条件2碰墙{ if (head->x <= 1 || head->x >= 98 || head->y <= 0 || head->y >= 26)  return 1;  return 0;}int i = LIFE - 1;     //变量存储生命次数void qcsytmslbhs()     //清除并释放上一条蛇留下来的痕迹,更新生命信息{ p = head; int _x_ = p->x;     //用于保存死掉的蛇的蛇头处的位置,用于输出被蛇头顶掉的墙壁 int _y_ = p->y; while (head) {  gotoxy(head->x, head->y);  printf(" ");  head = head->next;  free(p);  p = head; } gotoxy(52, 28);     //更新生命信息 printf("%d", i); if (_y_ == 0 || _y_ == HEIGHT - 4)  //用于在蛇死掉后,蛇头的位置输出被清除蛇头顶替掉的墙壁 {  gotoxy(_x_, _y_);  printf("--"); } else if (_x_ == WIDTH - 2) {  gotoxy(_x_+1, _y_);  printf("|"); } else if(_x_ == 0) {  gotoxy(_x_, _y_);  printf("|"); }}void sbjsjmhs()      //失败结束界面{ p = head;      //释放内存 while (head) {  head = head->next;  free(p);  p = head; } system("cls"); gotoxy(45, 12); printf("游戏结束!"); gotoxy(44, 14); printf("最终得分:%d", score); gotoxy(0,28);}int updatetime()      //获取一次电脑现在的时间{ int now; SYSTEMTIME system_time;     GetLocalTime(&system_time); now = system_time.wMinute * 60 + system_time.wSecond;  return now;}int time_1 = updatetime();     //保存游戏刚开始的时间void gametime()        //写在每次循环之内{ int time_2 = updatetime() - time_1;  //更新游戏开始后时间,用现在的时间减去刚开始的时间 gotoxy(72, 28); printf("%d s", time_2);}int main()//主函数{ system("mode con cols=100 lines=30"); //设置控制台大小 system("title 贪吃蛇游戏");    //设置标题 HideCursor();       //隐藏光标 sjcsswhs();        //初始化随机产生一个食物 dtxxcsh();        //初始化地图、信息 for (; i >= 0; i--)       //生命 {  cshs();         //初始化蛇的位置  status = R;        //初始化运动方向  while (1)  {   snakemove();      //蛇行动动画,方向被控制变量控制   if (_kbhit())   {    czfxhs();      //接收键盘按键,控制控制变量   }      if (yxjstjjsmz_1() || yxjstjjsmz_2())//两个掉落生命的条件    break;   gametime();       //更新游戏时间   Sleep(SPEED);  }  qcsytmslbhs();       //清除上一条蛇留下来的痕迹,更新生命信息 } sbjsjmhs();         //失败结束界面 return 0;}void HideCursor(){ CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);}void gotoxy(int x, int y){ COORD pos = { x,y }; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);}

到此,相信大家对“怎么用C语言写一个贪吃蛇小游戏”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. 【C语言小游戏】 贪吃蛇
  2. 使用C语言如何实现一个贪吃蛇小游戏

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c语言

上一篇:WebSocket中怎么区分不同客户端

下一篇:java如何实现动态数组

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》