当前位置:   article > 正文

用C语言实现经典游戏——贪吃蛇_c语言贪吃蛇

c语言贪吃蛇

目录

1.游戏实现思想

(1)定义蛇对象

(2)食物对象

(3)分数: 

(4)初始化蛇

(5)初始化食物

(6)修改控制台光标位置

(7)画出蛇和食物

(8)蛇的移动控制

(9)开始游戏 

(10)蛇移动

(11)画墙

(12)去除蛇尾

(13)去除光标

(14)显示分数

(15)加速

2.游戏实现代码和头文件


该项目适合刚学完C语言结构体,有一定C语言基础的练习,该小项目可以帮助自己锻练的面向对象编程思想。

1.游戏实现思想

要想实现贪吃蛇游戏,根据面向对象的思想,要实现出以下几个模块

1. 定义蛇对象、食物对象

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

3. 控制流程:

        1) 蛇头和墙壁的碰撞

        2) 蛇头和蛇身体的碰撞

        3) 蛇头和食物的碰撞

            1> 蛇身增长

            2> 食物消失 -- 新食物产生

            3> 分数累加

            4> 移动速度增大

      4)蛇的移动

            自动移动

            手动控制移动: ASWD --- 左下上右

       5)显示分数

            排行榜 

  4. 图形界面。


(1)定义蛇对象

蛇对象实现方式原理是坐标,而设置X,Y分别表示横坐标与纵坐标,身体使用数组方式表示可以body[0],表示蛇头,其他表示蛇身,蛇的大小会根据吃的食物个数而增加。

  1. struct BODY {
  2. int x;
  3. int Y;
  4. };
  5. struct SNAKE {
  6. struct BODY body[20*60]; // 蛇身 。 body[0] -- 蛇头
  7. int size; // 蛇的大小
  8. }snake;

 

(2)食物对象

食物对象实现和蛇对象实现同理

  1. struct FOOD {
  2. int X;
  3. int Y;
  4. }food;

(3)分数: 
 

    int score;

(4)初始化蛇

封装一个函数 完成蛇的初始,蛇的初始大小为2,分别表示蛇身和蛇头

  1. void initSnake(void)
  2. {
  3. snake.size = 2;
  4. snake.body[0].X = WIDE/2; // 初始化好了蛇头
  5. snake.body[0].Y = HiGH/2;
  6. snake.body[1].X = WIDE/2 - 1; // 初始化一节蛇身
  7. snake.body[1].Y = HIGH/2;
  8. }

(5)初始化食物

  1. void initFood(void)
  2. {
  3. food.X = rand() % WIDE; // 0-59
  4. food.Y = rand() % HIGH; // 0-59
  5. return;
  6. }

(6)修改控制台光标位置

会将光标位置,定位到 初始化好的蛇头位置(WIDE/2, HIGH/2). 屏幕中间 。注意实现下面代码要用到头文件:#include <conio.h>,#include <Windows.h>

  1. COORD coord; // COORD --> 结构体, 有两个成员变量:x,y 坐标
  2. coord.X = snake.body[0].X;
  3. coord.Y = snake.body[0].Y;
  4. setConsoleCursorPositon(GetStdHandle(STD_OUTPUT_HANDLE), coord);

(7)画出蛇和食物

“@”表示蛇头,“*”表示蛇身。“#”表示食物

  1. 封装函数, initUI()
  2. COORD coord = {0}; // 光标移动的位置。
  3. // 画蛇
  4. for (size_t i = 0; i < snake.size; i++)
  5. {
  6. coord.X = snake.body[i].X;
  7. coord.Y = snake.body[i].Y;
  8. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
  9. if (i == 0)
  10. putchar('@');
  11. else
  12. putchar('*');
  13. }
  14. // 画食物
  15. coord.X = food.X;
  16. coord.Y = food.Y;
  17. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
  18. putchar('#');

(8)蛇的移动控制

键盘输入

  W:(0, -1)  --> 影响蛇头。

    s:(0, +1)

    A:(-1, 0)

    D:(+1, 0)


    不回显:可以让键盘打的asdw不显示在输入界面

        getch()    接收用户输入。    

        char key = getch();

        编译时出错,尝试使用 _getch();


    不阻塞:可以让输入的小蛇光标不阻塞

        kbhit(); 不阻塞判断用户输入。

        有用户输入,返回 “真”, 否则返回“假”值。

        编译时出错,尝试使用 _kbhit();

(9)开始游戏 

  1. void playGame(void
  2. {
  3. char key = 'd'; // 默认蛇向右移动
  4. // 蛇头和墙壁的碰撞:
  5. while ( 判断是否撞墙 ) {
  6. // 重画蛇身 intiUI
  7. // 接收用户键盘输入。
  8. 在全局 添加:kx, ky --》 根据 asdw 按键得不同坐标,影响蛇头
  9. // 蛇头和身体的碰撞
  10. // 蛇与食物的碰撞
  11. // 蛇身体移动 : 前一节给后一节赋值,蛇头收 kx ky 的影响。
  12. system("cls"); 清屏 -- 去除蛇尾。
  13. }
  14. }

蛇头和墙壁的碰撞

判断条件

  1. snake.body[0].X > 0 && snake.body[0].X < WIDE
  2. &&
  3. snake.body[0].Y > 0 && snake.body[0].Y < HIGH

蛇头和身体的碰撞    

蛇头的坐标 和 任意一节身体的坐标 完全一致。

  1. for(i = 1; i < snake.size; i++)
  2. {
  3. if (snake.body[0].X == snake.body[i].X && snake.body[0].Y == snake.body[i].Y )
  4. {
  5. 终止游戏。
  6. return ;
  7. }
  8. }


    蛇头和食物的碰撞

  1. if (snake.body[0].X == food.X && snake.body[0].Y == food.Y)
  2. {
  3. 蛇身增长: snake.size++;
  4. 食物消失:(产生一个新食物)initFood()
  5. 加分:score += 10;
  6. 加速:sleepSecond -= 20;
  7. }

(10)蛇移动

    前一节身体给后一节身体赋值。 蛇头按照 aswd 换算的坐标值 进行变换。

      

  1.  for (size_t i = snake.size-1; i > 0; i--)
  2.         {
  3.             snake.body[i].X = snake.body[i - 1].X;
  4.             snake.body[i].Y = snake.body[i - 1].Y;
  5.         }
  6.         snake.body[0].X += kx;        // 蛇头坐标根据用户按键,修改。
  7.         snake.body[0].Y += ky;

(11)画墙

  1. void initWall(void)
  2. {
  3. for (size_t i = 0; i <= HIGH; i++) // 多行
  4. {
  5. for (size_t j = 0; j <= WIDE; j++) // 一行中的多列
  6. {
  7. if (j == WIDE)
  8. {
  9. printf("|");
  10. }
  11. else if (i == HIGH)
  12. {
  13. printf("_");
  14. }
  15. else
  16. {
  17. printf(" ");
  18. }
  19. }
  20. printf("\n");
  21. }
  22. }

(12)去除蛇尾

蛇移动之前保存蛇尾坐标。

    定义全局变量 :lastX, lastY;

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

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

    在initUI中, 将蛇尾 替换为 ' '

  1. coord.X = lastX;
  2. coord.Y = lastY;
  3. setConsoleCursorPosition(GetSTDHandler(STD_OUTPUT_HANDLE), coord);
  4. putchar(' ');

(13)去除光标

取消显示的光标:请按任意位置继续,使得界面更美观

  1. typedef struct _CONSOLE_CURSOR_INFO {
  2. DWORD dwSize; // 大小
  3. BOOL bVisible; // 是否可见。
  4. } CONSOLE_CURSOR_INFO;
  5. 定义结构体变量:
  6. CONSOLE_CURSOR_INFO cci;
  7. cci.dwSize = sizeof(cci);
  8. cci.bVisible = FALSE; // 0 假 --- 不可见
  9. 设置光标不可见生效:
  10. setConsoleCursorInfo(GetSTDHandler(STD_OUTPUT_HANDLE), &cci);
  11. 在main函数中,调用一次即可生效。

(14)显示分数

    playGame调用结束时,打印 全局score 值。

(15)加速

全局定义变量: sleepSecond = 400;

            Sleep(sleepSecond);

            成功吃食物,    sleepSecond -= 20;

2.游戏实现代码和头文件

游戏使用建议使用VS编辑器,不建议初学者使用dev编辑器,下面有完整代码和实现好的exe文件,感兴趣的可以打包带走。

下图是代码实现后

 


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/372530
推荐阅读
相关标签
  

闽ICP备14008679号