当前位置:   article > 正文

C语言实战项目-贪吃蛇小游戏_c语言小游戏代码

c语言小游戏代码

一、贪吃蛇游戏实现思路:


1.定义蛇对象、食物对象
2.初始化蛇、初始化食物
3.控制流程:

1)蛇头和墙壁的碰撞
(2)蛇头和蛇身体碰撞
(3)蛇头和食物碰撞
(4)移动速度增大

4.游戏效果:
1)蛇身增长
(2)食物消失 -- 新食物产生
(3)分数累加
(4)移动速度增大
(5)蛇的移动
(6)显示分数

 

二、实现步骤:


1.引入头文件:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <time.h>
  6. #include <conio.h>
  7. #include <windows.h>
2.宏定义:
  1. #define WIDE 60 //宽度
  2. #define HIGH 20 //高度
3.定义对象:
蛇身对象:
struct BOOY {
        int X;
        int Y;
    };
蛇对象:
struct SNAKE {
        struct BODY body[20*60]; //蛇身 body[0] -- 蛇头
        int size;   //蛇的大小
    } snake;

食物对象:
    struct FOOD {
            int X;
            int Y;
    } food;
4.初始化:
初始化分数:
    int score = 0;

初始化蛇:
    封装一个函数 完成蛇的初始化:
void initSnake(void)
{
    snake.size = 2;
    初始化好了蛇头
    snake.body[0].X = WIDE/2;
    snake.body[0].Y = HIGH/2;

    初始化一节蛇身
    snake.body[1].X = WIDE/2 - 1;
    snake.body[1].Y = HIGH/2;

    return;
}

初始化食物:
void initFood(void)
{
   food.X = rand() % WIDE; //0-59
   food.Y = rand() % HIGH; //0-59

   return;
}

5.控制定位:

修改控制台光标位置:
COORD coord;  //CORD --> 结构体, 有两个成员变量:x, y 坐标
coord.X = snake.body[0].X;
coord.Y = snake.body[0].Y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
会将光标位置,定位到 初始化好的蛇头位置(WIDE/2, HIGH/2), 屏幕中间
 6.画出形状:
画出蛇和食物:
封装函数 initUI(void)
{
//光标移动位置
COORD coord = {0};

//画蛇
for (size_t i = 0; i < snake.size; ++i)
{
coord.X = snake.body[0].X;
coord.Y = snake.body[0].Y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

    if (i == 0)
        putchar('@');
    else
        putchar('*');
    }

    //画食物
    coord.X = food.X;
    coord.Y = food.Y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    putchar('#');
}
画墙:
void initWall(void)
{
    for (size_t i = 0; i <= HIGH; i++)  //多行
    {
        for (size_t j = 0; j <= WIDE; j++)  //一行中的多列
        {
            if (j == WIDE)
            {
                printf("|");
            }
            else if (i = HIGH)
            {
                printf("_");
            }
            else
            {
                printf(" ");
            }
        }
        printf("\n");
    }
}
7.按键控制: 
蛇的移动控制:
    W: (0, -1)  -->影响蛇头
    S: (0, +1)
    A: (-1, 0)
    D: (+1, 0)

    不回显:
        getch():接受用户输入。
        char key = getch();
        编译时出错,尝试使用 _getch();
    不堵塞:
        kbhit(); 不阻塞判断用户输入。
        有用户输入返回“真”,否则返回“假”值
        编译时出错,尝试使用 _kbhit();
 8.游戏体验:
开始游戏:
    void playGame(void)
    {
        char key = 'd'; //默认蛇向右移动
        蛇头和墙壁的碰撞:
        while(判断是否撞墙) 
        {
            //重画蛇身 initUI   
            //接受用户键盘输入
                在全局 添加:kx, ky --> 根据 A S D W 按键得不同坐标, 影响蛇头

            //蛇头和身体的碰撞
            //蛇头和食物的碰撞
            //蛇身体移动:前一节给后一节赋值,舌头收 kx ky 的影响
            system("cls"); 清屏 -- 去除蛇尾
        }
    }

    蛇头和墙壁的碰撞:
        snake.body[0].X > 0 && snake.body[0].X < WIDE
      &&
        snake.body[0].Y > 0 && snake.body[0].Y < HIGH
    蛇头和身体碰撞:    蛇头的坐标 和 任意一节身体和坐标 完全一致
        for(i = 1; i < snake.size; i++)
        {
            if(snake.body[0].X == snake.body[i].X && snake.body[0].Y == snake.body[i].Y)
            {
                    //终止游戏
                    return;
            }
        }
    蛇头和食物的碰撞:
        if(snake.body[0].X == food.X && snake.body[0].Y == food.Y)
        {
            蛇身增长:snake.size++
            食物消失:(产生一个新食物)initFood()
            加分:score += 10;
            加速: 
        }

    蛇移动:
        前一节身体给后一节身体赋值。蛇头按照 A S W D 换算的坐标值 进行交换
            for (size_t i = snake.size - 1; i > 0; i--)
            {
                snake.body[i].X = snake.body[i - 1].X;
                snake.body[i].Y = snake.body[i - 1].Y;
            }
            snake.body[0].X += kx;   //蛇头坐标根据用户按键,修改
            snake.body[0].Y += ky;
