Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct Subtile
- {
- int sequenceId;
- AnimationSequenceState sequenceState;
- };
- struct Tile
- {
- bool visible;
- bool walkable;
- int x, y;
- int height;
- XMFLOAT2 position;
- float depth;
- XMVECTOR color;
- std::vector<Subtile> subtiles;
- };
- struct AnimationSequenceState
- {
- int loopCount;
- int currentIndex;
- int currentFrame;
- double elapsed;
- AnimationSequenceState():
- loopCount(0),
- currentIndex(0),
- currentFrame(0),
- elapsed(0)
- {}
- };
- struct AnimationSequence
- {
- std::vector<int> frame;
- std::vector<int> frameLength;
- int length;
- int loop;
- AnimationSequence():
- length(0),
- loop(-1)
- {}
- void nextFrame(AnimationSequenceState& state)
- {
- if(loop < 0)
- {
- state.currentIndex = ++state.currentIndex % length;
- }
- else
- {
- if(state.currentIndex == (length - 1))
- {
- if(state.loopCount < loop)
- {
- state.currentIndex = 0;
- state.loopCount++;
- }
- }
- else
- {
- state.currentIndex++;
- }
- }
- state.currentFrame = frame[state.currentIndex];
- }
- void update(AnimationSequenceState& state)
- {
- state.currentFrame = frame[state.currentIndex];
- update(state, TimeData());
- }
- void update(AnimationSequenceState& state, const TimeData& time)
- {
- if(length > 1)
- {
- state.elapsed += time.milliseconds;
- while(state.elapsed >= frameLength[state.currentIndex])
- {
- state.elapsed -= frameLength[state.currentIndex];
- nextFrame(state);
- }
- }
- }
- void appendFrame(int frameId, int milli)
- {
- frame.push_back(frameId);
- frameLength.push_back(milli);
- }
- };
- class Map : public Resource
- {
- private:
- friend class MapFactory;
- spSpriteBatch _sprite;
- spSpriteSheet _tileset;
- int _rows;
- int _columns;
- XMFLOAT2 _size;
- std::vector<AnimationSequence> _sequences;
- std::vector<Tile> _tiles;
- Map(const ParameterList& P);
- //Disabled
- Map(const Map&);
- Map& operator=(const Map&);
- static spMap Create(const ParameterList& P);
- HRESULT parseMap(LuaState& l);
- HRESULT parseSequences(LuaState& l);
- HRESULT parseTileGrid(LuaState& l);
- HRESULT parseTile(LuaState& l, int ix, int iy, XMFLOAT2 pos);
- void drawTile(Tile& tile, ID3D11ShaderResourceView* tex);
- protected:
- HRESULT _load() override;
- HRESULT _unload() override;
- public:
- void Update(const TimeData& time);
- void Draw(const TimeData& time);
- };
- class MapFactory : public ResourceFactory
- {
- private:
- MapFactory():ResourceFactory(constants::MapFormat){}
- public:
- static upResourceFactory Instance()
- {
- return upResourceFactory(new MapFactory());
- }
- spResource Create(const ParameterList& P)
- {
- return Map::Create(P);
- }
- };
- Map::Map(const ParameterList& P):
- Resource(P)
- {
- _sprite = Game::getDX11()->getSpriteBatch();
- }
- spMap Map::Create(const ParameterList& P)
- {
- return spMap(new Map(P));
- }
- HRESULT Map::_load()
- {
- LuaState l;
- //Find the tileset
- l.doFile(getResourcePath());
- l.getGlobal(parsing::MapTable);
- auto tileset_path = l.getWStringField(-1, parsing::MapTileset);
- //Import the tileset
- _tileset = Game::getResourceManager()->getResource<SpriteSheet>(tileset_path);
- parseMap(l);
- return S_OK;
- }
- HRESULT Map::_unload()
- {
- _tiles.resize(0);
- _sequences.resize(0);
- _tileset = nullptr;
- return S_OK;
- }
- HRESULT Map::parseMap(LuaState& l)
- {
- parseSequences(l);
- parseTileGrid(l);
- return S_OK;
- }
- HRESULT Map::parseSequences(LuaState& l)
- {
- l.pushString(parsing::MapSequences);
- l.getTable();
- {
- for(l.pushNil(); l.next(); l.pop())
- {
- AnimationSequence s;
- s.loop = l.getIntField(-1, parsing::MapSequenceLoop);
- l.pushString(parsing::MapSequenceFrames);
- l.getTable();
- {
- for(l.pushNil(); l.next(); l.pop())
- {
- auto type = l.toString();
- l.pop(); l.next();
- auto milli = l.toInt();
- int id = _tileset->getIndex(type);
- s.appendFrame(id, milli);
- s.length++;
- }
- }
- l.pop();
- _sequences.push_back(s);
- }
- }
- l.pop();
- return S_OK;
- }
- HRESULT Map::parseTileGrid(LuaState& l)
- {
- srand(static_cast<unsigned int>(time(nullptr)));
- int ix = 0;
- int iy = 0;
- int maxcol = 0;
- XMFLOAT2 start(0,0);
- XMFLOAT2 za;
- XMFLOAT2 offset = _tileset->getTileOffset();
- l.pushString(parsing::MapTilesGrid);
- l.getTable();
- _rows = 0;
- _columns = 0;
- //Loop through the rows
- for(l.pushNil(); l.next(); l.pop())
- {
- _rows++;
- za.x = start.x;
- za.y = start.y;
- //Loop through the columns
- for(l.pushNil(); l.next(); l.pop())
- {
- maxcol++;
- parseTile(l, ix, iy, za);
- ix++;
- za.x += offset.x;
- za.y += offset.y;
- }
- iy++;
- ix = 0;
- start.x -= offset.x;
- start.y += offset.y;
- _columns = max(_columns, maxcol);
- maxcol = 0;
- }
- //Reverse and normalize depth
- float max_depth = static_cast<float>(_columns + _rows - 2);
- for(auto& t : _tiles)
- {
- t.depth += max_depth;
- t.depth /= max_depth;
- }
- _size.x = (_columns + _rows) * offset.x;
- _size.y = (_columns + _rows) * offset.y;
- std::sort(_tiles.begin(), _tiles.end(), [](const Tile& a, const Tile& b){return a.depth > b.depth;});
- return S_OK;
- }
- HRESULT Map::parseTile(LuaState& l, int ix, int iy, XMFLOAT2 pos)
- {
- Tile tile;
- tile.visible = l.getBoolField(-1, parsing::MapTileVisible, true);
- tile.walkable = l.getBoolField(-1, parsing::MapTileWalkable, true);
- tile.height = l.getIntField(-1, parsing::MapTileHeight, 0);
- bool sync = l.getBoolField(-1, parsing::MapTileSync, true);
- tile.x = ix;
- tile.y = iy;
- tile.position.x = pos.x;
- tile.position.y = pos.y;
- tile.depth = -1.0f * static_cast<float>(ix + iy);
- tile.color = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
- l.pushString(parsing::MapTileSubtiles);
- l.getTable();
- {
- for(l.pushNil(); l.next(); l.pop())
- {
- Subtile subtile;
- subtile.sequenceId = l.toInt();
- _sequences[subtile.sequenceId].update(subtile.sequenceState);
- if(!sync)
- {
- subtile.sequenceState.elapsed = rand() % 1000; //一秒、適当に
- }
- tile.subtiles.push_back(subtile);
- }
- }
- l.pop();
- _tiles.push_back(tile);
- return S_OK;
- }
- void Map::Update(const TimeData& time)
- {
- for(auto& tile : _tiles)
- {
- for(auto& subtile : tile.subtiles)
- {
- auto sequence = _sequences[subtile.sequenceId];
- sequence.update(subtile.sequenceState, time);
- }
- }
- }
- void Map::Draw(const TimeData& time)
- {
- auto tex = _tileset->getTexture()->getShaderResourceView().Get();
- for(auto& tile : _tiles)
- {
- drawTile(tile, tex);
- }
- }
- void Map::drawTile(Tile& tile, ID3D11ShaderResourceView* tex)
- {
- float height = .0f;
- for(auto& subtile : tile.subtiles)
- {
- auto frame = _tileset->getFrame(subtile.sequenceState.currentFrame);
- XMFLOAT2 pos(tile.position.x, tile.position.y - height);
- _sprite->Draw(
- tex, //texture
- pos, //position
- &frame.source, //source rect
- tile.color, //color
- .0f, //rotation
- frame.base,//origin
- 1.0f,//scale
- SpriteEffects::SpriteEffects_None,//effects
- tile.depth //depth
- );
- height += frame.base.y - frame.center.y;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement