C++ vector容器实现贪吃蛇小游戏

 更新时间:2020年04月28日 09:25:01   作者:白家名  
这篇文章主要为大家详细介绍了C++ vector容器实现贪吃蛇小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++ vector容器 实现贪吃蛇,供大家参考,具体内容如下

使用vector容器实现贪吃蛇简化了很多繁琐操作,且相比之前我的代码已经做到了尽量的简洁

技术环节:

编译环境:windows VS2019

需求:

控制贪吃蛇吃食物,吃到一个食物蛇身变长一节,得分增加,撞墙或撞自己则游戏结束。

思路:

创建一个vector容器,容器内存储蛇的每节身体的结构变量,结构变量中保存蛇身体的xy坐标,通过使用vector成员方法不断添加和删除容器中的数据,实现蛇坐标的规律移动,吃到食物等时执行对应操作。

在代码注释中标注了每一步是怎么实现的。

注意:

由于编译器原因程序中_kbhit()和_getch()函数可能在其他编译器上编译会出现错误,解决办法是去掉函数前面的“_”。

运行效果:

#include <iostream>
#include <vector>
#include <windows.h>
#include <conio.h>
#include <ctime>

using namespace std;


void gotoxy(int x, int y); //光标定位

//食物类
class Food
{
private:
 int m_x;
 int m_y;
public:
 void randfood() //随机产生一个食物
 {
 srand((int)time(NULL));
 L1:
 m_x = rand() % (85) + 2;
 m_y = rand() % (25) + 2;

 if (m_x % 2) //如果食物的x坐标不是偶数则重新确定食物的坐标
 goto L1;

 gotoxy(m_x, m_y); //在确认好的位置输出食物
 cout << "★";
 }
 int getFoodm_x() //返回食物的x坐标
 {
 return m_x;
 }
 int getFoodm_y() //返回食物的y坐标
 {
 return m_y;
 }
};

//蛇类
class Snake
{
private:
 //蛇坐标结构
 struct Snakecoor
 {
 int x;
 int y;
 };
 //蛇容器
 vector<Snakecoor> snakecoor;


 //判断和改变方向函数
 void degdir(Snakecoor& nexthead) //参数:新蛇头结构变量、蛇坐标容器
 {
 static char key = 'd'; //静态变量防止改变移动方向后重新改回来

 if (_kbhit()) //改变蛇前进的方向
 {
 char temp = _getch();

 switch (temp) //如果临时变量的值为wasd中的一个,则赋值给key
 {
 default:
 break;
 case 'w':
 case 'a':
 case 's':
 case 'd':
 //如果temp的方向和key的方向不相反则赋值
 if ((key == 'w' && temp != 's') || (key == 's' && temp != 'w') || \
 (key == 'a' && temp != 'd') || (key == 'd' && temp != 'a'))
 key = temp;
 }
 }


 switch (key) //根据key的值确定蛇的移动方向
 {
 case 'd':
 nexthead.x = snakecoor.front().x + 2; //新的蛇头的头部等于容器内第一个数据(旧蛇头)x坐标+2
 nexthead.y = snakecoor.front().y;
 break;
 case 'a':
 nexthead.x = snakecoor.front().x - 2;
 nexthead.y = snakecoor.front().y;
 break;
 case 'w':
 nexthead.x = snakecoor.front().x;
 nexthead.y = snakecoor.front().y - 1;
 break;
 case 's':
 nexthead.x = snakecoor.front().x;
 nexthead.y = snakecoor.front().y + 1;
 }

 }

 //游戏结束时需要做的事情
 void finmatt(const int score)
 {
 system("cls");
 gotoxy(40, 14);
 cout << "游戏结束";
 gotoxy(40, 16);
 cout << "得分:" << score;
 gotoxy(0, 26);
 exit(0);
 }

 //游戏结束的情况
 void finishgame(const int score)
 {
 //撞墙情况
 if (snakecoor[0].x >= 88 || snakecoor[0].x < 0 || snakecoor[0].y >= 28 || snakecoor[0].y < 0)
 finmatt(score);

 //撞到自己情况
 for (int i = 1; i < snakecoor.size(); i++)
 if (snakecoor[0].x == snakecoor[i].x && snakecoor[0].y == snakecoor[i].y)
 finmatt(score);
 }
public:
 //构造初始化蛇的位置
 Snake()
 {
 Snakecoor temp; //临时结构变量用于创建蛇

 for (int i = 5; i >= 0; i--) //反向创建初始蛇身,初始蛇头朝东
 {
 temp.x = 16 + (i << 1); //偶数
 temp.y = 8;
 snakecoor.push_back(temp);
 }

 }

