Reputation: 21
i wanted to make player a bit realistic instead of just hovering around like a ghost. this is my code just some basic gravity and movement, i want to make jumping animation, walking animation, turn left and turn right animation. how do i do that?
here code:
void Game::initTexture()
{
if (!texture.loadFromFile("/home/webmaster/Documents/vscode-sfml/src/Ball_and_Chain_Bot/pixil-frame-0(1).png"))
{
std::cout << "failed to load texture\n";
rect.setTexture(texture);
rect.setPosition(this->window->getView().getCenter());
rect.setScale(2,2);
}
}
rendering:
void Game::render()
{
this->window->clear(sf::Color(239, 235, 216));
this->window->draw(rect);
this->window->display();
}
Upvotes: 0
Views: 824
Reputation: 30830
You forgot to show your actual code, the headers are not very useful. Regardless:
sf::Shape::setTextureRect
to select a part of the texture to draw.Let us define the frames of an animation in terms of sf::IntRect
sections of a given sprite sheet: (example sprite sheet)
std::vector<sf::IntRect> idle {
{0, 0, 35, 61}
};
std::vector<sf::IntRect> runningRight {
{657, 473, 43, 52}, // first frame is at 657x473 and is 43x52 pixels
// other frames.
};
We can define an Animation
class with the following data and methods:
class Animation {
public:
Animation(const std::vector<sf::IntRect>& frames, float duration, bool cycles = true) : frames(frames), frameTime(duration / frames.size()), cycles(cycles) { reset(); }
void reset() {
currentFrame = 0;
currentFrameTime = 0;
}
void update(float dt);
const sf::IntRect& getCurrentRect() const { return frames[currentFrame]; }
private:
const std::vector<sf::IntRect>& frames;
const float frameTime;
bool cycles;
int currentFrame;
float currentFrameTime;
};
This implements most of step 2: keeping track of which frame should be on screen, assuming update(dt)
is called every frame.
Now all that remains is the update
method:
void Animation::update(float dt) {
currentFrameTime += dt;
// TODO: take `cycles` into account.
while (currentFrameTime >= frameTime) {
currentFrameTime -= frameTime;
currentFrame = (currentFrame + 1) % frames.size();
}
}
Finally, to hook this up, create the following variables:
sf::Texture textureAtlas = ...;
Animation currentAnimation{idle, 10.0f};
sf::Sprite player(textureAtlas, currentAnimation.getCurrentRect());
update()
code, call currentAnimation.update(dt)
.player.setTextureRect(currentAnimation.getCurrentRect())
.currentAnimation = Animation{runningRight, 1.0f}
;Upvotes: 1