9.游戏优化 :
去除蛇尾:
    蛇移动之前保存蛇尾坐标:
    定义全局变量:lastX, lastY;
    lastX = snake.body[nake.size - 1].X;
    lastX = snake.body[nake.size - 1].X;
    在int中,将蛇尾 替换为 ' '
    coord.X = lastX;
    coord.Y = lastY;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    putchar(' ');
去除光标:
    typedef struct _CONSOLE_CURSOR_INFO {
    DWORD dwSize;   //大小
    BOOL bVisible;  //是否可见
    } CONSOLE_CURSOR_INFO;
    定义结构体变量:
    CONSOLE_CURSOR_INFO cci;
    cci.dwSize = sizeof(cci);
    cci.bVisible = FALSE; //TRUE;
设置光标不可见生效:
    SetConsoleCursorInfo(SetStdHandle(STD_OUTPUT_HANDLE), &cci);

显示分数
    playGame调用结束时, 打印 全局 score 值
加速:
    全局定义变量: sleepSecond = 400;
                Sleep(sleepSecond);
                sleepSecond -= 20;
    
10.实现效果:

 

三、项目源码:


1.主程序文件" main.c "中的代码:
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include "snake.h" //引入自定义头文件
  3. int main(void) {
  4. // 强制控制输出
  5. //-----------------------------------------------------------------
  6. // setbuf(stdout, NULL); //直接输出,解除缓存
  7. //-----------------------------------------------------------------
  8. // 游戏地图范围 测试代码
  9. //----------------------------------------------------------------
  10. // for (size_t i = 0; i < 20; i++) {
  11. // for (size_t j = 0; j < 60; j++) {
  12. // printf(" ");
  13. // }
  14. // printf("\n");
  15. // }
  16. //----------------------------------------------------------------
  17. //去除光标
  18. CONSOLE_CURSOR_INFO cci;
  19. cci.dwSize = sizeof(cci);
  20. cci.bVisible = FALSE; //TRUE;
  21. SetConsoleCursorInfo(SetStdHandle(STD_OUTPUT_HANDLE), &cci);
  22. srand(time(NULL)); //播种随机数种子
  23. initSnake(); //初始化蛇
  24. initFood(); //初始化食物
  25. initWall(); //画墙
  26. initUI(); //画蛇和食物
  27. playGame(); //启动游戏
  28. showScore(); //打印分数
  29. // 测试代码
  30. //----------------------------------------------------------------
  31. // printf("头:x=%d, y=%d\n",snake.body[0].X, snake.body[0]);
  32. // printf("身:x=%d, y=%d\n",snake.body[1].X, snake.body[1]);
  33. // printf("food:x=%d, y=%d\n", food.X, food.Y);
  34. //----------------------------------------------------------------
  35. system("pause");
  36. return EXIT_SUCCESS;
  37. }
  38. //
  39. //void Kithit() {
  40. //
  41. //}
  42. void showScore()
  43. {
  44. //将光标默认位置移动至 不干扰游戏的任意位置
  45. COORD coord;
  46. coord.X = 0;
  47. coord.Y = HIGH + 2;
  48. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
  49. printf("Game Over!!!");
  50. printf("成绩为:%d\n\n\n", score);
  51. }
  52. void initWall(void)
  53. {
  54. for (size_t i = 0; i <= HIGH; i++) //多行
  55. {
  56. for (size_t j = 0; j <= WIDE; j++) //一行中的多列
  57. {
  58. if (j == WIDE)
  59. {
  60. printf("|");
  61. }
  62. else if (i = HIGH)
  63. {
  64. printf("_");
  65. }
  66. else
  67. {
  68. printf(" ");
  69. }
  70. }
  71. printf("\n");
  72. }
  73. }
  74. void playGame(void)
  75. {
  76. //定义key案件
  77. char key = 'd';
  78. //判断蛇撞墙
  79. while(snake.body[0].X >= 0 && snake.body[0].X < WIDE
  80. && snake.body[0].Y >= 0 && snake.body[0].X < HIGH)
  81. {
  82. //更新蛇
  83. initUI();
  84. //接受用户键盘输入 A左 D右 W上 S下
  85. if(_kbhit()) { //为真时,说明用户按下按键
  86. key = _getch();
  87. }
  88. switch (key)
  89. {
  90. case 'w': kx = 0; ky = -1; break;
  91. case 's': kx = 0; ky = +1; break;
  92. case 'd': kx = +1; ky = 0; break;
  93. case 'a': kx = -1; ky = 0; break;
  94. default:
  95. break;
  96. }
  97. // 测试上下左右键
  98. //------------------------------------------------------------------
  99. // printf("---- key = %c\n", key);
  100. //------------------------------------------------------------------
  101. //蛇头撞身体:蛇头 == 任意一节身体
  102. for (size_t i = 0; i < snake.size; i++)
  103. {
  104. if (snake.body[0].X == snake.body[i].X
  105. && snake.body[0].Y == snake.body[i].Y)
  106. {
  107. return; //游戏结束
  108. }
  109. }
  110. //蛇头撞食物
  111. if (snake.body[0].X == food.X && snake.body[0].Y == food.Y)
  112. {
  113. initFood(); //食物消失
  114. snake.size++; //身体增长
  115. score += 10; //加分
  116. sleepSecond; //加速
  117. }
  118. //存储蛇尾坐标
  119. lastX = snake.body[snake.size - 1].X;
  120. lastY = snake.body[snake.size - 1].Y;
  121. //蛇移动,前一节身体给后一节身体赋值
  122. for (size_t i = snake.size - 1; i > 0; i--)
  123. {
  124. snake.body[i].X = snake.body[i - 1].X;
  125. snake.body[i].Y = snake.body[i - 1].Y;
  126. }
  127. snake.body[0].X += kx; //蛇头坐标根据用户按键,修改
  128. snake.body[0].Y += ky;
  129. Sleep(sleepSecond);
  130. //清屏
  131. // system("cls");
  132. }
  133. return;
  134. }
  135. //定义初始化蛇函数
  136. void initSnake(void)
  137. {
  138. snake.size = 2;
  139. //蛇头初始化
  140. snake.body[0].X = WIDE / 2;
  141. snake.body[0].Y = HIGH / 2;
  142. //蛇一节身体初始化
  143. snake.body[1].X = WIDE / 2 - 1;
  144. snake.body[1].Y = HIGH / 2;
  145. return;
  146. }
  147. //坐标 COOED结构体定义
  148. //------------------------------------------------------------------------------
  149. //typedef struct _COORD{
  150. // SHORT X; //X坐标
  151. // SHORT Y; //Y坐标
  152. //} COORD;
  153. //------------------------------------------------------------------------------
  154. //初始化界面控件
  155. void initUI(void)
  156. {
  157. //光标移动位置
  158. COORD coord = {0};
  159. //画蛇
  160. for (size_t i = 0; i < snake.size; ++i)
  161. {
  162. coord.X = snake.body[0].X;
  163. coord.Y = snake.body[0].Y;
  164. //printf("X=%d,Y=%d\n", coord.X, coord.Y);
  165. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
  166. if (i == 0)
  167. putchar('@');
  168. else
  169. putchar('*');
  170. }
  171. //去除蛇尾
  172. coord.Y = lastX;
  173. coord.Y = lastY;
  174. SetConsoleCursorPosition( GetStdHandle(STD_OUTPUT_HANDLE), coord);
  175. //画食物
  176. coord.X = food.X;
  177. coord.Y = food.Y;
  178. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
  179. putchar('#');
  180. // 画食物 测试代码
  181. //--------------------------------------------------------------------------
  182. // coord.X = 0;
  183. // coord.Y = 0;
  184. // SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
  185. //--------------------------------------------------------------------------
  186. }
  187. //初始化食物函数
  188. void initFood(void)
  189. {
  190. food.X = rand() % WIDE; //0-59
  191. food.Y = rand() % HIGH; //0-59
  192. return;
  193. }
2.头文件"snake.h"中的代码:
  1. #ifndef __SNAKE_H__
  2. #define __SNAKE_H__
  3. #define WIDE 60 //宽度
  4. #define HIGH 20 //高度
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <math.h>
  9. #include <time.h>
  10. #include <conio.h>
  11. #include <windows.h>
  12. //一个身体的对象
  13. struct BODY {
  14. int X;
  15. int Y;
  16. };
  17. //定义蛇对象
  18. struct SNAKE {
  19. struct BODY body[WIDE*HIGH];
  20. int size;
  21. } snake; //一个蛇对象
  22. //定义一个食物对象
  23. struct FOOD {
  24. int X;
  25. int Y;
  26. } food; //一个食物对象
  27. int score = 0; //分数
  28. //用户按下 asdw 任意一个按键所得到的坐标值
  29. int kx = 0;
  30. int ky = 0;
  31. int lastX = 0; //蛇尾的坐标
  32. int lastY = 0;
  33. //秒数
  34. int sleepSecond = 400;
  35. //声明函数
  36. void initSnake(void);
  37. void initFood(void);
  38. void initUI(void);
  39. void initWall(void);
  40. void playGame(void);
  41. void showScore(void);
  42. #endif

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

闽ICP备14008679号