 //蛇运动主要函数
 void move(Food& food, int& score)
 {
 Snakecoor nexthead; //新蛇头变量

 degdir(nexthead); //判断和改变蛇前进的方向

 snakecoor.insert(snakecoor.begin(), nexthead); //将新的蛇头插入容器头部

 gotoxy(0, 0);
 cout << "得分:" << score; //每次移动都在左上角刷新得分

 finishgame(score); //判断游戏结束函数

 if (snakecoor[0].x == food.getFoodm_x() && snakecoor[0].y == food.getFoodm_y()) //蛇头与食物重合
 {
 gotoxy(snakecoor[0].x, snakecoor[0].y); //吃到食物时因为直接返回此次移动没有输出蛇身,会少输出一次蛇
 cout << "●"; //所以在这里补上蛇移动时需要输出的字符
 gotoxy(snakecoor[1].x, snakecoor[1].y);
 cout << "■";

 score++; //吃到食物得分+1

 food.randfood(); //如果蛇头坐标和食物坐标重合则重新产生一个食物
 return; //直接结束本次移动
 }

 for (int i = 0; i < snakecoor.size(); i++) //遍历容器,判断食物与蛇身是否重合并输出整条蛇
 {
 gotoxy(snakecoor[i].x, snakecoor[i].y);

 if (!i) //头部输出圆形否则输出方块
 cout << "●";
 else
 cout << "■";

 //如果食物刷新到了蛇身上,则重新产生一个食物
 if (snakecoor[i].x == food.getFoodm_x() && snakecoor[i].y == food.getFoodm_y())
 food.randfood();
 }

 gotoxy(snakecoor.back().x, snakecoor.back().y); //在容器尾部的地方输出空格
 cout << " ";
 snakecoor.pop_back(); //删除容器中最后一个数据
 }

};


void HideCursor() //隐藏光标
{
 CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void gotoxy(int x, int y) //光标定位
{
 COORD pos = { x,y };
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

//主函数
int main()
{
 system("mode con cols=88 lines=28"); //设置控制台窗口大小
 system("title C++ 贪吃蛇");  //设置标题
 HideCursor();  //光标隐藏

 int score = 0; //得分变量

 Food food; //食物对象
 food.randfood(); //开局随机产生一个食物

 Snake snake; //蛇对象


 while (true)
 {
 snake.move(food, score);//蛇移动

 Sleep(150); //游戏速度
 }

 return 0;
}

不足之处:

因为初学C++,所以程序中肯定还有一些不规范或不合理的地方。

关于C++小游戏的更多精彩内容请点击专题: 《C++经典小游戏》 学习了解

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++实现LeetCode(206.倒置链表)

    C++实现LeetCode(206.倒置链表)

    这篇文章主要介绍了C++实现LeetCode(206.倒置链表),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++代码实现学生信息管理系统

    C++代码实现学生信息管理系统

    这篇文章主要为大家详细介绍了C++代码实现学生信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • 用c语言编写一个通讯录代码详解

    用c语言编写一个通讯录代码详解

    大家好,本篇文章主要讲的是用c语言实现一个通讯录代码详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • C++接口文件小技巧之PIMPL详解

    C++接口文件小技巧之PIMPL详解

    C++ 里面有一些惯用法(idioms),如 RAII,PIMPL,copy-swap、CRTP、SFINAE 等,今天要说的是 PIMPL,即 Pointer To Implementation,指向实现的指针,感兴趣的可以了解一下
    2023-06-06
  • C++中如何调用C语言的代码实现

    C++中如何调用C语言的代码实现

    这篇文章主要介绍了C++中如何调用C语言的代码实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • C++两种素数判定方法

    C++两种素数判定方法

    这篇文章主要介绍了C++如何判断一个数是不是素数,提供了两种方法具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • C语言求矩阵主对角线元素及副对角线元素之和

    C语言求矩阵主对角线元素及副对角线元素之和

    这篇文章主要介绍了C语言求矩阵主对角线元素及副对角线元素之和实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • C语言实现简单五子棋游戏

    C语言实现简单五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现简单五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • opencv检测直线方法之形态学方法

    opencv检测直线方法之形态学方法

    这篇文章主要为大家详细介绍了opencv检测直线方法之形态学方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • C++基础入门教程(六):为什么创建类的时候要用new?

    C++基础入门教程(六):为什么创建类的时候要用new?

    这篇文章主要介绍了C++基础入门教程(六):为什么创建类的时候要用new?本文讲解了使用new创建动态结构体、为什么要有new、自动存储(自动变量、局部变量)、动态存储、vector和array等内容,需要的朋友可以参考下
    2014-11-11

最新评论