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

Linux C++ 贪吃蛇游戏 -- 方向键控制蛇移动

1. 代码

#include <iostream>
#include <ncurses.h>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <thread>using namespace std;// 定义方向
enum class Direction { UP, DOWN, LEFT, RIGHT };class SnakeGame {
public:SnakeGame(int width, int height) : width(width), height(height), score(0), gameover(false) {srand(time(nullptr));initscr(); // 初始化终端keypad(stdscr, true); // 启用键盘输入noecho(); // 关闭回显nodelay(stdscr, true); // 非阻塞模式curs_set(0); // 隐藏光标getmaxyx(stdscr, max_y, max_x);window = newwin(height, width, (max_y - height) / 2, (max_x - width) / 2);box(window, 0, 0); // 绘制窗口边框refresh();wrefresh(window);generateFood();snake.push_back(make_pair(height / 2, width / 2)); // 初始化贪吃蛇位置drawSnake();}~SnakeGame() {delwin(window);endwin();}void run() {// 游戏循环while (!gameover) {int ch = getch();handleInput(ch);moveSnake();checkCollision();std::this_thread::sleep_for(std::chrono::milliseconds(100));}showGameOver();}private:int width, height;int score;bool gameover;int max_x, max_y;WINDOW *window;vector<pair<int, int>> snake;pair<int, int> food;Direction direction = Direction::RIGHT;void generateFood() {do {food.first = rand() % (height - 2) + 1;food.second = rand() % (width - 2) + 1;} while (isSnakeCell(food.first, food.second));mvwaddch(window, food.first, food.second, '@');refresh();wrefresh(window);}void drawSnake() {for (const auto& cell : snake) {mvwaddch(window, cell.first, cell.second, '#');}refresh();wrefresh(window);}void moveSnake() {pair<int, int> head = snake.front();pair<int, int> newHead = head;switch (direction) {case Direction::UP:newHead.first--;break;case Direction::DOWN:newHead.first++;break;case Direction::LEFT:newHead.second--;break;case Direction::RIGHT:newHead.second++;break;}snake.insert(snake.begin(), newHead);mvwaddch(window, newHead.first, newHead.second, '#');refresh();wrefresh(window);if (newHead != food) {mvwaddch(window, snake.back().first, snake.back().second, ' ');snake.pop_back();} else {score++;generateFood();}}void handleInput(int ch) {switch (ch) {case KEY_UP:if (direction != Direction::DOWN) {direction = Direction::UP;}break;case KEY_DOWN:if (direction != Direction::UP) {direction = Direction::DOWN;}break;case KEY_LEFT:if (direction != Direction::RIGHT) {direction = Direction::LEFT;}break;case KEY_RIGHT:if (direction != Direction::LEFT) {direction = Direction::RIGHT;}break;}}void checkCollision() {pair<int, int> head = snake.front();// 检查是否撞墙if (head.first == 0 || head.first == height - 1 || head.second == 0 || head.second == width - 1) {gameover = true;return;}// 检查是否撞到自己的身体for (size_t i = 1; i < snake.size(); i++) {if (snake[i] == head) {gameover = true;return;}}}void showGameOver() {clear();string gameOverText = "Game Over!";mvprintw(max_y / 2, (max_x - gameOverText.length()) / 2, gameOverText.c_str());string scoreText = "Score: " + to_string(score);mvprintw(max_y / 2 + 1, (max_x - scoreText.length()) / 2, scoreText.c_str());refresh();getch();}bool isSnakeCell(int row, int col) {for (const auto& cell : snake) {if (cell.first == row && cell.second == col) {return true;}}return false;}
};int main() {SnakeGame game(40, 20);game.run();return 0;
}

2. 编译命令

alfred@ubuntu:~/c_learning/d_cplusplus_learning$ g++ -std=c++11 snake.cpp -o snake -lncurses

3. 运行游戏,使用方向键 ↑ ↓ ← → 上下左右控制蛇移动

alfred@ubuntu:~/c_learning/d_cplusplus_learning$ ./snake

4. 调整蛇移动的速度

修改延时时间100,单位为ms,数字越小,移动越快,修改完后重新编译,运行

std::this_thread::sleep_for(std::chrono::milliseconds(100));

相关文章:

  • 三、Zookeeper数据模型
  • 苍穹外卖项目笔记(7)— 微信登录、商品浏览
  • python中序列类型运算符
  • 大数据Doris(三十一):Doris简单查询
  • LeetCode103. Binary Tree Zigzag Level Order Traversal
  • 微服务--03--OpenFeign 实现远程调用 (负载均衡组件SpringCloudLoadBalancer)
  • 快速安装Axure RP Extension for Chrome插件
  • WordPress(安装比子主题文件)zibll-7.5.1
  • springboot的配置文件加载总结
  • C++作业5
  • 流媒体方案之FFmpeg——实现物联网视频监控项目
  • 关于嵌入式系统一些名词的小结(ARM/CORTEX/STM32等)
  • 免费WordPress站群插件-批量管理站群的免费软件
  • ArkTS开发webview,html页面中的input和按钮等操作均无响应 【Bug已解决-鸿蒙开发】
  • android.view.WindowLeaked解决方法
  • python3.6+scrapy+mysql 爬虫实战
  • Angular4 模板式表单用法以及验证
  • AngularJS指令开发(1)——参数详解
  • dva中组件的懒加载
  • echarts的各种常用效果展示
  • es6--symbol
  • js继承的实现方法
  • text-decoration与color属性
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 阿里云购买磁盘后挂载
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 从重复到重用
  • 复杂数据处理
  • 近期前端发展计划
  • 前端面试题总结
  • 使用SAX解析XML
  • 思考 CSS 架构
  • 微信小程序设置上一页数据
  • 学习JavaScript数据结构与算法 — 树
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #Java第九次作业--输入输出流和文件操作
  • $$$$GB2312-80区位编码表$$$$
  • (26)4.7 字符函数和字符串函数
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (七)c52学习之旅-中断
  • (五)关系数据库标准语言SQL
  • (一)UDP基本编程步骤
  • (转)C#调用WebService 基础
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)我也是一只IT小小鸟
  • (转载)OpenStack Hacker养成指南
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .NET大文件上传知识整理
  • :O)修改linux硬件时间
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • [ C++ ] STL_list 使用及其模拟实现