贪吃蛇小游戏—C++、Opencv编写实现

来源:互联网 发布:薪酬优化 北京公司 编辑:程序博客网 时间:2024/06/13 11:29

贪吃蛇游戏,C++、Opencv实现

设计思路:
1.显示初始画面,蛇头box初始位置为中心,食物box位置随机
2.按随机方向移动蛇头,按a、s、d、w键控制移动方向,分别为向左,向下,向右,向上
3.蛇头位置与食物box位置重合,则把食物box加入到蛇身向量arraryBox里,并设置食物box为第一个元素
4.蛇身各个box移动规律是,每次移动后一个box的位置变为前一个box的位置
5.蛇头移动超越边界,游戏结束


开始界面:



过程:



游戏结束:



编码:

控制方向模块:

<span style="font-size:18px;">//*************************************************************************************//通过键盘a s d w四个键控制上下左右移动方向;//int waittime; 等待时间,通过这个可以设置游戏的难易程度//bool &horizMove //允许水平移动标志//bool &verMove //允许垂直移动标志//int &moveDirection  具体移动方向,0:向左  1:向右  2:向上  3:向下//*************************************************************************************void MoveDirection(int waittime,bool &horizMove,bool &verMove,int &moveDirection){char pointKey=waitKey(waittime);switch (pointKey){case 'a':if(horizMove){moveDirection=0;horizMove=false;verMove=true;}break;case 'd':if(horizMove){moveDirection=1;horizMove=false;verMove=true;}break;case 's':if(verMove){moveDirection=3;horizMove=true;verMove=false;}break;case 'w':if(verMove){moveDirection=2;horizMove=true;verMove=false;}break;default:break;}}</span>

游戏结束判定模块:

<span style="font-size:18px;">//************************************************************************************//越界判断游戏是否结束//传入参数: Box序列//************************************************************************************bool GameOver(const vector<Box> arraryBox){if(arraryBox[0].boxPoint.x<0){putText(backGroundImage,"Game Over!",Point(50,200),1,3,Scalar(0,0,255),2,8,false);imshow(windowname,backGroundImage);return false;}if((arraryBox[0].boxPoint.x)>=Width){putText(backGroundImage,"Game Over!",Point(50,200),1,3,Scalar(0,0,255),2,8,false);imshow(windowname,backGroundImage);return false;}if(arraryBox[0].boxPoint.y<0){putText(backGroundImage,"Game Over!",Point(50,200),1,3,Scalar(0,0,255),2,8,false);imshow(windowname,backGroundImage);return false;}if((arraryBox[0].boxPoint.y)>=Hight){putText(backGroundImage,"Game Over!",Point(50,200),1,3,Scalar(0,0,255),2,8,false);imshow(windowname,backGroundImage);return false;}return true;}</span>


蛇身序列第一个(蛇头)Box根据移动方向移动模块:

<span style="font-size:18px;">//************************************************************************//根据移动方向改变第一个box的增长方向//const int moveDirection: 移动方向,0:向左  1:向右  2:向上  3:向下//vector<Box> arraryBox :Box 序列//************************************************************************void MoveAccordingDirecton(const int moveDirection, vector<Box> &arraryBox,Box & boxTarget){switch (moveDirection){case 0:arraryBox[0].boxPoint.x-=width;if(arraryBox[0].boxPoint==boxTarget.boxPoint){arraryBox.insert(arraryBox.begin(),boxTarget);meetTargetBox=true;}break;case 1:arraryBox[0].boxPoint.x+=width;if(arraryBox[0].boxPoint==boxTarget.boxPoint){arraryBox.insert(arraryBox.begin(),boxTarget);meetTargetBox=true;}break;case 2:arraryBox[0].boxPoint.y-=hight;if(arraryBox[0].boxPoint==boxTarget.boxPoint){arraryBox.insert(arraryBox.begin(),boxTarget);meetTargetBox=true;}break;case 3:arraryBox[0].boxPoint.y+=hight;if(arraryBox[0].boxPoint==boxTarget.boxPoint){arraryBox.insert(arraryBox.begin(),boxTarget);meetTargetBox=true;}break;default:break;}}</span>

蛇身每一个Box移动模块:

<span style="font-size:18px;">//******************************************************************************//定义蛇身box移动//每次移动,后一个box移动到前一个box位置//******************************************************************************void SnakeMove(vector<Box>&arraryBox1,vector<Box>&arraryBox,Mat &imageBackground){Box bb;arraryBox1.push_back(bb);arraryBox1[0]=arraryBox[0];for(int i=0;i<arraryBox.size();i++){if(i!=0){arraryBox1[1]=arraryBox[i];arraryBox[i]=arraryBox1[0];arraryBox1[0]=arraryBox1[1];}for(int i=0;i<arraryBox.size();i++){Mat ROICenterPoint=imageBackground(Rect(arraryBox[i].boxPoint.x,arraryBox[i].boxPoint.y,width,hight));addWeighted(ROICenterPoint,0,arraryBox[i].boxMat,1,0,ROICenterPoint);}}imshow(windowname,imageBackground);}</span>

