基于C++与OpenCV的贪吃蛇小游戏(简单版)

 本人蒟蒻一个,因为学习OpenCV途中收到了要写贪吃蛇小游戏的要求

于是上网广搜精华

震惊的发现他们写的贪吃蛇都用了很多复杂的函数(包括类啊巴拉巴拉,让人很难看懂)

于是我自己琢磨了很长时间

写出来了一个比较平易近人的贪吃蛇版本 

也恳请各位大佬指正写的不好的地方

#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <time.h>
//Direction 0上 1是左 2是下 3是右
using namespace std;
using namespace cv;
//定义每个方块的高度
int height = 15;
int width = 15;
int Sizes = 20;//定义Size*Size的棋盘大小
int Height = height * Sizes;
int Width = width * Sizes;
//记录现在的方向 长度
int NowDirection = 1, Lenth;
int Difficult = 500;
bool Judge = true;
//随机数类 记住一定要在函数外声明
RNG rng = theRNG();
//位置类 a数组记录蛇 Food记录食物
class Position{
	public:
	int x;
	int y;
}a[3000],Food;
//方向输入
void ReadMoveDirection(int LastTimeDirction) {
	char pointKey = waitKey(Difficult);
	if(pointKey == 'w')
		NowDirection = 0;
	if(pointKey == 'a')
		NowDirection = 1;
	if(pointKey == 's')
		NowDirection = 2;
	if(pointKey == 'd')
		NowDirection = 3;
//确保不会向反方向走
	if (NowDirection == LastTimeDirction || NowDirection == LastTimeDirction + 2 || NowDirection == LastTimeDirction - 2 ) {
		NowDirection = LastTimeDirction;
	}
	return;
}
//初始化界面 可没有
void Start(void) {
	Mat image(Height, Width, CV_8UC3, Scalar(255, 255, 255));
	char StartKey = 'a';
	putText(image, "Press f to Start", Point(Width/2-120 ,Height/2 - 20 ), 2, 1, Scalar(0, 0, 0), 2);
	while (1) {
		imshow("贪吃蛇~", image);
		char StartKey = waitKey(20);
		if (StartKey == 'f') {
			destroyWindow("贪吃蛇~");
			break;
		}
	}
	return;
}
//制作食物
void MakeFood(void) {
	
	while (1) {
		bool s = true;
		int FoodX = rng.uniform(0, Sizes);
		int FoodY = rng.uniform(0, Sizes);
		for (int i = 1; i <= Lenth; i++)
			if (a[i].x == FoodX && a[i].y == FoodY) {
				s = false;
				break;
			}
		if (s) {
			Food.x = FoodX;
			Food.y = FoodY;
			//cout << FoodX << "TTT" << FoodY << endl;
			return;
		}
	}
}
//判断是否食物被吃掉
bool JudgeFood(void) {
	if (a[1].x == Food.x && a[1].y == Food.y) {
		a[Lenth + 1].x = a[Lenth].x;
		a[Lenth + 1].y = a[Lenth].y;
		Lenth++;
		
		return true;
	}
	else 
		return false;
}
//蛇头包括蛇身的移动,后一块继承前一块
void HeadMove(int MoveDirection,int len) {
	if (MoveDirection == 0) {
		for (int i = len; i >= 2; i--) {
			a[i].x = a[i - 1].x;
			a[i].y = a[i - 1].y;
		}
		a[1].y--;
	}
	if (MoveDirection == 1) {
		for (int i = len; i >= 2; i--) {
			a[i].x = a[i - 1].x;
			a[i].y = a[i - 1].y;
		}
		a[1].x--;
	}
	if (MoveDirection == 2) {
		for (int i = len; i >= 2; i--) {
			a[i].x = a[i - 1].x;
			a[i].y = a[i - 1].y;
		}
		a[1].y++;
	}
	if (MoveDirection == 3) {
		for (int i = len; i >= 2; i--) {
			a[i].x = a[i - 1].x;
			a[i].y = a[i - 1].y;
		}
		a[1].x++;
	}
	return;
}
//判断是否越界或者咬自己尾巴
bool JudgeOver(void){
	if (a[1].x == 0 || a[1].x == Sizes || a[1].y == 0 || a[1].y == Sizes )
		return true;
	else {
		for (int i = 2; i <= Lenth; i++)
			if (a[i].x == a[1].x && a[i].y == a[1].y)
				return true;
		return false;
	}
}
//游戏结束界面
void GameOver(Mat PreImage) {
	putText(PreImage, "You Loss!  ", Point(Width / 2 - 120, Height / 2 - 20), 2, 1, Scalar(5, 30, 216), 3);
	putText(PreImage, "Your Score : " + std::to_string(Lenth - 3), Point(Width / 2 - 120, Height / 2 + 10), 2, 1, Scalar(5, 30, 216), 3);
	imshow("GG!", PreImage);
	waitKey(0);
	return;
}
int main(int argc, char** argv) {
	Start();
	MakeFood();
//初始化蛇蛇
	Lenth = 3;
	a[1].x = Sizes / 2;
	a[1].y = Sizes / 2;
	a[2].x = a[1].x + 1;
	a[2].y = a[1].y;
	a[3].x = a[2].x + 1;
	a[3].y = a[2].y;
	Mat frame(Height, Width, CV_8UC3, Scalar(255, 255, 255));
	while(1){
		Mat frame(Height, Width, CV_8UC3, Scalar(255, 255, 255));
		ReadMoveDirection(NowDirection);
		HeadMove(NowDirection,Lenth);
		if (JudgeOver()) {
			break;
		}//先走再判断
		if (JudgeFood()) {
			MakeFood();
		}//如果食物被吃了再制造一个食物
		for (int j = 1; j <= Lenth; j++) {
			rectangle(frame, Rect(a[j].x * width, a[j].y * height, width, height), Scalar(255, 204, 51), -1);
		}
		rectangle(frame, Rect(Food.x * width, Food.y * height, width, height), Scalar(255, 204, 51), -1);
		imshow("贪吃蛇 by RogicYu", frame);
	}//显示蛇和食物,可以写进函数里,我懒了
//出循环代表游戏结束
	destroyWindow("贪吃蛇 by RogicYu");
	GameOver(frame);
	return 0;
}

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值