Randomizing sprite drawing in SFML

I have a spritesheet 900x100 pixels. Each 100x100 pixel block is a shape. I store it using sf::IntRect into an array of sprites with each sprite being a separate shape.

When my program runs, after 2 seconds, a shape appears on screen. When I click it, it disappears and after two seconds it appears again. I can't figure out how to make it so that every time I click it, the next shape will be a randomly selected one.


My code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  #include <SFML/Graphics.hpp>
#include <iostream>


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[9];

	bool shapeVisible = false;

	srand(time(NULL));
	
	Background.loadFromFile("bg.png");
	bg.setTexture(Background);

	shapeSpriteSheet.loadFromFile("shapes.png");
	shapeSpriteSheet.setSmooth(true);


	for (int i = 0; i < 9; i++)
	{
		Shape[i].setTexture(shapeSpriteSheet);
		Shape[i].setTextureRect(sf::IntRect((i*100), 0, 100, 100));
		Shape[i].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();
		}

		if (clock.getElapsedTime().asSeconds() >= 2)
		{

			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();
				}
			}
			
		}

		window.display();
	}

	return 0;
}
Last edited on
Do you just want a randomly selected one out of that array?
Try something like

1
2
3
4
5
6
7
8
9
unsigned int index = 0;
...
if (event.type == sf::Event::MouseButtonPressed) {
  index = SomeRandomlyChosenNumberBetween1and9..
}
...
window.clear();
window.draw(Shape[index]);
window.display();


I recommend avoiding polling using sf::Mouse::IsButtonPressed for things like this, since it will fire every frame that you're holding the mouse down. Using if (event.type == sf::Event::MouseButtonPressed) you'll only change the index when the user presses the mouse down and it won't be triggered again until the user releases the mouse and pressed down on the mouse again. It'll only fire once per mouse click rather than firing every frame the mouse is held down.

The reason it takes 2 seconds to change is because you have if (clock.getElapsedTime().asSeconds() >= 2). Remove that if you don't want to only check every 2 seconds.
If there is no shape on screen, I want it to wait 2 seconds before showing the next one. But if there is, then I want that shape to stay there until clicked.

Thanks for the code it works perfectly.

For anyone who's isn't clear on what I did:

1
2
3
// Outside of game loop, within main().
//When the program runs for the first time, it assigns a random index number
unsigned int random = rand() % 8;


In my while (window.pollEvent(event)) loop, I added:

1
2
3
4
		if (event.type == sf::Event::MouseButtonPressed)
			{
				random = rand() % 8;
			}


Now every time the game starts, there is a random index number, after that, each time a mouse button is pressed it assigns a new random number to the index variable.
I have another related question:

Shape[0].setPosition(sf::Vector2f(192, 146));

I was trying to set it so after clicking, the next random shape appears in any one of 4 coordinates instead of the ones I set. So:

1
2
3
4
5
6
7
8
9
10
11
12
13
sf::Vector2f vector[4];

	vector[0].x = 192;
	vector[0].y = 146;
	vector[1].x = 352;
	vector[1].y = 146;
	vector[2].x = 192;
	vector[2].y = 307;
	vector[3].x = 352;
	vector[3].y = 307;

        //Setting the first PosIndex to be random
	unsigned int PosIndex = rand() % 3;


Then in my while(window.isOpen()), I add PosIndex = rand() % 3; :

1
2
3
4
5
6
if (event.type == sf::Event::MouseButtonPressed)
			{
				ShapeIndex = rand() % 8;
				PosIndex = rand() % 3;
				
			}


And change the .setPosition parameters to: (vector[PosIndex]).


However now, after clicking on a shape, the next shape either takes 2 seconds to appear or appears instantly. They are changing coordinates randomly, just not taking 2 seconds to appear.
Topic archived. No new replies allowed.