贪吃蛇小游戏—C++、Opencv编写实现
贪吃蛇游戏,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>
-
<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; //是否击中目标box
-
Box 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>
原理很简单,部分代码有注释,就不多说了,欢迎探讨。