# What way to draw random sprite from spritesheet in SFML?

I have a spritesheet(900x100) with of different colored shapes each size 100x100. I am trying to code a program such that, after every 2 seconds, one random sprite appears on screen. If I click, it should disappear and after 2 seconds another random shape should appear. If I don't, it should continue to show that image.

Using IntRect, I am able to cut out individual shapes out of the spritesheet and display them. I thought that in the IntRect parameters:

Shape.setTextureRect(sf::IntRect(0, 0, 100, 100));


I could replace the first 0, like this:

Shape.setTextureRect(sf::IntRect(((rand() % 8) * 100), 0, 100, 100));


and after 2 seconds, it would show me a new random sprite. However, after 2 seconds, the window shows what looks like a bunch of random shapes playing really fast one after the other, nothing and then 2 seconds later it repeats.

If I can't get the random images to work properly I don't think I'll be able to do the mouse events.

Here is my code so far: main.cpp

#include <SFML/Graphics.hpp>
#include <iostream>
#include <stdlib.h>
#include <time.h>

int main()
{
sf::RenderWindow window(sf::VideoMode(640, 480), "Tile Game");

sf::Clock clock;
sf::Time timer;

sf::Texture shapeSpriteSheet;
sf::Texture Background;

sf::Sprite bg;
sf::Sprite Shape;

srand(time(NULL));

bg.setTexture(Background);

shapeSpriteSheet.setSmooth(true);

Shape.setTexture(shapeSpriteSheet);
Shape.setPosition(sf::Vector2f(192, 146));

while (window.isOpen())
{
sf::Event event;
window.draw(bg);

while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}

timer = clock.getElapsedTime();

if (timer.asSeconds() >= 2)
{
Shape.setTextureRect(sf::IntRect(((rand() % 8) * 100), 0, 100, 100));
window.draw(Shape);

if (timer.asSeconds() > 2.1)
clock.restart();
}

window.display();
}

return 0;
}


Update:

I've finally made it so that, every 2 seconds a sprite appears, on click it disappears. Now Im working on making every sprite randomly selected

New code:

if (clock.getElapsedTime().asSeconds() >= 2)
{
shapeVisible = true;
Shape[0].setPosition(sf::Vector2f(192, 146));
window.draw(Shape[0]);

if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
if (Shape[0].getGlobalBounds().contains(window.mapPixelToCoords(sf::Mouse::getPosition(window))))
{
clock.restart();
}
}

}


if (timer.asSeconds() >= 2)
{
// { code here to choose a new sprite and draw it to the screen }

if (timer.asSeconds() > 2.1)
clock.restart();
}


(this is a snippet of your provided code)

What's the behaviour of this code in between time 2 and time 2.1?

Remember that at 60fps, there's 0.016 seconds between each frame, so there'll be about six frames in that interval. If you're running at higher than 60fps, there could be far more.

So think through just this little bit of your code; what is the program going to do when it executes this part of your program's main loop when it reaches this 'if' statement during the six frames between those two times, if it's following your instructions exactly as you've written them?

• Sorry if my understanding is a bit wrong: I don't think its running at 60 FPS since I haven't limited it. What I think is happening is that between timer is =2 and timer is 2.1, the program is still running thru the if (timer.asSeconds() >= 2) so it is still selecting a new sprite and drawing it to the window. Probably because the program is fast enough to run multiple times between 2 and 2.1 seconds? Is that correct? – ArmenHeat Nov 29 '16 at 11:11
• Each frame between time 2 and time 2.1, you're selecting a random sprite and drawing it. And at any other time you draw nothing (since you're only drawing the shape inside the 'if time > 2' conditional). That's exactly what you've described your program as doing, right? – Trevor Powell Nov 29 '16 at 11:14