C语言开发实现贪吃蛇小游戏

 更新时间:2020年10月11日 15:40:18   作者:WolfOnTheWay  
这篇文章主要为大家详细介绍了C语言开发实现贪吃蛇小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

小时候相信大家都玩过贪吃蛇,但是自从学了编程以后我都想自己实现一下,苦于没有契机。

首先看一下游戏效果把:

接下来我们先分析一下贪吃蛇的需求有哪些:

  • 用合适的数据结构表示蛇、食物
  • 地图的初始化
  • 蛇的移动、食物的随机生成
  • 蛇的显示、食物的显示
  • 贪吃蛇的规则确定(碰到食物边长、碰到边界和自己死亡等……)

主要功能需求就是上面这些,接下来我直接上C语言代码,这个游戏相信没做过的人看完之后会觉得非常简单,因为其中没什么技术点可言,最重要的就是下面这几句代码,用于控制光标的位置。

#include<Windows.h>
COORD cor;
cor.X = 0;
cor.Y =2;
//光标位置更新到(0,2)
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor);

源码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#include<conio.h>
#define WIDE 60
# define HIGH 20
//1设置地图边界
//2初始化蛇的初始坐标、以及事务
//3、将蛇和食物显示
//4 蛇的移动(WASD)
/*
 规则:
 蛇碰到强死掉
 蛇碰到自己死掉
 蛇碰到食物,身体增长,增加分数
*/
//5.蛇死掉显示分数
//存储蛇的每一节的坐标
typedef struct _body
{
 int x;
 int y;
}BODY;
typedef struct _snake
{
 //存储蛇的身体
 BODY list[WIDE * HIGH];//身体的每一节坐标
 int size;//记录身体长度
 BODY food;//食物的位置
 int dx;//x移动方向
 int dy;//y移动方向
 //记录设尾位置
 int lastx;
 int lasty;
}SNAKE;
 
//初始化食物坐标
void initFood(SNAKE* s)
{
 srand(time(NULL));
 s->food.x = rand() % WIDE;
 s->food.y = rand() % HIGH;
 
}
 
//初始化蛇
void initSnake(SNAKE* s)
{
 //头部
 s->list[0].x = WIDE / 2;
 s->list[0].y = HIGH / 2;
 //第一节
 s->list[1].x = WIDE / 2-1;
 s->list[1].y = HIGH / 2;
 //记录身体大小
 s->size = 2;
 //初始化食物的坐标
 initFood(s);
 //默认向右移动
 s->dx = 1;
 s->dy = 0;
}
//显示蛇
void showUi(SNAKE* s)
{
 /*
 每次显示都要设置光标的位置
 
 */
 //显示蛇
 COORD cor;
 for (int i = 0; i < s->size; ++i)
 {
 //设置光标的位置
 
 cor.X = s->list[i].x;
 cor.Y = s->list[i].y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cor);
 
 //蛇头
 if (i == 0)
 {
  printf("@");
  continue;
 }
 printf("*");
 }
 //显示食物
 cor.X = s->food.x;
 cor.Y = s->food.y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cor);
 printf("#");
 //清除掉蛇尾
 cor.X = s->lastx;
 cor.Y = s->lasty;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor);
 printf(" ");
 
}
//更新的蛇的坐标
void moveSnake(SNAKE* s)
{
    //记录下蛇尾的位置
 s->lastx = s->list[s->size - 1].x;
 s->lasty = s->list[s->size - 1].y;
 for (int i = s->size-1; i >0; --i)
 {
 s->list[i].x = s->list[i - 1].x;
 s->list[i].y = s->list[i - 1].y;
 }
 s->list[0].x += s->dx;
 s->list[0].y += s->dy;
 
}
 
void controlSnake(SNAKE* s)
{
 char key=0;
 //判断按键
 while (_kbhit())
 {
 key = _getch();
 }
 switch (key)
 {
 case 'a':
 s->dx = -1;
 s->dy = 0;
 break;
 case 's':
 s->dx = 0;
 s->dy = 1;
 break;
 case 'd':
 s->dx = 1;
 s->dy = 0;
 break;
 case 'w':
 s->dx = 0;
 s->dy = -1;
 break;
 default:
 break;
 }
}
 
//游戏结束
void gameEnd(SNAKE* s)
{
 COORD cor;
 cor.X = 0;
 cor.Y = HIGH + 1;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor);
 printf("游戏结束,最终得分为%d\n", (s->size - 2) * 10);
 //直接退出程序
 exit(0);
}
//蛇吃到自己
void snakeEatSelf(SNAKE* s)
{
 for (int i = 1; i < s->size; ++i)
 {
 if (s->list[0].x == s->list[i].x && s->list[0].y == s->list[i].y)
 {
  gameEnd(s);
 }
 }
}
//吃到食物
void snakeEatFood(SNAKE* s)
{
 if (s->list[0].x == s->food.x && s->list[0].y == s->food.y)
 {
 //食物重置
 initFood(s);
 //蛇加长
 s->size++;//增加后的坐标在移动的时候会自己进行加长
 }
}
 
