-
Asking for help to the experienced developers.
What I have: I have a single sprite. And I have created a standalone single file program to demonstrate my case.
About the sprite: That sprite is supposed to be a woodcutter. He is panting. When the left arrow key is pressed, he would blow his axe. For this purpose, I have 4 different textures of the woodcutter so that I can use them on the same sprite depending on the passed time and user input.
My problem: So far, my program works. But not as expected. The process of "blowing the axe" does not work perfectly as expected I mean is a bit sluggish and don't update correctly. I am sure I am doing something wrong or not following the most preffered way. Run it once and you would know what I am talking about. If anyone kind enough, please edit my code (62 lines total) so that everything works perfectly :'(
I have uploaded the 4 textures here in google site. You can directly download them and get them on work.
https://sites.google.com/view/metalinmyveins
The program is here:
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
int main()
{
sf::RenderWindow window{sf::VideoMode{1366, 768}, "Test", sf::Style::Fullscreen};
window.setMouseCursorVisible(false);
window.setKeyRepeatEnabled(false);
sf::Clock clock;
sf::Time timeLag1{sf::Time::Zero};
sf::Time timeLimit1{sf::seconds(0.3f)};
bool flag{true};
bool blow{false};
int blowMotionCounter{0};
sf::Clock blowClock;
sf::Time blowTimeLag{sf::Time::Zero};
sf::Time blowTimeLimit{sf::seconds(0.06f)};
sf::Texture p11, p12, p13, p14;
p11.loadFromFile("player11.png");
p12.loadFromFile("player12.png");
p13.loadFromFile("player13.png");
p14.loadFromFile("player14.png");
sf::Sprite sp;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed){ window.close(); break; }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){ window.close(); break; }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){ blow = true; break; }
}
timeLag1 += clock.restart();
blowTimeLag += blowClock.restart();
if (timeLag1 > timeLimit1)
{
timeLag1 = sf::Time::Zero;
if (flag and !blow){ flag = false; sp.setTexture(p12); }
else if (!flag and !blow){ flag = true; sp.setTexture(p11); }
sp.setScale(0.3, 0.3);
}
if (blowTimeLag > blowTimeLimit)
{
blowTimeLag = sf::Time::Zero;
if (blow and blowMotionCounter == 0){ ++blowMotionCounter; sp.setTexture(p13); }
else if (blow and blowMotionCounter == 1){ ++blowMotionCounter; sp.setTexture(p14); }
else if (blow and blowMotionCounter == 2){ blowMotionCounter = 0; blow = false; sp.setTexture(p13); }
}
window.clear();
window.draw(sp);
window.display();
}
}
-
I haven't tried running the code yet, but my off-the-top-of-my-head reaction would be:
The two lag timers are running at the same time. When the left arrow is pressed and the state switches to blowing, the blowing time lag is already at some point during the cycle, so the first frame will have a random length. Same for when leaving the blowing state, the other lag timer is already in progress.
Perhaps try these changes:
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){ blow = true; blowTimeLag = sf::Time::Zero; break; }
and
else if (blow and blowMotionCounter == 2){ blowMotionCounter = 0; blow = false; timeLag1 = sf::Time::Zero; sp.setTexture(p13); }
-
I have tried your solution. But sadly the problem still persists :'(
-
to be honest I ran your code and didn't understood what is the problem
(https://i.postimg.cc/RF90cq7Y/out.gif) (https://postimages.org/)
-
Keep pressing the left arrow key super fast and you would see that the blowing cycle is not complete. (he should hold his axe upside once between each cycle).
-
Not that this is the issue, but you shouldn't mix real-time input and events
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed){ window.close(); break; }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){ window.close(); break; }
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){ blow = true; break; }
}
Use this instead:
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed){ window.close(); break; }
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape){ window.close(); break; }
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Left)){ blow = true; break; }
}