From 19a32074595a4a2797eaeb978f8bd302f736f6a6 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 19 Jan 2017 09:14:12 -0500 Subject: [PATCH] Limb animation actually works --- assets/NPC_Sheet.png | Bin 531 -> 763 bytes assets/player/player.png | Bin 0 -> 840 bytes include/components.hpp | 81 +++++++++++++++++++++++++++++++-------- main.cpp | 4 +- src/components.cpp | 34 ++++++++++------ src/player.cpp | 5 +-- src/world.cpp | 40 ++++++++++++++----- todo.sh | 1 + xml/entities.xml | 32 ++++++++++++++-- 9 files changed, 152 insertions(+), 45 deletions(-) create mode 100644 assets/player/player.png diff --git a/assets/NPC_Sheet.png b/assets/NPC_Sheet.png index 5537b5e1601c356fa3c0bfac332082fcae0e4286..f0f6530efa0153b048e8bc8f74229d40f201b0a4 100644 GIT binary patch delta 687 zcmV;g0#N;v1p5UciBL{Q4GJ0x0000DNk~Le0001I0000F2nGNE0Qu(8&XFN92onwn z5ytm4wvk&ae*#}gL_t(o!|hlxZ__{&{*IuwidhmRLzJ1Jm6#9%D_gq65=_M%@L57- zU_&iZ`2}pK6AA&OhyfuKGNda~*G~NpRV5sy14=}P=rQ2C+;c9riws4`FM9g)&Y#Zb z_vPI^ThuCLbl!e|vgT}vJNI9ciu?V(XwHUc1wDl0e+lw5Ap{Cb$PW>rUUe`!p8^0y zf@p&4x{OUKjPM!xH=A`4jCb zE)t%zIA+x}XTt@dYL#-4sjCpDUUjV7+41Mc_&W7)TH3^6$HU2Jh0Lni-`gp&_ou}P z#}g4ef7;Rqe=F$ei>IYcjZwp3wX<*E85WlFnRBaAg6q0ytX-fL^q5G>4m%#qbH@}! z`X1hNdyu|YoI5#pYt&e~(1Z0Gzmog(e&OFj8*_ZBvlarWNo<%5ii-To&8v4 zf|v*Z;dr8wPy2g2+EuLHm7?U+`;86lDi%Tzf78-%7|1xgb64>Khvu&0IEVdUpvhrN zf`N0+00ZqRURaN@Bo!~-YpL5?>B9cu_Z-ty)kIsGu86d5O$b5n*4NXf&$0m$?PlPl zPejPVNhi?&gAC6_8SZsSaiX@F4?3(Npx^1%j_%%OXtTig7+N`@$I!}=9z&bS=$cI8 zdHCB5ZT7|g$k6^=+YIgZ@)$C4x(5>71IYz(=E9`4(XnogY{DdQ0%LKC6aRN9K@vGK zog=ewv@pv#N|40$WSB=Td3OCVQ&q(1e7dxSs#VGqjwd3XSj!%h3kQJ6Q2zfd=O@a! Vm8Q(A;@$uN002ovPDHLkV1l@QO;-Q_ delta 454 zcmV;%0XhEr1(O6JiBL{Q4GJ0x0000DNk~Le0000V0000F2nGNE033J}qLCpo2n7!d z2W`HvP?1|Je*t$%L_t(I%f*#3OT$1E$N#S_R?;aY9ZKd7E!0IET)Wk!2RhX(wpnx+ z6!c4olhmpZoI9l-z;EDpkV0GPAQctDb1--0n$jvH_=m^47asiXasS+rWg6(+JwnP3 zeC+Jsu&f7z0oj3%rt4ucnrD&JQRt$C5MX9X5}sN1 z(GGmHS}h#r+X~#MnqmSsN~ReJqAFj zxqbAJe^=|P(*rF7P!|mm@#Xo63Rx48x(tYjA8IufvX(s={G-;w<b%7 diff --git a/assets/player/player.png b/assets/player/player.png new file mode 100644 index 0000000000000000000000000000000000000000..0f7f13a4f68228b925af1eb0350205281bd62f04 GIT binary patch literal 840 zcmV-O1GoH%P)_cVU5sz&z??+4|ZT#op^8VcHYkH2M{$qZHQAeT8-D_c$xn5?GTgD2CD9vtOld02>kl}1@?X>&eqoIwDB5@rf{{! z_0>VDz({{*Wa;^4W&b4iTPQUOQAlh`om z!o*L8ASz9yC9INuOBrnCBBuo&IZZG%Y1$Sa>8D3GTkNfq} zD-QOQiwrzZOfR@I=1C?;nqU6L7@h>* zLPS*PKMgCH5Lx4jU|p?g68ba=ed6pSBKYVfdd9k16FVUy^3hB5020qd__St>; +/** + * @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; /**< The multiple frames of each limb. */ +}; + +//TODO kill clyne struct Animate { // COMMENT - Limb frame; + std::vector 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); + } + } } }; diff --git a/main.cpp b/main.cpp index a9ccac8..f04581a 100644 --- a/main.cpp +++ b/main.cpp @@ -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() && entity.has_component()) { + if (entity.has_component() && entity.has_component()) { auto animate = entity.component(); - entity.component()->sprite = - (direction.x != 0) ? animate->nextFrame() : animate->firstFrame(); - }*/ + auto sprite = entity.component(); + + animate->updateAnimation(1, sprite->sprite, dt); + } if (entity.has_component() && entity.component()->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()) { + if (entity.has_component()) sz = entity.component()->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 developFrame(XMLElement* xml) { Frame tmpf; std::vector 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 tag auto framexml = xml->FirstChildElement(); while (framexml) { @@ -294,7 +302,6 @@ std::vector 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 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 = " \ \ - assets/cat.png \ + assets/player/player.png \ + assets/player/player.png\ \ "; @@ -22,14 +23,12 @@ void PlayerSystem::create(void) //player.assign(-0.001f); player.assign(1); player.assign(-0.2f); - auto sprite = player.assign(); XMLDocument xmld; xmld.Parse(spriteXML); auto frame = developFrame(xmld.FirstChildElement("Sprite")); if (frame.size() > 0) sprite->sprite = frame.at(0); - vec2 dim = player.component().get()->getSpriteSize(); float cdat[2] = {dim.x, dim.y}; player.assign(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()->getSpriteSize(); - float cdat[2] = {dim.x * game::HLINE, dim.y * game::HLINE}; + float cdat[2] = {dim.x, dim.y}; entity.assign(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(); 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()->addMultiple(20, ParticleType::SmallPoof, - [&](){ return vec2(loc.x + randGet() % static_cast(dim.width * game::HLINE), loc.y);}, 500, 30); + [&](){ return vec2(loc.x + randGet() % static_cast(dim.width), loc.y);}, 500, 30); } } } diff --git a/todo.sh b/todo.sh index 5f053a2..e065a76 100755 --- a/todo.sh +++ b/todo.sh @@ -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 @@ - + - assets/NPC.png + assets/NPC_Sheet.png - assets/NPC_Walk.png + assets/NPC_Sheet.png + + + assets/NPC_Sheet.png + + + assets/NPC_Sheet.png + + + assets/NPC_Sheet.png + + + assets/NPC_Sheet.png + + + assets/NPC_Sheet.png + + + assets/NPC_Sheet.png + + + assets/NPC_Sheet.png + + + assets/NPC_Sheet.png @@ -43,7 +67,7 @@ - + -- 2.39.5