贪吃蛇--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.pswp.cn/news/919774.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity资源领取反作弊工具加密器

https://assetstore.unity.com/packages/tools/utilities/anti-cheat-pro-2025-3006260元购码GUARDINGPEARSOFTWARE

FPGA设计中的信号完整性量化与优化:探索高速数字系统的关键路径

在高速FPGA设计中&#xff0c;信号完整性&#xff08;Signal Integrity, SI&#xff09;已成为确保系统稳定、可靠运行的核心要素之一。随着数据传输速率的不断提升和电路规模的日益复杂&#xff0c;信号在传输过程中受到的干扰和畸变问题日益凸显。因此&#xff0c;如何有效量…

`strncasecmp` 字符串比较函数

1) 函数的概念与用途 strncasecmp 是 C 语言中一个非常实用的字符串处理函数&#xff0c;它执行不区分大小写的字符串比较&#xff0c;但只比较前 n 个字符。这个函数的名字来源于"string n case-compare"&#xff08;字符串前n个字符不区分大小写比较&#xff09;。…

软件安装教程(一):Visual Studio Code安装与配置(Windows)

文章目录前言一、Visual Studio Code下载二、安装步骤&#xff08;Windows&#xff09;1. GUI安装2. 命令行安装三、首次启动后建议的快速配置&#xff08;几分钟完成&#xff09;四、常见问题 & 小贴士总结前言 Visual Studio Code&#xff08;VS Code&#xff09;是一款…

JavaSSM框架从入门到精通!第三天(MyBatis(二))!

四、Mapper 的动态代理1. 引入 在上面的 CURD 例子中&#xff0c;我们发现&#xff1a;Dao 层的实现类的每一个方法仅仅是通过 SqlSession 对象的相关 API 定位到映射文件 mapper 中的 SQL 语句&#xff0c;真正对数据库操作的工作实际上是有 Mybatis 框架通过 mapper 中的 SQL…

大模型应用发展与Agent前沿技术趋势(下)

Agent技术的行业应用与实践案例 金融领域的Agent应用 金融行业是大模型Agent技术应用最为广泛的领域之一&#xff0c;涵盖了风险评估、投资决策、客户服务等多个方面。在金融风控领域&#xff0c;Agent系统通过结合大模型的语义理解能力和强化学习的决策优化能力&#xff0c;能…

94. 城市间货物运输 I, Bellman_ford 算法, Bellman_ford 队列优化算法

94. 城市间货物运输 IBellman_ford 算法Bellman_ford 算法 与 dijkstra算法 相比通用性更强。dijkstra算法解决不了负权边的问题&#xff0c;因为Dijkstra基于贪心策略&#xff0c;一旦一个节点被从队列中取出&#xff08;标记为已解决&#xff09;&#xff0c;它就假定已经找到…

如何使用Prometheus + Grafana + Loki构建一个现代化的云原生监控系统

如何使用 Prometheus + Grafana + Loki 构建一个现代化的云原生监控系统。这套组合被誉为监控领域的“瑞士军刀”,功能强大且生态极佳。 一、核心组件概念介绍 在搭建之前,深刻理解每个组件的角色和职责至关重要。 1. Prometheus(指标监控与时序数据库) 角色:系统的“核…

JavaScript Object 操作方法及 API

一、对象创建方式1.字面量创建&#xff08;最常用&#xff09;const obj { name: "张三", age: 25 };2.构造函数创建const obj new Object(); obj.name "李四";3.Object.create()&#xff08;指定原型&#xff09;const proto { greet: () > "…

pta乙级题目day1

第1天&#xff1a;输入输出与运算&#xff08;6题&#xff09;1001 害死人不偿命的(3n1)猜想&#xff08;基础运算&#xff09;★1006 换个格式输出整数&#xff08;格式化输出&#xff09;★1016 部分AB&#xff08;数字提取&#xff09;★★1046 划拳&#xff08;多输入处理&…

在VSCode中配置.NET项目的tasks.json以实现清理、构建、热重载和发布等操作

