1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| #ifndef UI_H #define UI_H
#include <opencv2/core.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp>
#define BOX_WIDTH 10
class UI { public: static void LoadMap() { Get().loadMap(); } static inline void SetFood() { Get().setFood(); } static inline void SetFood(const cv::Point &pt) { Get().setFood(pt); } static inline void SetBody(const cv::Point &pt, bool head) { Get().setBody(pt, head); } static inline void DelBody(const cv::Point &pt) { Get().delBody(pt); } static inline bool OuttaRange(const cv::Point &pt) { return Get().outtaRange(pt); } static inline bool Occupied(const cv::Point &pt) { return Get().occupied(pt); } static inline void UpdateFrame(bool end) { Get().updateFrame(end); } static inline cv::Point GetFoodPos() { return Get().getFoodPos(); } static inline cv::Point RandomPos() { return Get().randomPos(); }
static UI &Get() { static UI map; return map; } UI(const UI &) = delete; UI &operator=(const UI &) = delete;
private: UI() = default; void loadMap() { this->gameWindow_ = cv::Mat(cv::Size(1000, 800), CV_8UC3, cv::Scalar(240, 250, 255)); this->mapRange_ = cv::Mat(cv::Size(800, 600), CV_8UC3, cv::Scalar(255, 255, 240)); this->mapBox_ = cv::Mat(cv::Size(BOX_WIDTH, BOX_WIDTH), CV_8UC3, cv::Scalar(255, 255, 240)); this->foodBox_ = cv::Mat(cv::Size(BOX_WIDTH, BOX_WIDTH), CV_8UC3, cv::Scalar(93, 66, 255)); this->snakeHeadBox_ = cv::Mat(cv::Size(BOX_WIDTH, BOX_WIDTH), CV_8UC3, cv::Scalar(128, 0, 0)); this->snakeBodyBox_ = cv::Mat(cv::Size(BOX_WIDTH, BOX_WIDTH), CV_8UC3, cv::Scalar(211, 85, 186)); this->maxPoint_ = cv::Point(mapRange_.cols + 100 - BOX_WIDTH, mapRange_.rows + 100 - BOX_WIDTH); this->minPoint_ = cv::Point(100, 100); this->mapRange_.copyTo(this->gameWindow_(cv::Rect(100, 100, 800, 600)));
cv::putText(this->gameWindow_, "Simple Snake", cv::Point(410, 65), 3, 0.8, cv::Scalar(255, 66, 93), 2); cv::putText(this->gameWindow_, "Press Esc to suicide.", cv::Point(100, 75), 1, 1, cv::Scalar(205, 0, 0), 1); cv::line(this->gameWindow_, cv::Point(100, 100), cv::Point(900, 100), cv::Scalar(230, 240, 230), 1); cv::line(this->gameWindow_, cv::Point(900, 100), cv::Point(900, 700), cv::Scalar(230, 240, 230), 1); cv::line(this->gameWindow_, cv::Point(900, 700), cv::Point(100, 700), cv::Scalar(230, 240, 230), 1); cv::line(this->gameWindow_, cv::Point(100, 700), cv::Point(100, 100), cv::Scalar(230, 240, 230), 1);
srand((unsigned int)time(nullptr)); }
inline void setFood() { this->foodPos_ = randomPos(); copyBox(this->foodBox_, this->gameWindow_, foodPos_); this->occupation_[this->foodPos_.x / 10][this->foodPos_.y / 10] = true; }
inline void setFood(const cv::Point &pt) { this->foodPos_ = pt; copyBox(this->foodBox_, this->gameWindow_, foodPos_); this->occupation_[this->foodPos_.x / 10][this->foodPos_.y / 10] = true; }
inline void setBody(const cv::Point &pt, bool head) { head ? copyBox(this->snakeHeadBox_, this->gameWindow_, pt) : copyBox(this->snakeBodyBox_, this->gameWindow_, pt); this->occupation_[pt.x / 10][pt.y / 10] = true; }
inline void delBody(const cv::Point &pt) { copyBox(this->mapBox_, this->gameWindow_, pt); this->occupation_[pt.x / 10][pt.y / 10] = false; }
inline void updateFrame(bool end) { if (!end) { cv::imshow("Snake", this->gameWindow_); } else { cv::putText(this->gameWindow_, ">.< GameOver!", cv::Point(375, 375), 4, 1, cv::Scalar(93, 66, 255), 2); cv::imshow("Snake", this->gameWindow_); } }
inline cv::Point randomPos() { cv::Point pos; pos.x = (rand() % ((this->maxPoint_.x + BOX_WIDTH - this->minPoint_.x) / 10) + this->minPoint_.x / 10) * 10; pos.y = (rand() % ((this->maxPoint_.y + BOX_WIDTH - this->minPoint_.y) / 10) + this->minPoint_.y / 10) * 10; return pos; }
inline cv::Point getFoodPos() { return this->foodPos_; } inline bool occupied(const cv::Point &pt) { return this->occupation_[pt.x / 10][pt.y / 10]; }
inline bool outtaRange(const cv::Point &pt) { return pt.x >= this->minPoint_.x && pt.x <= this->maxPoint_.x && pt.y >= this->minPoint_.y && pt.y <= this->maxPoint_.y; }
static inline void copyBox(const cv::Mat &src, cv::Mat &dst, const cv::Point &pt) { src.copyTo(dst(cv::Rect(pt.x, pt.y, BOX_WIDTH, BOX_WIDTH))); }
private: cv::Mat gameWindow_; cv::Mat mapRange_; cv::Mat mapBox_; cv::Mat foodBox_; cv::Mat snakeHeadBox_; cv::Mat snakeBodyBox_;
private: cv::Point minPoint_; cv::Point maxPoint_; cv::Point foodPos_;
private: bool occupation_[100][80] = {false}; };
#endif
|