主程序:

<span style="font-size:18px;">//*************************************************//贪吃蛇游戏,C++、Opencv实现//设计思路://1.显示初始画面,蛇头box初始位置为中心,食物box位置随机//2.按随机方向移动蛇头,按a、s、d、w键控制移动方向,分别为向左,向下,向右,向上//3.蛇头位置与食物box位置重合,则把食物box加入到蛇身向量arraryBox里,并设置食物box为第一个元素//4.蛇身各个box移动规律是,每次移动后一个box的位置变为前一个box的位置//5.蛇头移动超越边界,游戏结束//*************************************************#include <core/core.hpp>#include <highgui/highgui.hpp>#include <imgproc/imgproc.hpp>#include <iostream>#include <time.h>using namespace std;using namespace cv;//定义每个box大小和窗口大小int width=14;int hight=14;int Width=41*width;int Hight=41*hight;//定义box类,包含大小和位置信息class  Box{public:Mat boxMat;Point boxPoint;Box();};Box:: Box(){Mat image01(width,hight,CV_8UC3,Scalar(255,255,255));boxMat=image01;boxPoint=Point(((Width/width)/2+1)*width,((Hight/hight)/2+1)*hight);}vector<Box> arraryBox;vector<Box> arraryBox1;Mat image;int moveDirection;   //移动方向,bool horizMove=true;   //水平移动bool verMove=true;  //垂直移动bool meetTargetBox=false;  //是否击中目标boxBox boxTarget;Mat backGroundImage;string windowname="Gluttonous Snake ----by 牧野";//*************************************************************************************//通过键盘a s d w四个键控制上下左右移动方向;//int waittime; 等待时间,通过这个可以设置游戏的难易程度//bool &horizMove //允许水平移动标志//bool &verMove //允许垂直移动标志//int &moveDirection  具体移动方向,0:向左  1:向右  2:向上  3:向下//*************************************************************************************void MoveDirection(int waittime,bool &horizMove,bool &verMove,int &moveDirection);//************************************************************************************//越界判断游戏是否结束//传入参数: Box序列//************************************************************************************bool GameOver(const vector<Box> arraryBox);//******************************************************************************//定义蛇身box移动//每次移动,后一个box移动到前一个box位置//******************************************************************************void SnakeMove(vector<Box>&arraryBox1,vector<Box>&arraryBox,Mat &imageBackground);//************************************************************************//根据移动方向改变box//const int moveDirection: 移动方向,0:向左  1:向右  2:向上  3:向下//vector<Box> arraryBox :Box 序列//************************************************************************void MoveAccordingDirecton(const int moveDirection, vector<Box> &arraryBox,Box & boxTarget);int main(int argc,char* argv[]){Box box01;arraryBox.push_back(box01);srand(time(0));boxTarget.boxPoint.x=(rand()%(Width/width))*width;boxTarget.boxPoint.y=(rand()%(Hight/hight))*hight;moveDirection=rand()%4;  //初始化移动方向  0:向左   1:向右   2 向上  3 乡下   while(true){//判断是否越界,越界则游戏结束if(!GameOver(arraryBox)){break;}//初始化显示界面Mat imageBackground(Width,Hight,CV_8UC3,Scalar(0,0,0));Mat ROIBackground=imageBackground(Rect(boxTarget.boxPoint.x,boxTarget.boxPoint.y,width,hight));addWeighted(ROIBackground,0,boxTarget.boxMat,1,0,ROIBackground);Mat ROICenterPoint=imageBackground(Rect(arraryBox[0].boxPoint.x,arraryBox[0].boxPoint.y,width,hight));addWeighted(ROICenterPoint,0,arraryBox[0].boxMat,1,0,ROICenterPoint);if(arraryBox.size()>1){Mat imageBackground01(Width,Hight,CV_8UC3,Scalar(0,0,0));imageBackground=imageBackground01;Mat ROIBackground=imageBackground(Rect(boxTarget.boxPoint.x,boxTarget.boxPoint.y,width,hight));addWeighted(ROIBackground,0,boxTarget.boxMat,1,0,ROIBackground);}if(meetTargetBox){boxTarget.boxPoint.x=(rand()%(Width/width))*width;boxTarget.boxPoint.y=(rand()%(Hight/hight))*hight;Mat ROIBackground=imageBackground(Rect(boxTarget.boxPoint.x,boxTarget.boxPoint.y,width,hight));addWeighted(ROIBackground,0,boxTarget.boxMat,1,0,ROIBackground);meetTargetBox=false;}//通过键盘a s d w四个键控制上下左右移动方向;MoveDirection(10000,horizMove,verMove,moveDirection);//定义蛇身box移动SnakeMove(arraryBox1,arraryBox,imageBackground);//根据移动方向改变第一个box的增长方向MoveAccordingDirecton(moveDirection, arraryBox,boxTarget);backGroundImage=imageBackground;imshow(windowname,imageBackground);}waitKey();}</span>

原理很简单,部分代码有注释,就不多说了,欢迎探讨。


0 0
原创粉丝点击