鱼C论坛

 找回密码
 立即注册
查看: 6992|回复: 82

[技术交流] 贪吃蛇:C++

[复制链接]
发表于 2020-8-21 16:33:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 livcui 于 2020-8-22 21:22 编辑

Snake.gif
使用 EasyX 库制作的贪吃蛇,下面是源代码:    (没hide权限,骗不了回复)

另外,EasyX 仅支持 VC ,这是下载地址 https://easyx.cn/downloads/

如果不想安装 EasyX,可下载打包好的 EXE 文件 Snake.zip (43.95 KB, 下载次数: 48)



源文件:
  1. // Code.cpp
  2. #include "Snake.h"
  3. #include <cstdio>
  4. #include <string>
  5. #include <sstream>
  6. #include <time.h>
  7. #include <conio.h>

  8. Snake::Snake(): hwnd(initgraph(480 + 153, 480))// 设置窗口大小 (730, 480)
  9.                                 , speed(50), level_ () {

  10.         setbkcolor(WHITE);                // 窗口颜色为白 White

  11.         // 初始化蛇
  12.         snake.num = 3;                                // 初始化时为三节
  13.         snake.snakeXY[0].x = 20;        // 间隔10像素
  14.         snake.snakeXY[0].y = 0;
  15.         snake.snakeXY[1].x = 10;
  16.         snake.snakeXY[1].y = 0;
  17.         snake.snakeXY[2].x = 0;
  18.         snake.snakeXY[2].y = 0;
  19.         snake.postion = right;                // 初始化方向为右

  20.         // 初始化食物
  21.         food.foodXY.x = rand() % 65 * 10;        // 随机生成坐标
  22.         food.foodXY.y = rand() % 48 * 10;
  23.         food.flag = 1;                // 食物存在
  24.         // 检测食物和蛇坐标是否重复
  25.         for (int i = 0; i < snake.num; i++) {
  26.                 // 如果坐标重复,重新生成
  27.                 if (food.foodXY.x == snake.snakeXY[i].x and food.foodXY.y == snake.snakeXY[i].y) {
  28.                         food.foodXY.x = rand() % 65 * 10;
  29.                         food.foodXY.y = rand() % 48 * 10;
  30.                 }
  31.         }
  32. }
  33. Snake::~Snake() {}

  34. // 按键处理
  35. void Snake::keyDown() {

  36.         char userKey;
  37.         userKey = _getch();

  38.         switch (userKey) {

  39.                 // 上下左右
  40.         case right:
  41.                 if (snake.postion != down) snake.postion = up;
  42.                 break;
  43.         case left:
  44.                 if (snake.postion != right) snake.postion = left;
  45.                 break;
  46.         case down:
  47.                 if (snake.postion != left) snake.postion = right;
  48.                 break;
  49.         case up:
  50.                 if (snake.postion != up) snake.postion = down;
  51.                 break;

  52.                 // 调整速度(数字键 1, 2, 3, 4, ... , 10)
  53.         case 49:
  54.                 speed = 10;
  55.                 break;
  56.         case 50:
  57.                 speed = 20;
  58.                 break;
  59.         case 51:
  60.                 speed = 30;
  61.                 break;
  62.         case 52:
  63.                 speed = 40;
  64.                 break;
  65.         case 53:
  66.                 speed = 50;
  67.                 break;
  68.         case 54:
  69.                 speed = 60;
  70.                 break;
  71.         case 55:
  72.                 speed = 70;
  73.                 break;
  74.         case 56:
  75.                 speed = 80;
  76.                 break;
  77.         case 57:
  78.                 speed = 90;
  79.                 break;
  80.         case 48:
  81.                 speed = 100;
  82.                 break;
  83.         default:
  84.                 break;

  85.         }

  86. }
  87. // 画蛇
  88. void Snake::drawSnake() {

  89.         for (int i = 0; i < snake.num; i++) {

  90.                 setlinecolor(BLACK);        //矩形边框颜色为黑Black
  91.                 setfillcolor(BLUE);                //矩形内部颜色为蓝blue
  92.                 fillrectangle(snake.snakeXY[i].x, snake.snakeXY[i].y, snake.snakeXY[i].x + 10, snake.snakeXY[i].y + 10);
  93.         }
  94. }
  95. // 移动蛇
  96. void Snake::moveSnake() {

  97.         // 除蛇第一节以外的移动坐标处理
  98.         for (int i = snake.num - 1; i > 0; i--) {

  99.                 snake.snakeXY[i].x = snake.snakeXY[i - 1].x;
  100.                 snake.snakeXY[i].y = snake.snakeXY[i - 1].y;
  101.         }
  102.         // 第一节坐标处理
  103.         switch (snake.postion) {

  104.         case right:
  105.                 snake.snakeXY[0].x += 10;
  106.                 break;
  107.         case left:
  108.                 snake.snakeXY[0].x -= 10;
  109.                 break;
  110.         case down:
  111.                 snake.snakeXY[0].y += 10;
  112.                 break;
  113.         case up:
  114.                 snake.snakeXY[0].y -= 10;
  115.                 break;
  116.         default:
  117.                 break;
  118.         }
  119. }
  120. // 移动蛇 - 穿墙
  121. void Snake::moveSnake_2() {

  122.         // 除蛇第一节以外的移动坐标处理
  123.         for (int i = snake.num - 1; i > 0; i--) {

  124.                 snake.snakeXY[i].x = snake.snakeXY[i - 1].x;
  125.                 snake.snakeXY[i].y = snake.snakeXY[i - 1].y;
  126.         }
  127.         // 第一节坐标处理, 穿墙
  128.         switch (snake.postion) {

  129.         case right:
  130.                 snake.snakeXY[0].x += 10;
  131.                 break;
  132.         case left:
  133.                 snake.snakeXY[0].x -= 10;
  134.                 break;
  135.         case down:
  136.                 snake.snakeXY[0].y += 10;
  137.                 break;
  138.         case up:
  139.                 snake.snakeXY[0].y -= 10;
  140.                 break;
  141.         default:
  142.                 break;
  143.         }

  144.         if (snake.snakeXY[0].x > 470) snake.snakeXY[0].x = 0;
  145.         if (snake.snakeXY[0].x < 0) snake.snakeXY[0].x = 470;
  146.         if (snake.snakeXY[0].y > 470) snake.snakeXY[0].y = 0;
  147.         if (snake.snakeXY[0].y < 0) snake.snakeXY[0].y = 470;
  148. }
  149. // 初始化食物
  150. void Snake::initFood() {

  151.         srand(time(NULL));
  152.         food.foodXY.x = rand() % 48 * 10;        // 随机生成坐标
  153.         food.foodXY.y = rand() % 48 * 10;
  154.         food.flag = 1;

  155.         // 检测食物和蛇坐标是否重复
  156.         for (int i = 0; i < snake.num; i++) {
  157.                 // 如果坐标重复,重新生成
  158.                 if (food.foodXY.x == snake.snakeXY[i].x and food.foodXY.y == snake.snakeXY[i].y) {
  159.                         food.foodXY.x = rand() % 48 * 10;        // 随机生成坐标
  160.                         food.foodXY.y = rand() % 48 * 10;
  161.                 }
  162.         }
  163. }
  164. // 画食物
  165. void Snake::drawFood() {

  166.         fillrectangle(food.foodXY.x, food.foodXY.y, food.foodXY.x + 10, food.foodXY.y + 10);
  167.         setlinecolor(BLACK);        //矩形边框颜色为黑Black
  168.         setfillcolor(BLUE);                //矩形内部颜色为蓝blue

  169. }
  170. // 吃食物
  171. void Snake::eatFood() {

  172.         if (snake.snakeXY[0].x == food.foodXY.x and snake.snakeXY[0].y == food.foodXY.y) {

  173.                 // 蛇吃掉后长度 +1
  174.                 snake.num++;
  175.                 food.eatGrade += 1;
  176.                 food.flag = 0;

  177.                 // 蛇吃掉后重新画食物
  178.                 void drawFood();
  179.         }
  180. }
  181. // 判断蛇撞墙而死
  182. void Snake::snakeWallDie() {

  183.         if (snake.snakeXY[0].x > 470 or
  184.                 snake.snakeXY[0].x < 0 or
  185.                 snake.snakeXY[0].y > 470 or
  186.                 snake.snakeXY[0].y < 0 ) {
  187.                 outtextxy(200, 200, "你撞墙了!");
  188.                 snake.flag = 1;                // 蛇死亡
  189.         }
  190. }
  191. // 判断蛇自杀而死
  192. void Snake::snakeBodyDie() {

  193.         for (int i = 1; i < snake.num; i++) {

  194.                 if (snake.snakeXY[0].x == snake.snakeXY[i].x and snake.snakeXY[0].y == snake.snakeXY[i].y) {
  195.                         outtextxy(200, 200, "你自杀了!");

  196.                         snake.flag = 1;                // 蛇死亡
  197.                 }
  198.         }
  199. }
  200. // 显示分数
  201. void Snake::showGrade() {

  202.         //char arr[10];
  203.         //sprintf(arr, "%d", food.eatGrade);
  204.         std::ostringstream ss;
  205.         ss << food.eatGrade;
  206.         std::string str = ss.str();
  207.         setbkmode(BLUE);
  208.         settextcolor(BLACK);
  209.         outtextxy(500, 25, "分数");
  210.         outtextxy(550, 25, str.c_str());
  211. }

  212. // 运行
  213. void Snake::run() {

  214.         setbkcolor(BLACK);                // 窗口颜色为黑 BLACK
  215.         settextcolor(WHITE);        // 文字颜色
  216.         outtextxy(50, 50, "选择模式");
  217.         outtextxy(60, 80, "( 1    经典");
  218.         outtextxy(60, 100, "( 2    围墙");
  219.         
  220.         switch (_getch()) {

  221.         case '1':
  222.                 level_ = 0;
  223.                 break;
  224.         case '2':
  225.                 level_ = 1;
  226.                 break;
  227.         default:
  228.                 level_ = 0;
  229.         }
  230.         setbkcolor(WHITE);                // 窗口颜色为白 WHITE

  231. loop:
  232.         while (true) {
  233.         
  234.                 while (_kbhit()) {

  235.                         keyDown();                // 如果有键盘输入, 检测输入
  236.                 }
  237.                 cleardevice();        // 刷新
  238.                 switch (level_){        // 不同模式
  239.                 case 0:
  240.                         snakeBodyDie();
  241.                         moveSnake_2();                                // 移动蛇 - 穿墙
  242.                         setlinecolor(BLACK);                // 画线颜色为黑 Black
  243.                         setlinestyle(PS_DASH, 2);        // 设置线 (虚线, 宽 2)
  244.                         line(480, 480, 480, 0);                // 画线
  245.                         // 线条恢复默认
  246.                         setlinestyle(PS_SOLID, 1);        // 设置线 (实线, 宽 1)
  247.                         outtextxy(500, 60, "游戏模式 : ");
  248.                         outtextxy(590, 60, "经典");
  249.                         break;
  250.                 case 1:
  251.                         snakeWallDie();
  252.                         snakeBodyDie();
  253.                         moveSnake();                                // 移动蛇 - 围墙
  254.                         setlinecolor(BLACK);                // 画线颜色为黑 Black
  255.                         setlinestyle(PS_SOLID, 5);        // 设置线 (实线, 宽 5)
  256.                         line(480, 480, 480, 0);                // 画线
  257.                         line(1, 1, 1, 480);
  258.                         line(479, 479, 1, 479);
  259.                         line(1, 1, 480, 1);
  260.                         // 线条恢复默认
  261.                         setlinestyle(PS_SOLID, 1);        // 设置线 (实线, 宽 1)
  262.                         outtextxy(500, 60, "游戏模式 : ");
  263.                         outtextxy(590, 60, "围墙");
  264.                         break;
  265.                 default:
  266.                         snakeBodyDie();
  267.                         moveSnake_2();        // 移动蛇 - 穿墙
  268.                         setlinecolor(BLACK);                // 画线颜色为黑 Black
  269.                         setlinestyle(PS_DASH, 2);        // 设置线 (虚线, 宽 2)
  270.                         line(480, 480, 480, 0);                // 画线
  271.                         // 线条恢复默认
  272.                         setlinestyle(PS_SOLID, 1);        // 设置线 (实线, 宽 1)
  273.                         break;
  274.                 }
  275.                 drawSnake();        // 画蛇
  276.                 if (snake.flag == 1) {                // 如果蛇死了...

  277.                         if (MessageBox(NULL, "再玩一局?", "GameOver", MB_YESNO) != IDYES) return;
  278.                         else {
  279.                                 snake.flag = 0;
  280.                                 snake.num = 3;
  281.                                 snake.snakeXY[0].x = 20;
  282.                                 snake.snakeXY[0].y = 0;
  283.                                 snake.snakeXY[1].x = 10;
  284.                                 snake.snakeXY[1].y = 0;
  285.                                 snake.snakeXY[2].x = 0;
  286.                                 snake.snakeXY[2].y = 0;
  287.                                 snake.postion = right;
  288.                                 food.eatGrade = 0;
  289.                                 goto loop;
  290.                                 
  291.                         }
  292.                 }
  293.                 if (food.flag != 1) initFood();                // 初始化食物
  294.                 if (food.flag == 1) drawFood();                // 画食物
  295.                 eatFood();                // 吃食物
  296.                 showGrade();                // 显示分数

  297.                 outtextxy(530, 450, "作者: livcui");

  298.                 Sleep(speed);                // 间隔时间50ms
  299.         }

  300.         char ch = getchar();        // 退出
  301. }