//开始游戏
void startGame(SNAKE* s)
{
 //每次对蛇头是否碰墙进行判断
 while (s->list[0].x<WIDE&&s->list[0].x>=0&&s->list[0].y<HIGH&&s->list[0].y>0)
 {
 //控制方向
  controlSnake(s);
 //更新蛇的坐标
 moveSnake(s);
 //system("cls");//清屏
 //蛇移动
 showUi(s);
 //判断蛇是否碰到自己
 snakeEatSelf(s);
 //吃到食物
 snakeEatFood(s);
 //蛇的速度可以通过睡眠时间进行调整
 Sleep(200);
 
 }
 gameEnd(s);
}
//初始化边界
void initWall()
{
 COORD cor;
 for (int i = 0; i <= WIDE; ++i)
 {
 for (int j = 0; j <= HIGH; ++j)
 {
  if (i == 0 || i == WIDE||j==0||j==HIGH)
  {
 
  COORD cor;
  cor.X = i;
  cor.Y = j;
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor);
  printf("+");
  }
 }
 }
}
//隐藏光标
void hideCursor()
{
 CONSOLE_CURSOR_INFO cursor;
 cursor.bVisible = FALSE;
 cursor.dwSize = sizeof(cursor);
 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
 SetConsoleCursorInfo(handle, &cursor);
}
int main()
{
 //隐藏光标
 hideCursor();
 //初始化地图
 initWall();
 //蛇类型定义
 SNAKE* snake = (SNAKE*)malloc(sizeof(SNAKE));
 
 //初始化蛇和食物
 initSnake(snake);
 //显示蛇
 showUi(snake);
 //开始游戏
 startGame(snake);
 
 
 free(snake);
 //程序在HIGH+1行后面输出
 COORD cor;
 cor.X = 0;
 cor.Y =HIGH+2;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor);
 return 0;
}

更多有趣的经典小游戏实现专题,分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

java经典小游戏汇总

javascript经典小游戏汇总

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

相关文章

  • C语言非递归算法解决快速排序与归并排序产生的栈溢出

    C语言非递归算法解决快速排序与归并排序产生的栈溢出

    上期我们讲完了排序算法下,不知道小伙伴们有没有发现一个问题,快速排序和归并排序我们都是用递归来实现的,可能有小伙伴会问,如果说数据量很多话,栈区空间会不会不够用呢?这期我们就来解决使用递归实现的排序导致栈溢出如何解决
    2022-04-04
  • C语言驱动开发之内核使用IO/DPC定时器详解

    C语言驱动开发之内核使用IO/DPC定时器详解

    本章将继续探索驱动开发中的基础部分,定时器在内核中同样很常用,在内核中定时器可以使用两种,即IO定时器,以及DPC定时器,感兴趣的可以了解一下
    2023-04-04
  • C++使用WideCharToMultiByte函数生成UTF-8编码文件的方法

    C++使用WideCharToMultiByte函数生成UTF-8编码文件的方法

    用来映射Unicode字符串的WideCharToMultiByte函数经常被用来进行UTF-8编码的转换,以下我们将看到C++使用WideCharToMultiByte函数生成UTF-8编码文件的方法,首先先来对WideCharToMultiByte作一个详细的了解:
    2016-06-06
  • C++快速排序超详细讲解

    C++快速排序超详细讲解

    快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下
    2025-03-03
  • C++中的函数修饰符深入讲解

    C++中的函数修饰符深入讲解

    这篇文章主要给大家介绍了关于C++中函数修饰符的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-02-02
  • C语言的程序环境与预处理你真的了解吗

    C语言的程序环境与预处理你真的了解吗

    这篇文章主要为大家详细介绍了C语言的程序环境与预处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • 如何在程序中判断VS的版本(实现方法详解)

    如何在程序中判断VS的版本(实现方法详解)

    下面小编就为大家带来一篇如何在程序中判断VS的版本(实现方法详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • OpenCV实现直线拟合

    OpenCV实现直线拟合

    这篇文章主要为大家详细介绍了OpenCV实现直线拟合,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C++多线程之互斥锁与死锁

    C++多线程之互斥锁与死锁

    互斥锁和死锁是C++多线程中常见的情况,这篇文章就带大家进一步了解多线程中的互斥锁与死锁这两个概念,文中的示例代码介绍得很详细,快来跟随小编一起学习吧
    2021-12-12
  • 你知道如何自定义sort函数中的比较函数

    你知道如何自定义sort函数中的比较函数

    这篇文章主要介绍了如何自定义sort函数中的比较函数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12

最新评论