本人蒟蒻一个,因为学习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;
}