当前位置: 首页 > news >正文

贪吃蛇--C++实战项目(零基础)

视频地址:C语言必学项目:贪吃蛇!

贪吃蛇游戏框架
├── 基础框架
│ ├── 头文件引入
│ ├── 常量和宏定义
│ └── 窗口初始化

├── 数据结构系统
│ ├── Pos结构体(位置和颜色)
│ ├── Snake结构体(蛇的属性)
│ ├── Food结构体(食物属性)
│ └── DIR枚举(方向控制)

├── 初始化系统
│ ├── 随机种子设置
│ ├── 蛇属性初始化
│ ├── 蛇身位置初始化
│ └── 食物生成

├── 绘制系统
│ ├── 清屏操作
│ ├── 蛇身绘制
│ ├── 食物绘制
│ └── 分数显示

├── 控制系统
│ ├── 键盘输入检测
│ ├── 方向键处理
│ └── 防反向移动逻辑

├── 移动系统
│ ├── 蛇身跟随算法
│ └── 蛇头方向移动

├── 食物系统
│ ├── 食物生成算法
│ ├── 碰撞检测
│ ├── 分数增加
│ └── 蛇身增长

└── 游戏循环
├── 绘制→移动→输入→检测
└── 速度控制

游戏实现步骤分析

1. 基础框架搭建

// 1. 包含必要的头文件
#include <graphics.h>  // EasyX图形库
#include <conio.h>     // 控制台输入输出
#include <iostream>    // 标准输入输出
using namespace std;// 2. 定义游戏窗口大小和常量
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500

2. 数据结构设计

// 3. 定义位置结构体
struct Pos {int x;int y;DWORD color;
};// 4. 定义蛇结构体
struct Snake {int num;      // 蛇节数int dir;      // 方向int score;    // 分数int size;     // 尺寸int speed;    // 速度Pos coor[MAX_SNAKE]; // 坐标数组
};// 5. 定义食物结构体
struct Food {int x;int y;DWORD color;bool flag;    // 是否存在
};// 6. 定义方向枚举
enum DIR { UP, DOWN, LEFT, RIGHT };

3. 游戏初始化

void GameInit() {// 初始化随机种子srand(GetTickCount());// 设置蛇的初始属性snake.num = 3;snake.dir = RIGHT;snake.score = 0;snake.size = 10;snake.speed = 10;// 初始化蛇身位置和颜色snake.coor[0].x = 20;snake.coor[0].y = 0;snake.coor[0].color = RGB(rand() % 256, rand() % 256, rand() % 256);// 随机生产颜色snake.coor[1].x = 10;snake.coor[1].y = 0;snake.coor[1].color = RGB(rand() % 256, rand() % 256, rand() % 256);snake.coor[2].x = 0;snake.coor[2].y = 0;snake.coor[2].color = RGB(rand() % 256, rand() % 256, rand() % 256);// 初始化食物createFood();
}

4. 游戏绘制系统

void GameDraw() {cleardevice(); // 清屏// 绘制蛇身for (int i = 0; i < snake.num; i++) {setfillcolor(snake.coor[i].color);fillrectangle(snake.coor[i].x, snake.coor[i].y,snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);}// 绘制食物if (food.flag) {setfillcolor(food.color);solidellipse(food.x, food.y, food.x + 10, food.y + 10);}// 绘制分数char temp[20] = "";sprintf(temp, "分数: %d", snake.score);outtextxy(10, 10, temp);
}

5. 输入控制系统

void GameController() {if (_kbhit()) {char key = _getch();switch (key) {case 72: if (snake.dir != DOWN) snake.dir = UP; break;case 80: if (snake.dir != UP) snake.dir = DOWN; break;case 75: if (snake.dir != RIGHT) snake.dir = LEFT; break;case 77: if (snake.dir != LEFT) snake.dir = RIGHT; break;}}
}

6. 移动逻辑实现

void GameMove() {// 蛇身跟随移动for (int i = snake.num - 1; i > 0; i--) {snake.coor[i].x = snake.coor[i - 1].x;snake.coor[i].y = snake.coor[i - 1].y;}// 蛇头移动switch (snake.dir) {case UP:    snake.coor[0].y -= snake.speed; break;case DOWN:  snake.coor[0].y += snake.speed; break;case LEFT:  snake.coor[0].x -= snake.speed; break;case RIGHT: snake.coor[0].x += snake.speed; break;}
}

7. 食物系统

void createFood() {food.x = rand() % (WIDTH / 10) * 10;food.y = rand() % (HEIGHT / 10) * 10;food.color = RGB(rand() % 256, rand() % 256, rand() % 256);food.flag = true;
}void EatFood() {if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y) {food.flag = false;snake.num++;snake.score += 10;snake.coor[snake.num - 1].color = RGB(rand() % 256, rand() % 256, rand() % 256);createFood();}
}

8. 游戏主循环

