Here is the shortest possible code i could come up with to reproduce the problem:
#include <iostream>
#include <iomanip>
#include <queue>
#include <string>
#include <math.h>
#include <ctime>
#include <SFML/Graphics.hpp>
#include <vector>
#include <memory>
#include <stdlib.h>
#include <stdio.h>
#include "Animation.hpp"
#include "AnimatedSprite.hpp"
#include <chrono>
#include <thread>
class TileMap : public sf::Drawable, public sf::Transformable
{
public:
bool load(const std::string& tileset, sf::Vector2u tileSize, const int* tiles, unsigned int width, unsigned int height)
{
// load the tileset texture
if (!m_tileset.loadFromFile(tileset))
return false;
// resize the vertex array to fit the level size
m_vertices.setPrimitiveType(sf::Quads);
m_vertices.resize(width * height * 4);
// populate the vertex array, with one quad per tile
for (unsigned int i = 0; i < width; ++i)
for (unsigned int j = 0; j < height; ++j)
{
// get the current tile number
int tileNumber = tiles[i + j * width];
// find its position in the tileset texture
int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);
// get a pointer to the current tile's quad
sf::Vertex* quad = &m_vertices[(i + j * width) * 4];
// define its 4 corners
quad[0].position = sf::Vector2f(i * tileSize.x, j * tileSize.y);
quad[1].position = sf::Vector2f((i + 1) * tileSize.x, j * tileSize.y);
quad[2].position = sf::Vector2f((i + 1) * tileSize.x, (j + 1) * tileSize.y);
quad[3].position = sf::Vector2f(i * tileSize.x, (j + 1) * tileSize.y);
// define its 4 texture coordinates
quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
}
return true;
}
private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
// apply the transform
states.transform *= getTransform();
// apply the tileset texture
states.texture = &m_tileset;
// draw the vertex array
target.draw(m_vertices, states);
}
sf::VertexArray m_vertices;
sf::Texture m_tileset;
};
int main()
{
// create the window
sf::Vector2i map_dim(512,256);
sf::RenderWindow window(sf::VideoMode(map_dim.x, map_dim.y), "Tilemap");
sf::Texture texture;
// window.setFramerateLimit(60);
if (!texture.loadFromFile("FFSPRITE.gif"))
{
std::cout << "Failed to load player spritesheet!" << std::endl;
return 1;
}
bool has_clicked = false;
// set up tshe animations for all four directions (set spritesheet and push frames)
Animation walkingAnimationDown;
walkingAnimationDown.setSpriteSheet(texture);
walkingAnimationDown.addFrame(sf::IntRect(47,5, 16,16) );
walkingAnimationDown.addFrame(sf::IntRect(65,5,16, 16) );
walkingAnimationDown.addFrame(sf::IntRect(47,5, 16,16) );
Animation walkingAnimationLeft;
walkingAnimationLeft.setSpriteSheet(texture);
walkingAnimationLeft.addFrame(sf::IntRect(83,5, 13,16 ) );
walkingAnimationLeft.addFrame(sf::IntRect(98,5,14,16));
walkingAnimationLeft.addFrame(sf::IntRect(83,5,13,16));
Animation walkingAnimationRight;
walkingAnimationRight.setSpriteSheet(texture);
walkingAnimationRight.addFrame(sf::IntRect(150,5, 13, 16) );
walkingAnimationRight.addFrame(sf::IntRect(165,5,14, 16) );
walkingAnimationRight.addFrame(sf::IntRect(150,5,13,16) );
Animation walkingAnimationUp;
walkingAnimationUp.setSpriteSheet(texture);
walkingAnimationUp.addFrame(sf::IntRect(114, 5, 16, 16));
walkingAnimationUp.addFrame(sf::IntRect(132, 5, 16, 16));
walkingAnimationUp.addFrame(sf::IntRect(114, 5, 16, 16));
Animation* currentAnimation = &walkingAnimationDown;
// set up AnimatedSprite
AnimatedSprite animatedSprite(sf::seconds(0.2), true, false);
animatedSprite.setPosition(sf::Vector2f(4.0*32.0,7.0*32.0));
sf::Clock frameClock;
float speed = 1.f;
bool noKeyWasPressed = true;
// define the level with an array of tile indices
const int level[] =
{
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 2, 0, 0, 0, 0,
1, 1, 0, 0, 3, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3,
0, 3, 3, 3, 3, 0, 3, 3, 0, 3, 1, 1, 1, 0, 0, 0,
0, 3, 1, 0, 2, 2, 3, 0, 0, 3, 1, 1, 1, 2, 0, 0,
0, 3, 1, 0, 2, 0, 3, 2, 0, 3, 1, 1, 1, 1, 2, 0,
2, 3, 1, 0, 2, 0, 3, 2, 2, 3, 1, 1, 1, 1, 1, 1,
0, 3, 3, 3, 3, 2, 3, 3, 3, 3, 0, 0, 1, 1, 1, 1,
};
string route = "445667077012322107666700000";
// create the tilemap from the level definition
TileMap map;
if (!map.load("tileset.png", sf::Vector2u(32, 32), level, 16, 8))
return -1;
animatedSprite.play(*currentAnimation);
sf::FloatRect as = animatedSprite.getGlobalBounds();
// run the main loop
while (window.isOpen())
{
sf::Event event;
char ada;
int qx;
if(count < route.length())
{
ada = route.at(count);
qx = atoi(&ada);
count += 1;
}
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
window.close();
}
sf::Time frameTime = frameClock.restart();
// if a key was pressed set the correct animation and move correctly
sf::Vector2f movement(0.f, 0.f);
if (qx == 6)
{
currentAnimation = &walkingAnimationUp;
movement.y -= speed;
noKeyWasPressed = false;
}
if (qx == 2)
{
currentAnimation = &walkingAnimationDown;
movement.y += speed;
noKeyWasPressed = false;
}
if(qx == 4)
{
currentAnimation = &walkingAnimationLeft;
movement.x -= speed;
noKeyWasPressed = false;
}
if (qx == 0)
{
currentAnimation = &walkingAnimationRight;
movement.x += speed;
noKeyWasPressed = false;
}
if (qx == 1)
{
currentAnimation = &walkingAnimationDown;
movement.y += speed;
movement.x += speed;
noKeyWasPressed = false;
}
if(qx==3)
{
currentAnimation = &walkingAnimationDown;
movement.y += speed;
movement.x -= speed;
noKeyWasPressed = false;
}
if(qx == 5)
{
currentAnimation = &walkingAnimationUp;
movement.y -= speed;
movement.x -= speed;
noKeyWasPressed = false;
}
if(qx == 7)
{
currentAnimation = &walkingAnimationUp;
movement.y -= speed;
movement.x += speed;
noKeyWasPressed = false;
}
animatedSprite.play(*currentAnimation);
float qy = 0;
if(movement.x != 0){
while (fabs(qy) < float(x_tileSize - as.width))
{
animatedSprite.move(sf::Vector2f(movement.x*frameTime.asSeconds(),0));
animatedSprite.update(frameTime);
qy += float(movement.x)*frameTime.asSeconds();
}
}
float qxz = 0;
if(movement.y != 0) {
while(fabs(qxz) < float(y_tileSize-as.height))
{
animatedSprite.move(sf::Vector2f(0,movement.y*frameTime.asSeconds()));
animatedSprite.update(frameTime);
qxz += float(movement.y)*frameTime.asSeconds();
}
}
std::chrono::milliseconds dura( 200 );
std::this_thread::sleep_for( dura );
// if no key was pressed stop the animation
if (noKeyWasPressed)
{
animatedSprite.stop();
}
noKeyWasPressed = true;
//animatedSprite.update(frameTime);
window.clear();
window.draw(map);
window.draw(animatedSprite);
window.display();
}
return 0;
}
Please keep in mind you need the animated sprite by laurent gomila(excuse me if it is misspelled) that i linked earlier