复制代码
  1. // Main.cpp
  2. #include "Snake.h"
  3. #include <Windows.h>
  4. #include <graphics.h>
  5. #include <conio.h>

  6. int main() {

  7.         Snake snake;
  8.         snake.run();

  9.         return 0;
  10. }
复制代码


头文件:
  1. // Snake.h
  2. #ifndef SNAKE_H_
  3. #define SNAKE_H_
  4. #include <graphics.h>
  5. #include <conio.h>

  6. class Snake {

  7. private:

  8.         HWND hwnd;
  9.         int speed;
  10.         int level_;

  11.         // 坐标 XY
  12.         struct pointXY {
  13.                 int x;
  14.                 int y;
  15.         };
  16.         // 蛇属性
  17.         struct snakeProperty {
  18.                 int num;                                //蛇的节数
  19.                 pointXY snakeXY[100];   //节数最多100节
  20.                 char postion;                        //方向
  21.                 int flag;                                //蛇是否死亡
  22.         } snake;
  23.         // 枚举方向
  24.         enum movPostion {

  25.                 right = 72, left = 75, down = 77, up = 80        //对应上下左右键的键码值
  26.                 //right = 'd', left = 'a', down = 's', up = 'w'        //对应dasw键的键码值
  27.         };

  28.         //食物的属性
  29.         struct foodProperty {

  30.                 pointXY foodXY;                // 食物坐标
  31.                 int eatGrade;                // 吃掉食物所得分数
  32.                 int flag;                    // 食物是否存在

  33.         }food;

  34.         void keyDown();                // 按键处理
  35.         void drawSnake();        // 画蛇
  36.         void moveSnake();        // 移动蛇
  37.         void moveSnake_2();        // 移动蛇 - 穿墙
  38.         void drawFood();        // 画食物
  39.         void eatFood();                // 吃食物
  40.         void snakeDie();        // 判断蛇死亡
  41.         void snakeWallDie();// 判断蛇撞墙死亡
  42.         void snakeBodyDie();// 判断蛇自杀而死
  43.         void showGrade();        // 显示分数
  44.         void initFood();        // 初始化食物

  45. public:
  46.         Snake();
  47.         ~Snake();
  48.         void run();

  49. };

  50. #endif
