zoukankan      html  css  js  c++  java
  • 自制贪吃蛇——主场景

      昨天突发奇想,想自己实现贪吃蛇。想了许久,定了一个方案,简要说明一下:

        1、主场景用数组表示,通过x和y坐标计算数组下标,每个元素是一个结构体,存着当前位置是什么类型,展示什么图形

        2、蛇用链表表示,每个结点存储着当前坐标,展示的图形等信息,头结点还存着前进方向等信息

        3、定期刷新界面

        4、直接在终端下运行,界面不会太好看

      先写个主场景吧。

      首先,是一个枚举和一个结构体:

     1 enum MapStatus
     2 {
     3     EN_MAP_EMPTY = 0,  //空地
     4     EN_MAP_WALL,       //边界
     5     EN_MAP_NEW_NODE,   //新节点
     6     EN_MAP_SNAKE,      //
     7 
     8 };
     9 
    10 struct MapBase
    11 {
    12     int int_type;
    13     char char_icon;
    14 };

      思考了一下,场景需要的功能有:

        1、获取指定坐标的信息

        2、设置指定坐标的信息

        3、获取场景的大小

        4、重置一个坐标的信息

        5、获取中心坐标

        6、输出

      于是,有了以下类:

     1  ///
     2  /// @file    map.h
     3  /// @author  marrs(chenchengxi993@gmail.com)
     4  /// @date    2017-07-15 09:45:50
     5  ///
     6 
     7 #ifndef __MAP_H__
     8 #define __MAP_H__
     9 
    10 #include "define.h" 
    11 
    12 namespace marrs{
    13 
    14 class Map
    15 {
    16     public:
    17         Map();
    18         Map(int int_x, int int_y);
    19         ~Map();
    20 
    21     public:
    22         int init();
    23         int get_map_val(int int_x, int int_y, MapBase & map_val);
    24         int set_map_val(int int_x, int int_y, MapBase int_val);
    25 
    26         int get_x_size();
    27         int get_y_size();
    28 
    29         int reset_point(int int_x, int int_y);
    30 
    31         Coordinate get_map_center_pos();
    32 
    33         friend ostream & operator << (ostream & output, MapBase & map); 
    34 
    35         int output_map(int int_x, int int_y);
    36 
    37     private:
    38         int get_map_pos(int int_x, int int_y);
    39 
    40     private:
    41         int _int_x_size;
    42         int _int_y_size;
    43         MapBase * _p_map;
    44         bool _bool_is_init_fail;
    45 };
    46  
    47 }
    48 
    49 #endif

      重载了输出流运算符只是为了方便输出。场景用一个一维数组存储,目的是为了可以定制场景大小。后期可能会做成可以在游戏中随时设置场景大小。

      各自的实现:

      1  ///
      2  /// @file    map.cc
      3  /// @author  marrs(chenchengxi993@gmail.com)
      4  /// @date    2017-07-15 10:08:01
      5  ///
      6  
      7 #include "map.h"
      8 
      9 namespace marrs{
     10 
     11 Map::Map()
     12 : _int_x_size(20)
     13 , _int_y_size(20)
     14 {
     15     _bool_is_init_fail = init();
     16 }
     17 
     18 Map::Map(int int_x, int int_y)
     19 : _int_x_size(int_x)
     20 , _int_y_size(int_y)
     21 {
     22     _bool_is_init_fail = init();
     23 }
     24 
     25 Map::~Map()
     26 {
     27     delete [] _p_map;
     28 }
     29 
     30 int Map::init()
     31 {
     32     int map_size = _int_x_size * _int_y_size;
     33     _p_map = new MapBase[map_size];
     34     if (_p_map == NULL)
     35     {
     36         return true;
     37     }
     38     int int_pos;
     39 
     40     for (int int_idx = 0; int_idx < _int_x_size; ++int_idx)
     41     {
     42         for (int int_idy = 0; int_idy < _int_y_size; ++int_idy)
     43         {
     44             int_pos = get_map_pos(int_idx, int_idy);
     45             if ((int_idx == 0 && (int_idy == 0 || int_idy == _int_y_size - 1))
     46                 || (int_idx == _int_x_size - 1 && (int_idy == 0 || int_idy == _int_y_size - 1)))
     47             {
     48                 _p_map[int_pos].int_type = EN_MAP_WALL;
     49                 _p_map[int_pos].char_icon = '+';
     50             }
     51             else if (int_idx == 0 || int_idx == _int_x_size - 1)
     52             {
     53                 _p_map[int_pos].int_type = EN_MAP_WALL;
     54                 _p_map[int_pos].char_icon = '=';
     55             }
     56             else if (int_idy == 0 || int_idy == _int_y_size - 1)
     57             {
     58                 _p_map[int_pos].int_type = EN_MAP_WALL;
     59                 _p_map[int_pos].char_icon = '|';
     60             }
     61             else
     62             {
     63                 reset_point(int_idx, int_idy);
     64             }
     65         }
     66     }
     67     return false;
     68 
     69 }
     70 
     71 int Map::get_map_pos(int int_x, int int_y)
     72 {
     73     if (int_x >= _int_x_size || int_y >= _int_y_size)
     74     {
     75         return -1;
     76     }
     77     
     78     int int_pos = int_y * _int_x_size + int_x;
     79     return int_pos;
     80 }
     81 
     82 int Map::get_map_val(int int_x, int int_y, MapBase & map_val)
     83 {
     84     int int_pos = get_map_pos(int_x, int_y);
     85     if (int_pos == -1)
     86     {
     87         return -1;
     88     }
     89     map_val = _p_map[int_pos];
     90     return map_val.int_type;
     91 
     92 }
     93 
     94 int Map::set_map_val(int int_x, int int_y, MapBase map_val)
     95 {
     96     int int_pos = get_map_pos(int_x, int_y);
     97     if (int_pos == -1)
     98     {
     99         return -1;
    100     }
    101     _p_map[int_pos] = map_val;
    102     return map_val.int_type;
    103 
    104 }
    105 
    106 int Map::get_x_size()
    107 {
    108     return _int_x_size;
    109 
    110 }
    111 
    112 int Map::get_y_size()
    113 {
    114     return _int_y_size;
    115 
    116 }
    117 
    118 int Map::reset_point(int int_x, int int_y)
    119 {
    120     int int_pos = get_map_pos(int_x, int_y);
    121     _p_map[int_pos].int_type = EN_MAP_EMPTY;
    122     _p_map[int_pos].char_icon = ' ';
    123     return 0;
    124 
    125 }
    126 
    127 Coordinate Map::get_map_center_pos()
    128 {
    129     Coordinate coordinate;
    130     coordinate.int_x = (_int_x_size + 1) / 2;
    131     coordinate.int_y = (_int_y_size + 1) / 2;
    132     return coordinate;    
    133 
    134 }
    135 
    136 ostream & operator << (ostream & output, MapBase & map)
    137 {
    138     output << map.char_icon;
    139     return output;
    140 }
    141 
    142 int Map::output_map(int int_x, int int_y)
    143 {
    144     int int_pos = get_map_pos(int_x, int_y);
    145     cout << _p_map[int_pos] << _p_map[int_pos];
    146 
    147     return 0;
    148 }
    149 
    150 }
    View Code

      这时候可以来测试一下场景是不是正常的。写了个game类,之后所有的各种游戏功能都加在里面。

     1  ///
     2  /// @file    game.h
     3  /// @author  marrs(chenchengxi993@gmail.com)
     4  /// @date    2017-07-15 11:42:03
     5  ///
     6 
     7 #ifndef __GAME_H__
     8 #define __GAME_H__
     9 
    10 #include "map.h"
    11 
    12 namespace marrs{
    13 
    14 class Game
    15 {
    16     public:
    17         int init();    
    18         int output_map();    
    19         int refresh_map();
    20 
    21     private:
    22         Map _map;
    23 };
    24  
    25 }
    26 
    27 #endif
     1  ///
     2  /// @file    game.cc
     3  /// @author  marrs(chenchengxi993@gmail.com)
     4  /// @date    2017-07-15 18:05:24
     5  ///
     6  
     7 #include <iostream>
     8 #include "game.h"
     9 
    10 namespace marrs{
    11 
    12 int Game::init()
    13 {
    14 
    15     output_map();
    16     return 0;
    17 
    18 }
    19 
    20 int Game::output_map()
    21 {
    22     int int_map_x_size = _map.get_x_size();
    23     int int_map_y_size = _map.get_y_size();
    24 
    25     for (int int_idx = 0; int_idx < int_map_x_size; ++int_idx)
    26     {
    27         for (int int_idy = 0; int_idy < int_map_y_size; ++int_idy)
    28         {
    29             _map.output_map(int_idx, int_idy);
    30         }
    31         cout << endl;
    32     }
    33     return 0;
    34     
    35 }
    36 
    37 int Game::refresh_map()
    38 {
    39     int int_map_y_size = _map.get_y_size();
    40     printf("33[%dA", int_map_y_size);
    41     output_map();
    42     return 0;
    43 
    44 }
    45 
    46 }
    View Code
     1  ///
     2  /// @file    main.cc
     3  /// @author  marrs(chenchengxi993@gmail.com)
     4  /// @date    2017-07-15 18:20:18
     5  ///
     6  
     7 #include "game.h" 
     8 using namespace marrs;
     9 
    10 int main()
    11 {
    12     Game game;
    13     game.init();
    14     for(int int_idx = 0; int_idx < 5; ++int_idx)
    15     {
    16         game.refresh_map();
    17         sleep(1);
    18     }
    19     
    20 
    21 
    22 
    23     return 0;
    24 }

      编译之后,预期的结果,是打印个框出来,并且5秒之后退出。

      结果如下:

    [ccx@ubuntu ~/Retro_Snaker/bin]$>./game.exe 
    ++====================================++
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ++====================================++
    [ccx@ubuntu ~/Retro_Snaker/bin]$>

      符合预期。

      未完待续....

      github:https://github.com/ccx19930930/Retro_Snaker

  • 相关阅读:
    Echarts 源码解读 一:zrender源码分析1var zr = zrender.init(document.getElementById(‘main‘));
    Vue3 script setup 语法糖详解
    TCP的状态 (SYN, FIN, ACK, PSH, RST, URG)
    vuerouter路由懒加载
    ECharts 源码解读 二
    前端必备10种设计模式
    VUE路由懒加载的3种方式
    RewriterConfig 配置
    JQ弹出层插件(tipsWindow 2.8)
    一个jQuery弹出层(tipsWindown)
  • 原文地址:https://www.cnblogs.com/chinxi/p/7184063.html
Copyright © 2011-2022 走看看