贪吃蛇小游戏—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>
蛇身序列第一个(蛇头)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; //是否击中目标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>
原理很简单,部分代码有注释,就不多说了,欢迎探讨。
贪吃蛇小游戏—C++、Opencv编写实现的更多相关文章
- C++ 简单的控制台贪吃蛇小游戏
由于比较懒,所以不怎么写,觉得这样不应该.我应该对自己学的做出整理,不管是高端低端,写出来是自己的. // 贪吃蛇.cpp : 定义控制台应用程序的入口点. // #include "std ...
- 贪吃蛇小游戏-----C语言实现
1.分析 众所周知,贪吃蛇游戏是一款经典的益智游戏,有PC和手机等多平台版本,既简单又耐玩.该游戏通过控制蛇头方向吃食物,从而使得蛇变得越来越长,蛇不能撞墙,也不能装到自己,否则游戏结束.玩过贪吃蛇的 ...
- JS高级---案例:贪吃蛇小游戏
案例:贪吃蛇小游戏 可以玩的小游戏,略复杂,过了2遍,先pass吧 先创建构造函数,再给原型添加方法.分别创建食物,小蛇和游戏对象. 食物,小蛇的横纵坐标,设置最大最小值,运动起来的函数,按上下左右键 ...
- Java GUI学习,贪吃蛇小游戏
JAVA GUI练习 贪吃蛇小游戏 前几天虽然生病了,但还是跟着狂神学习了GUI的方面,跟着练习了贪吃蛇的小项目,这里有狂神写的源码点我下载,还有我跟着敲的点我下载,嘿嘿,也就注释了下重要的地方,这方 ...
- 用GUI实现java版贪吃蛇小游戏
项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public static void main(String[] args) { JFrame jFr ...
- Java 用java GUI写一个贪吃蛇小游戏
目录 主要用到 swing 包下的一些类 上代码 游戏启动类 游戏数据类 游戏面板类 代码地址 主要用到 swing 包下的一些类 JFrame 窗口类 JPanel 面板类 KeyListener ...
- html5面向对象做一个贪吃蛇小游戏
canvas加面向对象方式的贪吃蛇 2016-08-25 这个小游戏可以增加对面向对象的理解,可以加强js逻辑能力,总之认真自己敲一两遍收获还是不少啊!!适合刚学canvas的同学练习!! 废话不多说 ...
- 用python+pygame写贪吃蛇小游戏
因为python语法简单好上手,前两天在想能不能用python写个小游戏出来,就上网搜了一下发现了pygame这个写2D游戏的库.了解了两天再参考了一些资料就开始写贪吃蛇这个小游戏. 毕竟最开始的练手 ...
- Java贪吃蛇小游戏
贪吃蛇 思路 首先构思游戏布局,计算合理的坐标系. 绘制静态数据(广告.初始小蛇.提示信息.棋盘) 添加键盘监听事件,改变游戏状态以及小蛇运动方向 添加定时器,让小蛇在一段时间内移动一定的距离 随机产 ...
随机推荐
- BZOJ——1611: [Usaco2008 Feb]Meteor Shower流星雨
http://www.lydsy.com/JudgeOnline/problem.php?id=1611 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1 ...
- Ubuntu官方Wiki教程资源
前言:通常学习一样新知识时,最快的方式是通过搜索引擎然后以最快的方式拿枪上战场,如果接下来还一直依赖搜索引擎去打,那么你会发现自己永远都在打游击:那么如果要解决这个问题,必须要学会系统的学习,只有连贯 ...
- mysql 密碼忘記 解決
WINDOW 1.my.ini 加入 [mysqld] skip-grant-tables 2.mysql -uroot -p 登入 USE MYSQL: update user set passwo ...
- 【转载】云计算的三种服务模式:IaaS,PaaS和SaaS
一张图就看懂了.其他的都不用说了. 原文:http://blog.csdn.net/hjxgood/article/details/18363789
- 【转载】C#中的泛型
1.1 C#中的泛型 .Net 1.1版本最受诟病的一个缺陷就是没有提供对泛型的支持.通过使用泛型,我们可以极大地提高代码的重用度,同时还可以获得强类型的支持,避免了隐式的装箱.拆箱,在一定程度上提升 ...
- 使用 Docker 在 Linux 上托管 ASP.NET Core 应用程序
说在前面 在阅读本文之前,您必须对 Docker 的中涉及的基本概念以及常见命令有一定了解,本文侧重实战,不会对相关概念详述. 同时请确保您本地开发机器已完成如下安装: Docker 18.06 或更 ...
- ConcurrentHashMap源代码解析
这些天一直在看集合相关的源代码.确实学到了不少东西.这些集合都是息息相关的,学了就停不下来! 学集合就必须要学习锁的知识.学了锁那么并发编程的知识也不能少,都是非常重要的基础知识. jdk1.8的源代 ...
- 一个简单的EBNF范式的实现
最近无事在看书的时候发现了这个东西刹那间突然觉得大学时候编译原理书上的的什么语法分析书.上下文无关等晦涩难懂的概念清晰了许多今天把它贴出来希望也能让你回想起些往事... 至于EBNF范式是什么东西,网 ...
- AndroidCityPicker仿IOS选择效果
近期的一个项目由于android端与IOS端须要同步,所以在城市选择器这里做了一个相似IOS的CityPicker控件,当然由于本人水平问题显示效果比IOS上面还是有一定差距的.OK先让大家看下效果. ...
- 三分钟教你学Git(十四) 之 线下传输仓库
有时候还有一个人不能从远程直接clone仓库或者说由于非常大,clone非常慢或其他原因.我们能够使用bundle命令将Git仓库打包,然后通过U盘或者是其他介质拷贝给他,这样他拿到打包好的仓库后能够 ...