复制代码

评分

参与人数 3荣誉 +3 鱼币 +1 收起 理由
鱼的七秒记忆 + 1 感谢楼主无私奉献!
xiao-wugui + 1 + 1 鱼C有你更精彩^_^
昨非 + 1 我没白嫖鱼币,真心支持,感谢

查看全部评分

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-21 16:33:59 | 显示全部楼层
本帖最后由 livcui 于 2020-8-21 16:35 编辑

自占沙发
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 16:40:07 | 显示全部楼层
1.png
2.png
3.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 16:41:27 | 显示全部楼层

回帖奖励 +3 鱼币

用exe试的呀
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 16:49:58 | 显示全部楼层
不错哦
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 17:02:20 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-21 17:39:25 | 显示全部楼层
厉害了!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 17:48:25 | 显示全部楼层

回帖奖励 +3 鱼币

谢谢大佬!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-21 17:58:41 | 显示全部楼层
本帖最后由 livcui 于 2020-8-21 22:30 编辑


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 19:59:21 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 20:29:37 | 显示全部楼层
牛啊
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-21 20:35:37 | 显示全部楼层

回帖奖励 +3 鱼币

厉害
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-21 21:04:56 | 显示全部楼层

回帖奖励 +3 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 21:14:08 | 显示全部楼层
大佬
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-21 21:25:36 | 显示全部楼层
66666
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-21 23:06:36 | 显示全部楼层

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-22 18:29:58 | 显示全部楼层
厉害
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-22 18:30:30 | 显示全部楼层

回帖奖励 +3 鱼币

玩玩
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-22 18:31:02 | 显示全部楼层
6666
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

头像被屏蔽
发表于 2020-8-22 19:43:35 | 显示全部楼层

回帖奖励 +3 鱼币

提示: 作者被禁止或删除 内容自动屏蔽
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-4 20:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表