int main() {initgraph(WIDTH, HEIGHT);setbkcolor(RGB(207, 214, 229));GameInit();while (true) {GameDraw();        // 绘制GameMove();        // 移动if(_kbhit()) {     // 输入检测GameController();}EatFood();         // 食物检测Sleep(100);        // 控制速度}return 0;
}

9. 完整代码

// 导入图形界面库 EasyX
#include <graphics.h>
//控制键盘的头文件
#include<conio.h>
#include<iostream>
using namespace std;// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500  // 常量struct Pos{int x;int y;DWORD color;//DWORD 是 Windows API 中定义的数据类型
};struct Snake{int num;      // 蛇身体的节数int dir;      // 蛇的方向int score;    // 分数int size;     // 蛇的宽和高int speed;    // 蛇的速度// 记录蛇的坐标数组struct Pos coor[MAX_SNAKE];
};struct Snake snake;//结构体变量struct Food{int x;int y;DWORD color;bool flag; // 是否被吃掉
} food;enum DIR
{UP,DOWN,LEFT,RIGHT
};// 初始化一下数据
void GameInit() {//蛇的身体的颜色随机变化srand(GetTickCount());snake.num = 3;snake.dir = RIGHT;snake.score = 0;snake.size = 10;snake.speed = 10;// 初始化蛇身位置和颜色for (int i = 0; i < snake.num; i++) {snake.coor[i].x = 20 - i * 10;snake.coor[i].y = 0;snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);}// 初始化食物 颜色随机变化createFood();
}// 画蛇 画食物 画分数
void GameDraw() {cleardevice();for (int i = 0; i < snake.num; i++){// 填充一下颜色setfillcolor(snake.coor[i].color);// 画矩形(修正后的)fillrectangle(snake.coor[i].x, snake.coor[i].y,snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);}// 绘制食物if (food.flag){setfillcolor(food.color);solidellipse(food.x, food.y, food.x + 10, food.y + 10);}// 绘制分数char temp[20] = "";sprintf(temp, "分数: %d", snake.score);outtextxy(10, 10, temp);
}//控制蛇的方向
void GameController() {// 获取键盘char key = _getch();// 控制蛇不能往回走switch (key) {case 72: if (snake.dir != DOWN) snake.dir = UP; break;case 80: if (snake.dir != UP) snake.dir = DOWN; break;case 75: if (snake.dir != RIGHT) snake.dir = LEFT; break;case 77: if (snake.dir != LEFT) snake.dir = RIGHT; break;}//cout << (int)key << endl;
}// 让蛇动起来
void GameMove() {// 循环部分 - 控制蛇身移动for (int i = snake.num - 1; i > 0; i--){snake.coor[i].x = snake.coor[i - 1].x;snake.coor[i].y = snake.coor[i - 1].y;}// switch部分 - 控制蛇头移动 [蛇头控制方向,蛇身跟随前一个位置]switch (snake.dir) {case UP:snake.coor[0].y -= snake.speed;break;case DOWN:snake.coor[0].y += snake.speed;break;case LEFT:snake.coor[0].x -= snake.speed;break;case RIGHT:snake.coor[0].x += snake.speed;break;}
}// 创建新食物的函数
void createFood() {food.x = rand() % (WIDTH / 10) * 10;food.y = rand() % (HEIGHT / 10) * 10;food.color = RGB(rand() % 256, rand() % 256, rand() % 256);food.flag = true;
}void EatFood() {// 碰撞检测if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y){// 吃到了food.flag = false;snake.num++;snake.score += 10;snake.coor[snake.num - 1].color = RGB(rand() % 256, rand() % 256, rand() % 256);// 吃完了 在重新创建一个新的食物createFood();}
}
int main() {// 初始化图形窗口initgraph(WIDTH, HEIGHT);// 设置背景色为浅蓝灰色setbkcolor(RGB(207, 214, 229));//清屏再重新绘制所有内容cleardevice();// 初始化蛇的数据GameInit();// 游戏主循环while (true) {GameDraw();GameMove();// 如果按了键盘就会执行if(_kbhit()){GameController();}EatFood();Sleep(100);}return 0;
}

10. 改进建议

  1. 添加碰撞检测 - 检测撞墙和自身碰撞
  2. 改进输入处理 - 使用Windows API处理方向键
  3. 添加游戏状态 - 游戏开始、暂停、结束状态优化
  4. 食物生成 - 避免食物生成在蛇身上添
  5. 加音效 - 吃食物和游戏结束的音效
http://www.dtcms.com/a/344701.html

相关文章:

  • 直播间聊天室直播录播消息发送自动对话点赞H5开源
  • Datawhale AI夏令营---coze空间共学
  • RoboTwin--CVPR2025--港大--2025.4.17--开源
  • NLP 场景下的强化学习
  • 数据分析编程第二步: 最简单的数据分析尝试
  • 总线之间的关系,64位32位与DB数据总线CB控制总线与AB地址总线的关系
  • Spring 中 @Import 注解:Bean 注入的灵活利器
  • Java面试-自动装箱与拆箱机制解析
  • Springboot项目的各层级详细总结
  • 腾讯云COS SDK签名有效期设置为10分钟到期会自动刷新
  • 2721. 【SDOI2010】外星千足虫
  • ArduPilot plane 俯仰姿态稳定器源码逐行解析:从期望角度到升降舵 PWM_角度环角速度环
  • day24
  • Nginx(一)认识Nginx
  • 一级指针遍历二维数组
  • 3-2〔OSCP ◈ 研记〕❘ WEB应用攻击▸WEB安全防护体系
  • Python Flask快速实现163邮箱发送验证码
  • 防爆自动气象监测设备:高危环境的 “安全堡垒”
  • 高防cdn如何缓存网页静态资源
  • Nacos docker 版本配置kingbase 人大金仓 达梦 数据库
  • 定时器中断学习汇总
  • 从快递运输与排队办事,看实时通信的MVP方案与增强方案
  • V380E telnet远程连接导致rce漏洞复现(CVE-2025-7503)
  • 【解决办法】wps的word文档编辑时字体的下方出现灰色的底色如何删除
  • 【字节拥抱开源】字节豆包团队开源豆包OSS大模型
  • 数学建模--Topsis
  • LLM实践系列:利用LLM重构数据科学流程04 - 智能特征工程
  • Redis事务与锁的顺序抉择:事务里加锁 vs 先锁再事务的“微妙差异”分享
  • C#自定义工具类-时间日期工具类
  • 【python与生活】如何用Python写一个简单的自动整理文件的脚本?