Advertisement
KIKIJIKI

Map

Dec 5th, 2012
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.69 KB | None | 0 0
  1.     struct Subtile
  2.     {
  3.         int sequenceId;
  4.         AnimationSequenceState sequenceState;
  5.     };
  6.  
  7.     struct Tile
  8.     {
  9.         bool visible;
  10.         bool walkable;
  11.  
  12.         int x, y;
  13.         int height;
  14.         XMFLOAT2 position;
  15.         float depth;
  16.         XMVECTOR color;
  17.  
  18.         std::vector<Subtile> subtiles;
  19.     };
  20.  
  21.    struct AnimationSequenceState
  22.     {
  23.         int loopCount;
  24.         int currentIndex;
  25.         int currentFrame;
  26.         double elapsed;
  27.  
  28.         AnimationSequenceState():
  29.             loopCount(0),
  30.             currentIndex(0),
  31.             currentFrame(0),
  32.             elapsed(0)
  33.         {}
  34.     };
  35.  
  36.     struct AnimationSequence
  37.     {
  38.         std::vector<int> frame;
  39.         std::vector<int> frameLength;
  40.  
  41.         int length;
  42.         int loop;
  43.  
  44.         AnimationSequence():
  45.             length(0),
  46.             loop(-1)
  47.         {}
  48.  
  49.         void nextFrame(AnimationSequenceState& state)
  50.         {
  51.             if(loop < 0)
  52.             {
  53.                 state.currentIndex = ++state.currentIndex % length;
  54.             }
  55.             else
  56.             {
  57.                 if(state.currentIndex == (length - 1))
  58.                 {
  59.                     if(state.loopCount < loop)
  60.                     {
  61.                         state.currentIndex = 0;
  62.                         state.loopCount++;
  63.                     }
  64.                 }
  65.                 else
  66.                 {
  67.                     state.currentIndex++;
  68.                 }
  69.             }
  70.  
  71.             state.currentFrame = frame[state.currentIndex];
  72.         }
  73.  
  74.         void update(AnimationSequenceState& state)
  75.         {
  76.             state.currentFrame = frame[state.currentIndex];
  77.             update(state, TimeData());
  78.         }
  79.  
  80.         void update(AnimationSequenceState& state, const TimeData& time)
  81.         {
  82.             if(length > 1)
  83.             {
  84.                 state.elapsed += time.milliseconds;
  85.  
  86.                 while(state.elapsed >= frameLength[state.currentIndex])
  87.                 {
  88.                     state.elapsed -= frameLength[state.currentIndex];
  89.                     nextFrame(state);
  90.                 }
  91.             }
  92.         }
  93.  
  94.         void appendFrame(int frameId, int milli)
  95.         {
  96.             frame.push_back(frameId);
  97.             frameLength.push_back(milli);
  98.         }
  99.     };
  100.  
  101.     class Map : public Resource
  102.     {
  103.     private:
  104.         friend class MapFactory;
  105.  
  106.         spSpriteBatch _sprite;
  107.         spSpriteSheet _tileset;
  108.  
  109.         int _rows;
  110.         int _columns;
  111.         XMFLOAT2 _size;
  112.  
  113.         std::vector<AnimationSequence> _sequences;
  114.         std::vector<Tile> _tiles;
  115.        
  116.         Map(const ParameterList& P);
  117.  
  118.         //Disabled
  119.         Map(const Map&);
  120.         Map& operator=(const Map&);
  121.  
  122.         static spMap Create(const ParameterList& P);
  123.  
  124.         HRESULT parseMap(LuaState& l);
  125.         HRESULT parseSequences(LuaState& l);
  126.         HRESULT parseTileGrid(LuaState& l);
  127.         HRESULT parseTile(LuaState& l, int ix, int iy, XMFLOAT2 pos);
  128.  
  129.         void drawTile(Tile& tile, ID3D11ShaderResourceView* tex);
  130.     protected:
  131.         HRESULT _load() override;
  132.         HRESULT _unload() override;
  133.     public:
  134.         void Update(const TimeData& time);
  135.         void Draw(const TimeData& time);
  136.     };
  137.  
  138.     class MapFactory : public ResourceFactory
  139.     {
  140.     private:
  141.         MapFactory():ResourceFactory(constants::MapFormat){}
  142.     public:
  143.         static upResourceFactory Instance()
  144.         {
  145.             return upResourceFactory(new MapFactory());
  146.         }
  147.  
  148.         spResource Create(const ParameterList& P)
  149.         {
  150.             return Map::Create(P);
  151.         }
  152.     };
  153.  
  154. Map::Map(const ParameterList& P):
  155.     Resource(P)
  156. {
  157.     _sprite = Game::getDX11()->getSpriteBatch();
  158. }
  159.  
  160. spMap Map::Create(const ParameterList& P)
  161. {
  162.     return spMap(new Map(P));
  163. }
  164.  
  165. HRESULT Map::_load()
  166. {
  167.     LuaState l;
  168.    
  169.     //Find the tileset
  170.     l.doFile(getResourcePath());
  171.     l.getGlobal(parsing::MapTable);
  172.  
  173.     auto tileset_path = l.getWStringField(-1, parsing::MapTileset);
  174.  
  175.     //Import the tileset
  176.     _tileset = Game::getResourceManager()->getResource<SpriteSheet>(tileset_path);
  177.  
  178.     parseMap(l);
  179.  
  180.     return S_OK;
  181. }
  182.  
  183. HRESULT Map::_unload()
  184. {
  185.     _tiles.resize(0);
  186.     _sequences.resize(0);
  187.     _tileset = nullptr;
  188.  
  189.     return S_OK;
  190. }
  191.  
  192. HRESULT Map::parseMap(LuaState& l)
  193. {
  194.     parseSequences(l);
  195.     parseTileGrid(l);
  196.  
  197.     return S_OK;
  198. }
  199.  
  200. HRESULT Map::parseSequences(LuaState& l)
  201. {
  202.     l.pushString(parsing::MapSequences);
  203.     l.getTable();
  204.     {
  205.         for(l.pushNil(); l.next(); l.pop())
  206.         {
  207.             AnimationSequence s;
  208.  
  209.             s.loop = l.getIntField(-1, parsing::MapSequenceLoop);
  210.  
  211.             l.pushString(parsing::MapSequenceFrames);
  212.             l.getTable();
  213.             {
  214.                 for(l.pushNil(); l.next(); l.pop())
  215.                 {
  216.                     auto type = l.toString();
  217.                     l.pop(); l.next();
  218.                     auto milli = l.toInt();
  219.  
  220.                     int id = _tileset->getIndex(type);
  221.                     s.appendFrame(id, milli);
  222.                    
  223.                     s.length++;
  224.                 }
  225.             }
  226.             l.pop();
  227.  
  228.             _sequences.push_back(s);
  229.         }
  230.     }
  231.     l.pop();
  232.  
  233.     return S_OK;
  234. }
  235.  
  236. HRESULT Map::parseTileGrid(LuaState& l)
  237. {
  238.     srand(static_cast<unsigned int>(time(nullptr)));
  239.  
  240.     int ix = 0;
  241.     int iy = 0;
  242.     int maxcol = 0;
  243.  
  244.     XMFLOAT2 start(0,0);
  245.     XMFLOAT2 za;
  246.  
  247.     XMFLOAT2 offset = _tileset->getTileOffset();
  248.  
  249.     l.pushString(parsing::MapTilesGrid);
  250.     l.getTable();
  251.  
  252.     _rows = 0;
  253.     _columns = 0;
  254.  
  255.     //Loop through the rows
  256.     for(l.pushNil(); l.next(); l.pop())
  257.     {
  258.         _rows++;
  259.  
  260.         za.x = start.x;
  261.         za.y = start.y;
  262.  
  263.         //Loop through the columns
  264.         for(l.pushNil(); l.next(); l.pop())
  265.         {
  266.             maxcol++;
  267.  
  268.             parseTile(l, ix, iy, za);
  269.  
  270.             ix++;
  271.  
  272.             za.x += offset.x;
  273.             za.y += offset.y;
  274.         }
  275.  
  276.         iy++;
  277.         ix = 0;
  278.  
  279.         start.x -= offset.x;
  280.         start.y += offset.y;
  281.  
  282.         _columns = max(_columns, maxcol);
  283.         maxcol = 0;
  284.     }
  285.  
  286.     //Reverse and normalize depth
  287.     float max_depth = static_cast<float>(_columns + _rows - 2);
  288.     for(auto& t : _tiles)
  289.     {
  290.         t.depth += max_depth;
  291.         t.depth /= max_depth;
  292.     }
  293.  
  294.     _size.x = (_columns + _rows) * offset.x;
  295.     _size.y = (_columns + _rows) * offset.y;
  296.  
  297.     std::sort(_tiles.begin(), _tiles.end(), [](const Tile& a, const Tile& b){return a.depth > b.depth;});
  298.  
  299.     return S_OK;
  300. }
  301.  
  302. HRESULT Map::parseTile(LuaState& l, int ix, int iy, XMFLOAT2 pos)
  303. {
  304.     Tile tile;
  305.  
  306.     tile.visible = l.getBoolField(-1, parsing::MapTileVisible, true);
  307.     tile.walkable = l.getBoolField(-1, parsing::MapTileWalkable, true);
  308.     tile.height = l.getIntField(-1, parsing::MapTileHeight, 0);
  309.  
  310.     bool sync = l.getBoolField(-1, parsing::MapTileSync, true);
  311.  
  312.     tile.x = ix;
  313.     tile.y = iy;
  314.  
  315.     tile.position.x = pos.x;
  316.     tile.position.y = pos.y;
  317.     tile.depth = -1.0f * static_cast<float>(ix + iy);
  318.     tile.color = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
  319.  
  320.     l.pushString(parsing::MapTileSubtiles);
  321.     l.getTable();
  322.     {
  323.         for(l.pushNil(); l.next(); l.pop())
  324.         {
  325.             Subtile subtile;
  326.             subtile.sequenceId = l.toInt();
  327.             _sequences[subtile.sequenceId].update(subtile.sequenceState);
  328.             if(!sync)
  329.             {
  330.                 subtile.sequenceState.elapsed = rand() % 1000; //一秒、適当に
  331.             }
  332.             tile.subtiles.push_back(subtile);
  333.         }
  334.     }
  335.     l.pop();
  336.    
  337.     _tiles.push_back(tile);
  338.  
  339.     return S_OK;
  340. }
  341.  
  342. void Map::Update(const TimeData& time)
  343. {
  344.     for(auto& tile : _tiles)
  345.     {
  346.         for(auto& subtile : tile.subtiles)
  347.         {
  348.             auto sequence = _sequences[subtile.sequenceId];
  349.             sequence.update(subtile.sequenceState, time);
  350.         }
  351.     }
  352. }
  353.  
  354. void Map::Draw(const TimeData& time)
  355. {
  356.     auto tex = _tileset->getTexture()->getShaderResourceView().Get();
  357.  
  358.     for(auto& tile : _tiles)
  359.     {
  360.         drawTile(tile, tex);
  361.     }
  362. }
  363.  
  364. void Map::drawTile(Tile& tile, ID3D11ShaderResourceView* tex)
  365. {
  366.     float height = .0f;
  367.  
  368.     for(auto& subtile : tile.subtiles)
  369.     {
  370.         auto frame = _tileset->getFrame(subtile.sequenceState.currentFrame);
  371.         XMFLOAT2 pos(tile.position.x, tile.position.y - height);
  372.  
  373.         _sprite->Draw(
  374.             tex, //texture
  375.             pos, //position
  376.             &frame.source, //source rect
  377.             tile.color, //color
  378.             .0f, //rotation
  379.             frame.base,//origin
  380.             1.0f,//scale
  381.             SpriteEffects::SpriteEffects_None,//effects
  382.             tile.depth //depth
  383.             );
  384.  
  385.         height += frame.base.y - frame.center.y;
  386.     }
  387. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement