diff options
author | Andy <drumsetmonkey@gmail.com> | 2017-01-19 09:14:12 -0500 |
---|---|---|
committer | Andy <drumsetmonkey@gmail.com> | 2017-01-19 09:14:12 -0500 |
commit | 19a32074595a4a2797eaeb978f8bd302f736f6a6 (patch) | |
tree | 3a25ebaf1c84746a16a7595175da6029ef3feb15 | |
parent | fbd59263b52a42f85453ae918f8d2ab5817bd470 (diff) |
Limb animation actually works
-rw-r--r-- | assets/NPC_Sheet.png | bin | 531 -> 763 bytes | |||
-rw-r--r-- | assets/player/player.png | bin | 0 -> 840 bytes | |||
-rw-r--r-- | include/components.hpp | 81 | ||||
-rw-r--r-- | main.cpp | 4 | ||||
-rw-r--r-- | src/components.cpp | 34 | ||||
-rw-r--r-- | src/player.cpp | 5 | ||||
-rw-r--r-- | src/world.cpp | 40 | ||||
-rwxr-xr-x | todo.sh | 1 | ||||
-rw-r--r-- | xml/entities.xml | 32 |
9 files changed, 152 insertions, 45 deletions
diff --git a/assets/NPC_Sheet.png b/assets/NPC_Sheet.png Binary files differindex 5537b5e..f0f6530 100644 --- a/assets/NPC_Sheet.png +++ b/assets/NPC_Sheet.png diff --git a/assets/player/player.png b/assets/player/player.png Binary files differnew file mode 100644 index 0000000..0f7f13a --- /dev/null +++ b/assets/player/player.png diff --git a/include/components.hpp b/include/components.hpp index 8e245a7..9a83d45 100644 --- a/include/components.hpp +++ b/include/components.hpp @@ -232,6 +232,8 @@ struct Sprite { } dim = vec2(ed.x - st.x, ed.y - st.y); + dim.x *= game::HLINE; + dim.y *= game::HLINE; return dim; } @@ -239,12 +241,62 @@ struct Sprite { bool faceLeft; }; -using Limb = std::vector<std::pair<uint, Frame>>; +/** + * @struct Limb + * @brief Storage of frames for the limbs of a sprite. + * This will allow us to only update a certain limb. This was we can do mulitple animation types at once. + */ +struct Limb { + Limb() { + } -//TODO + // adds frame to the back of the frame stack + void addFrame(Frame fr) { + frame.push_back(fr); + } + + void nextFrame(Frame& duckmyass, float dt) { + updateCurrent -= dt; + if (updateCurrent <= 0) { + updateCurrent = updateRate; + } else { + return; + } + + + if (index < frame.size() - 1) + index++; + else + index = 0; + + for (auto &d : duckmyass) { + if (d.first.limb == limbID) { + for (auto &fa : frame.at(index)) { + if (fa.first.limb == limbID) { + d.first = fa.first; + d.second = fa.second; + } + } + } + } + + } + + float updateRate; /**< How often we will change each frame. */ + float updateCurrent; /**< How much has been updated in the current frame. */ + uint updateType; /**< What the updateRate will base it's updates off of. + ie: Movement, attacking, jumping. */ + uint limbID; /**< The id of the limb we will be updating */ + + uint index = 0; /**< The current sprite being used for the limb. */ + + std::vector<Frame> frame; /**< The multiple frames of each limb. */ +}; + +//TODO kill clyne struct Animate { // COMMENT - Limb frame; + std::vector<Limb> limb; // COMMENT uint index; @@ -253,19 +305,18 @@ struct Animate { } // COMMENT - void nextFrame(Frame sprite) { - if (index < frame.size() - 1) { - index++; - } else { - index = 0; - } - auto fa = frame.at(index); - if (sprite.size() > fa.first-1) - sprite.at(fa.first) = fa.second.at(fa.first); - } - void firstFrame(Frame sprite) { - sprite = frame.at(0).second; + void firstFrame(Frame &sprite) { + (void)sprite; + } + //TODO make updateType an enum + void updateAnimation(uint updateType, Frame& sprite, float dt) { + uint upid = updateType; //^see todo + for (auto &l : limb) { + if (l.updateType == upid) { + l.nextFrame(sprite, dt); + } + } } }; @@ -106,9 +106,9 @@ int main(int argc, char *argv[]) // some basic OpenGL setup stuff // - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); // enable v-sync (TODO but 1000 fps?) - SDL_GL_SetSwapInterval(1); + SDL_GL_SetSwapInterval(0); // hide the cursor SDL_ShowCursor(SDL_DISABLE); // switch to pixel grid diff --git a/src/components.cpp b/src/components.cpp index 7e6f204..3096d39 100644 --- a/src/components.cpp +++ b/src/components.cpp @@ -21,11 +21,12 @@ void MovementSystem::update(entityx::EntityManager &en, entityx::EventManager &e position.x += direction.x * dt; position.y += direction.y * dt; - /*if (entity.has_component<Animate>() && entity.has_component<Sprite>()) { + if (entity.has_component<Animate>() && entity.has_component<Sprite>()) { auto animate = entity.component<Animate>(); - entity.component<Sprite>()->sprite = - (direction.x != 0) ? animate->nextFrame() : animate->firstFrame(); - }*/ + auto sprite = entity.component<Sprite>(); + + animate->updateAnimation(1, sprite->sprite, dt); + } if (entity.has_component<Dialog>() && entity.component<Dialog>()->talking) { direction.x = 0; } else { @@ -86,9 +87,11 @@ void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, float its = 0; float sz; - if (entity.has_component<Solid>()) { + if (entity.has_component<Solid>()) sz = entity.component<Solid>()->width; - } + else + sz = sprite.getSpriteSize().x; + if(sprite.faceLeft) { glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(-1.0f,1.0f,1.0f)); glm::mat4 translate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f - sz - pos.x * 2.0f, 0.0f, 0.0f)); @@ -282,11 +285,16 @@ std::vector<Frame> developFrame(XMLElement* xml) { Frame tmpf; std::vector<Frame> tmp; + SpriteData* sd; + + uint limb = 0; vec2 foffset; vec2 fsize; vec2 fdraw; + tmp.clear(); + // this is the xml elements first child. It will only be the <frame> tag auto framexml = xml->FirstChildElement(); while (framexml) { @@ -294,7 +302,6 @@ std::vector<Frame> developFrame(XMLElement* xml) std::string defframe = framexml->Name(); if (defframe == "frame") { tmpf.clear(); - tmp.clear(); // the xml element to parse each src of the frames auto sxml = framexml->FirstChildElement(); while (sxml) { @@ -304,17 +311,22 @@ std::vector<Frame> developFrame(XMLElement* xml) str2coord(sxml->Attribute("offset")) : vec2(0,0); fdraw = (sxml->Attribute("drawOffset") != nullptr) ? str2coord(sxml->Attribute("drawOffset")) : vec2(0,0); - + if (sxml->Attribute("size") != nullptr) { fsize = str2coord(sxml->Attribute("size")); - tmpf.push_back(std::make_pair(SpriteData(sxml->GetText(), foffset, fsize), fdraw)); + sd = new SpriteData(sxml->GetText(), foffset, fsize); } else { - tmpf.push_back(std::make_pair(SpriteData(sxml->GetText(), foffset), fdraw)); + sd = new SpriteData(sxml->GetText(), foffset); } + if (sxml->QueryUnsignedAttribute("limb", &limb) == XML_NO_ERROR) + sd->limb = limb; + tmpf.push_back(std::make_pair(*sd, fdraw)); } sxml = sxml->NextSiblingElement(); } - tmp.push_back(tmpf); + // we don't want segfault + if (tmpf.size()) + tmp.push_back(tmpf); } // if it's not a frame we don't care diff --git a/src/player.cpp b/src/player.cpp index e83616d..c0710cc 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -9,7 +9,8 @@ static const char *spriteXML = "<Sprite> \ <frame> \ - <src limb='0' offset='0,0' size='19,15' drawOffset='0,0'>assets/cat.png</src> \ + <src limb='0' offset='0,0' size='15,23' drawOffset='0,9'>assets/player/player.png</src> \ + <src limb='1' offset='15,0' size='12,11' drawOffset='2,0'>assets/player/player.png</src>\ </frame> \ </Sprite>"; @@ -22,14 +23,12 @@ void PlayerSystem::create(void) //player.assign<Physics>(-0.001f); player.assign<Physics>(1); player.assign<Visible>(-0.2f); - auto sprite = player.assign<Sprite>(); XMLDocument xmld; xmld.Parse(spriteXML); auto frame = developFrame(xmld.FirstChildElement("Sprite")); if (frame.size() > 0) sprite->sprite = frame.at(0); - vec2 dim = player.component<Sprite>().get()->getSpriteSize(); float cdat[2] = {dim.x, dim.y}; player.assign<Solid>(cdat[0], cdat[1]); diff --git a/src/world.cpp b/src/world.cpp index c882256..95bf576 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -350,7 +350,7 @@ void WorldSystem::load(const std::string& file) else dim = entity.component<Sprite>()->getSpriteSize(); - float cdat[2] = {dim.x * game::HLINE, dim.y * game::HLINE}; + float cdat[2] = {dim.x, dim.y}; entity.assign<Solid>(cdat[0], cdat[1]); } else if (tname == "Direction") { vec2 dir; @@ -390,19 +390,39 @@ void WorldSystem::load(const std::string& file) } else if (tname == "Animation") { auto entan = entity.assign<Animate>(); auto animx = abcd->FirstChildElement(); - uint idtc = 0; + + uint limbid = 0; + float limbupdate = 0; + uint limbupdatetype = 0; + while (animx) { std::string animType = animx->Name(); if (animType == "movement") { + limbupdatetype = 1; auto limbx = animx->FirstChildElement(); while (limbx) { - auto frames = developFrame(limbx); - if (limbx->UnsignedAttribute("changeID") != XML_NO_ERROR) - idtc = 0; - else - idtc = limbx->UnsignedAttribute("changeID"); - for (const auto& f : frames) { - entan->frame.emplace_back(idtc, f); + std::string limbHopefully = limbx->Name(); + if (limbHopefully == "limb") { + auto frames = developFrame(limbx); + + entan->limb.push_back(Limb()); + entan->limb.back().updateType = limbupdatetype; + + if (limbx->QueryUnsignedAttribute("id", &limbid) == XML_NO_ERROR) { + entan->limb.back().limbID = limbid; + } + if (limbx->QueryFloatAttribute("update", &limbupdate) == XML_NO_ERROR) { + entan->limb.back().updateRate = limbupdate; + } + + // place our newly developed frames in the entities animation stack + for (auto &f : frames) { + entan->limb.back().addFrame(f); + for (auto &fr : entan->limb.back().frame) { + for (auto &sd : fr) + sd.first.limb = limbid; + } + } } limbx = limbx->NextSiblingElement(); } @@ -1160,7 +1180,7 @@ void WorldSystem::detect(entityx::TimeDelta dt) if (!vel.grounded) { vel.grounded = true; game::engine.getSystem<ParticleSystem>()->addMultiple(20, ParticleType::SmallPoof, - [&](){ return vec2(loc.x + randGet() % static_cast<int>(dim.width * game::HLINE), loc.y);}, 500, 30); + [&](){ return vec2(loc.x + randGet() % static_cast<int>(dim.width), loc.y);}, 500, 30); } } } @@ -25,3 +25,4 @@ do done echo "Found" $TODO_COUNT "TODOs." +vim TODOS diff --git a/xml/entities.xml b/xml/entities.xml index 23b9358..04faac5 100644 --- a/xml/entities.xml +++ b/xml/entities.xml @@ -11,12 +11,36 @@ </Sprite> <Animation> <movement> - <limb update="1" id="0"> + <limb update="250.0" id="1"> <frame> - <src offset="0,21" size="15,9" drawOffset="0,13">assets/NPC.png</src> + <src offset="13,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> </frame> <frame> - <src offset="0,21" size="15,9" drawOffset="0,13">assets/NPC_Walk.png</src> + <src offset="22,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> + </frame> + <frame> + <src offset="31,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> + </frame> + <frame> + <src offset="40,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> + </frame> + <frame> + <src offset="49,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> + </frame> + <frame> + <src offset="58,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> + </frame> + <frame> + <src offset="67,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> + </frame> + <frame> + <src offset="76,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> + </frame> + <frame> + <src offset="85,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> + </frame> + <frame> + <src offset="94,0" size="9,6" drawOffset="3,0">assets/NPC_Sheet.png</src> </frame> </limb> </movement> @@ -43,7 +67,7 @@ </structure> <chest> - <Position value="0.0,100.0" /> + <Position value="1000.0,100.0" /> <Visible value="0.15" /> <Sprite> <frame> |