在 VS Code 中配置 .NET 开发任务的完整指南 引言 重要提醒&#xff1a;对于 .NET 开发&#xff0c;强烈推荐使用 Visual Studio&#xff0c;它提供了最完整和稳定的开发体验。如果你像我一样"蛋疼"想要尝试 VS Code&#xff0c;请确保安装了 C# 开发扩展包&#x…

EmEditor文本编辑器v25.3.0专业版,专业文本编辑,高亮显示,无限撤消

[软件名称]: EmEditor文本编辑器v25.3.0专业版 [软件大小]: 37.7 MB [软件大小]: 夸克网盘 | 百度网盘 软件介绍 EmEditor 是一款功能强大且非常实用的文本编辑器。它启动速度快&#xff0c;完全可以替代 Windows 自带的记事本&#xff0c;轻松应对日常文本编辑任务。它对 …

【spring security】权限管理组件执行流程详解

&#x1f3af; 权限管理组件执行流程详解 &#x1f3d7;️ 组件架构图 ┌─────────────────────────────────────────────────────────────┐ │ HTTP请求 …

redis怎么保障双写一致性

redis做为缓存&#xff0c;mysql的数据如何与redis进行同步呢&#xff1f;&#xff08;双写一致性&#xff09;候选人&#xff1a;嗯&#xff01;就说我最近做的这个项目&#xff0c;里面有xxxx&#xff08;根据自己的简历上写&#xff09;的功能&#xff0c;需要让数据库与red…

异常值检测:孤立森林模型(IsolationForest)总结

目录一、前言二、孤立森林算法2.1 算法简介2.2 基本原理2.3 算法步骤2.4 异常分数计算方式2.5 python调用方式三、python代码示例四、小结五、参考学习一、前言 近期在研究构建寿命预测模型&#xff0c;相信很多数据人都懂建模的过程&#xff0c;其实有80%的时间都是在和数据处…

Docker容器化部署实战:Tomcat与Nginx服务配置指南

部署Tomcat搜索镜像 使用以下命令搜索可用的Tomcat镜像&#xff1a;docker search tomcat拉取镜像 拉取官方Tomcat镜像&#xff1a;docker pull tomcat创建专用目录 为Tomcat配置和数据创建专用目录&#xff1a;mkdir tomcat运行临时容器并复制配置文件 启动临时容器以复制配置…

Go语言实战案例-使用SQLite实现本地存储

在开发工具类软件、桌面应用或者移动端时&#xff0c;我们经常需要一个轻量级数据库来做 本地存储。相比 MySQL、Postgres 等服务型数据库&#xff0c;SQLite 体积小、零配置、单文件存储&#xff0c;非常适合这种场景。Go 语言通过 GORM SQLite 驱动 就能轻松实现。本文将带你…

云计算学习100天-第23天

主机192.168.88.5 安装nginx#安装编译工具&#xff0c;正则表达式依赖包&#xff0c;SSL加密依赖包 yum -y install gcc make pcre-devel openssl-devel tar -xf /root/lnmp_soft.tar.gz cd lnmp_soft/ tar -xf nginx-1.22.1.tar.gz cd nginx-1.22.1/ #指定安装路径&…

【生成树+环】题解:P3907 环的异或_图论_环_异或_搜索_算法竞赛_C++

推销洛谷博客&#xff1a;https://www.luogu.com.cn/article/znmr9iu9 Link&#xff1a;Luogu - P3907 这里默认题目中指的环都是“简单环”&#xff08;即没有“环套环”的情况&#xff09;。 众所周知&#xff0c;树是图的一种特殊情况&#xff0c;且一定无环。如果我们想…

数据库优化提速(二)排序优化之搜索大数据酒店,进销存AI—仙盟创梦IDE

在 MySQL 数据库管理中&#xff0c;排序操作对于数据的有效展示和分析至关重要。本文将以一个实际的 SQL 查询为例&#xff0c;深入探讨排序优化方案&#xff0c;并结合进销存、酒店、知识库等大数据场景&#xff0c;阐述这些优化策略的应用价值。原始SELECT 应用编号, 应用序列…