#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>
using namespace std;
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 currentx = 4;
float currenty = 4;
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, 3, 2, 3, 0, 0, 3, 1, 1, 1, 2, 0, 0,
0, 3, 1, 0, 3, 0, 3, 2, 0, 3, 1, 1, 1, 1, 2, 0,
2, 3, 1, 0, 3, 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,
};
float y_tileSize = 32.0;
float x_tileSize = 32.0;
int count = 0;
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);
bool less_x = animatedSprite.getPosition().x >= currentx*32.0;
bool great_x = animatedSprite.getPosition().x < (currentx*32.0)+32.0;
bool less_y =animatedSprite.getPosition().y >= currenty*32.0;
bool great_y =animatedSprite.getPosition().y < (currenty*32.0)+32.0;
if(great_x == true && less_x == true && great_y == true && less_y == true)
{
animatedSprite.move(movement*frameTime.asSeconds());
animatedSprite.update(frameTime);
}
else
{
cout << currentx << endl;
cout << currenty << endl;
count += 1;
if(movement.x < 0)
currentx += -1;
else if(movement.x > 0)
currentx += 1;
else
currentx += 0;
if(movement.y < 0)
currenty += -1;
else if(movement.y > 0)
currenty += 1;
else
currenty += 0;
if(currenty > map_dim.y/y_tileSize)
currenty = (map_dim.y/y_tileSize)-1;
else if(currenty < 0)
currenty = 1;
if(currentx > map_dim.x/x_tileSize)
currentx = (map_dim.x/x_tileSize)-1;
else if (currentx < 0)
currentx = 1;
}
// 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;
}
Besides the Animated sprite by laurent gomila (
https://github.com/SFML/SFML/wiki/Source:-AnimatedSprite) this Is all of the code NEEDED to reproduce the issue.
the point of the current x, currenty stuff is that it is supposed to be a check if they are in a certain tile...
I apologize if it sounds quite rude.