C++实现简单贪吃蛇游戏分享!

我大概在一个多月前把自己上学期写的c代码的贪吃蛇游戏push到csdn上,并且说c风格的贪吃蛇写起来有些麻烦(贪吃蛇游戏的c语言实现),准备用面向对象的c++再写一遍。现在我们专业恰好刚教完了c++,学校也布置了一道简单的贪吃蛇的编程题目,实现下来,的确觉得c++的思路清晰很多,所以再次把c++的代码push上来,供大家对比参考:)

直接上代码,c++把整个游戏拆分成几个文件,分开上,有一定的c++基础的同学应该可以很容易看懂。

1、全局头文件(global.hpp)

  #ifndef _GLOBAL_H_  #define _GLOBAL_H_    #ifndef SYMBOLS  #define HEAD '@'  #define BODY 'X'  #define EMPTY '+'  #define FOOD '$'  #endif // !SYMBOLS    enum direction { up = 0, down = 1, left = 2, right = 4, freeze = 5 };    struct point {   int x;   int y;   point(int x = 0, int y = 0) : x(x), y(y) {}   point(const point& another) : x(another.x), y(another.y) {}   point& operator=(const point& other) {   x = other.x;   y = other.y;   return *this;   }   friend bool operator==(const point& point1, const point& point2) {   return point1.x == point2.x && point1.y == point2.y;   }   point& move(direction d) {   switch (d) {   case up:   x--;   break;   case down:   x++;   break;   case left:   y--;   break;   case right:   y++;   break;   case freeze:   default:   break;   }   return *this;   }  };    #endif // !_GLOBAL_H_    

2、snake类的声明和实现(snake.hpp)

(为了简化结构,把声明和实现共同放在了hpp文件里,减少了一点封装性,实际上应该分开头文件和实现文件好一点)

此处使用了容器list作为蛇身(body)的表达形式,这样可以非常方便地进行表达,读者有兴趣可以用数组实现一下,一不小心就会出现有趣的内存错误。。。

  #ifndef _SNAKE_H_  #define _SNAKE_H_  #include <iostream>  #include <list>  #include "global.hpp"    class snake {   point head;   std::list<point> body;   public:   snake(point initial_head);   snake();   ~snake() {}   point& getHead();   std::list<point>& getbody();   void grow(point);   void setHead(point);  };    snake::snake() {   head.x = 0;   head.y = 0;  }    snake::snake(point initial_head) {   setHead(initial_head);  }    void snake::setHead(point _head) {   head = _head;  }    void snake::grow(point second_node) {   this -> body.push_front(second_node);  }    point& snake::getHead() {   return head;  }    std::list<point>& snake::getbody() {   return body;  }  #endif    

3、map类的声明和实现(map.hpp)

在这里,map中应该包含一个snake类作为组合关系。
在组合关系里面,想要直接修改snake的各种参数是不可行的,所以在前面snake类的声明里加上了诸如setHead(), getHead(), getbody() 这一类的函数。

  #ifndef _MAP_H_  #define _MAP_H_  #include <iostream>  #include "global.hpp"  #include "snake.hpp"    class map {   private:   char** _map;   snake _snake;   int height, width;   std::list<point> foods;   public:   map();   map(point initial_size, point initial_head,   std::list<point> initial_foods);   ~map();   void move(direction d);   void print();   bool isGameOver();   bool isEat();;   void makemap(void);  };    map::map() {   _map = NULL;   height = width = 0;  }    void map::makemap() { // 这个是用来更新地图的   for (int i = 0; i < height; i++) {   for (int j = 0; j < width; j++)    _map[i][j] = 0;   }   for (std::list<point>::iterator i = foods.begin(); i != foods.end(); ++i) {   _map[i->x][i->y] = FOOD;   }   _map[_snake.getHead().x][_snake.getHead().y] = HEAD;   for (std::list<point>::iterator i = _snake.getbody().begin();   i != _snake.getbody().end(); ++i) {   _map[i->x][i->y] = BODY;   }   for (int i = 0; i < height; i++) {   for (int j = 0; j < width; j++) {    if (_map[i][j] == 0)    _map[i][j] = EMPTY;   }   }  }    map::map(point initial_size, point initial_head, std::list<point> initial_foods)  {   height = initial_size.x;   width = initial_size.y;   _map = new char*[height];   for (int i = 0; i < height; i++)   _map[i] = new char[width]();   _snake.setHead(initial_head);   foods = initial_foods;   makemap();  }    map::~map() {   for (int i = 0; i < height; i++) {   delete []_map[i];   }   delete []_map;  }    void map::print() {   for (int i = 0; i < height; i++) {   for (int j = 0; j < width; j++) {    std::cout << _map[i][j];   }   std::cout << std::endl;    }   std::cout << std::endl;  }    bool map::isGameOver() {   point temp = _snake.getHead();   if (temp.x == height || temp.y == width || temp.x < 0 || temp.y < 0)   return true;   if (_map[temp.x][temp.y] == BODY) return true;   return false;  }    bool map::isEat() {   point temp = _snake.getHead();   if (temp.x == height || temp.y == width || temp.x < 0 || temp.y < 0)   return false;   if (_map[temp.x][temp.y] == FOOD) return true;   else return false;  }    void map::move(direction d) {   point temp_f = _snake.getHead();   if (!(_snake.getbody().empty())) { // 为了避免追尾问题   _map[_snake.getbody().back().x][_snake.getbody().back().y] = EMPTY;   }   _snake.getHead().move(d);   if (_snake.getHead() == _snake.getbody().front()) { // 判断蛇是否往回走   _snake.setHead(temp_f);   _map[_snake.getbody().back().x][_snake.getbody().back().y] = BODY;   return;   }   if (!isGameOver()) {   if (isEat()) {    point eaten = _snake.getHead();    foods.remove(eaten);    _snake.grow(temp_f);   } else {    _snake.getbody().push_front(temp_f);    _snake.getbody().pop_back();   }   makemap();   } else {   if (!(_snake.getbody().empty())) {    _map[_snake.getbody().back().x][_snake.getbody().back().y] = BODY;   }   }  }  #endif  

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/482307.html

Like (0)
Previous 2020年11月9日
Next 2020年11月9日

精彩推荐