# Looping through a vector.

Page 1 of 1

## 4 Replies - 1348 Views - Last Post: 21 June 2012 - 07:47 AMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=283384&amp;s=f8f137957f6766c56bc90e4853523dbb&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

### #1 Gonzo0193

Reputation: 2
• Posts: 49
• Joined: 16-December 09

# Looping through a vector.

Posted 20 June 2012 - 11:46 AM

So i am having trouble looping through a vector and drawing everything in it to the screen (using SFML).

Here is the loop:

```		for(int i = 0; i < enemyList.size(); i++)
{
//sf::Sprite tempSprite = enemyList[i];
window.draw(enemyList[i]);
}

```

The vector is intialised as:

```std::vector<sf::Sprite> enemyList;

```

and added too with this function:

```void Game::addEnemy(int x, int y)
{
sf::Texture enemyImageTemp;
sf::Sprite enemyTemp;
{
//Something went wrong
std::cout << "Couldnt Load image for enemy" << std::endl;
}
enemyTemp.setTexture(enemyImageTemp);
enemyTemp.setPosition(x,y);
enemyList.push_back(enemyTemp);
if(enemyList.size() < 1)
{
std::cout << "nothing added" << std::endl;
}
}

```

here is all my code:

main.h
```#ifndef _main_H_
#define _main_H

#include <SFML/Graphics.hpp>
#include <iostream>
#include <Windows.h>
#include <vector>

class Game {

private:

public:

sf::RenderWindow window;
std::vector<sf::Sprite> enemyList;
sf::Sprite playerSprite;
sf::Texture playerTexture;

};

#endif

```

main.cpp
```#include "main.h"

const int PLAYER_MOVE_SPEED = 3;

std::vector<sf::Sprite> enemyList;

{
sf::Texture enemyImageTemp;
sf::Sprite enemyTemp;
{
//Something went wrong
std::cout << "Couldnt Load image for enemy" << std::endl;
}
enemyTemp.setTexture(enemyImageTemp);
enemyTemp.setPosition(x,y);
enemyList.push_back(enemyTemp);
if(enemyList.size() < 1)
{
std::cout << "nothing added" << std::endl;
}
}

int main()
{
Game game;

sf::RenderWindow window(sf::VideoMode(1024, 768), "SFML works!");
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(true);

sf::Sprite playerSprite;
sf::Texture playerTexture;

{
//Something went wrong
std::cout << "Couldnt Load image for player" << std::endl;
}
playerSprite.setTexture(playerTexture);
playerSprite.setScale(0.2,0.2);
playerSprite.setPosition(0, 768 - 100);

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

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
playerSprite.move(-PLAYER_MOVE_SPEED,0);
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
playerSprite.move(PLAYER_MOVE_SPEED,0);
}

window.clear();
window.draw(playerSprite);
window.draw(enemyList[0]);

for(int i = 0; i < enemyList.size(); i++)
{
//sf::Sprite tempSprite = enemyList[i];
window.draw(enemyList[i]);
}

window.display();
}

TerminateProcess(GetCurrentProcess(), EXIT_SUCCESS);
}

```

Is This A Good Question/Topic? 1

## Replies To: Looping through a vector.

### #2 NickDMax

Reputation: 2255
• Posts: 9,245
• Joined: 18-February 07

## Re: Looping through a vector.

Posted 20 June 2012 - 12:27 PM

Quote

So i am having trouble looping through a vector and drawing everything in it to the screen (using SFML).

Please tell us what KIND of trouble you are having? Help us understand what is happening, is it a syntax thing? Does it compile but does not draw the sprites? That is a lot of code to go swimming though looking for "trouble".

One thing I did note though -- you have two "enemyList" vectors -- one is a global variable (generally we try to avoid global variables) the other is a member of Game.

Make sure you know which one is which when you use it!

This post has been edited by NickDMax: 20 June 2012 - 12:27 PM

### #3 Gonzo0193

Reputation: 2
• Posts: 49
• Joined: 16-December 09

## Re: Looping through a vector.

Posted 20 June 2012 - 01:19 PM

NickDMax, on 20 June 2012 - 08:27 PM, said:

Quote

So i am having trouble looping through a vector and drawing everything in it to the screen (using SFML).

Please tell us what KIND of trouble you are having? Help us understand what is happening, is it a syntax thing? Does it compile but does not draw the sprites? That is a lot of code to go swimming though looking for "trouble".

One thing I did note though -- you have two "enemyList" vectors -- one is a global variable (generally we try to avoid global variables) the other is a member of Game.

Make sure you know which one is which when you use it!

I didn't realise that made i global, i was just doing what i would in c#. The problem i was having when it wasn't global was that the vector would be destroyed after the addEnemy function was called.

If i keep the one that belongs to game in, i get a vector subscript out of range. If i leave it as a global it is now seeming to work. So i guess my problem is now how do i get the list from destructing itself after being used in addEnemy?

### #4 NickDMax

Reputation: 2255
• Posts: 9,245
• Joined: 18-February 07

## Re: Looping through a vector.

Posted 21 June 2012 - 07:02 AM

Well, ultimately I was able to fix your issue with the list but ran into another problem:

From SFML documentation for sf:Sprite

Quote

It is important to note that the sf::Sprite instance doesn't copy the texture that it uses, it only keeps a reference to it. Thus, a sf::Texture must not be destroyed while it is used by a sf::Sprite (i.e. never write a function that uses a local sf::Texture instance for creating a sprite).

This means that that this little bit of code does not work:
```void Game::addEnemy(int x, int y)
{
sf::Texture enemyImageTemp; //this is a local instance and will be deconstructed at end of scope.
sf::Sprite enemyTemp;
{
//Something went wrong
std::cout << "Couldnt Load image for enemy" << std::endl;
}
enemyTemp.setTexture(enemyImageTemp);
enemyTemp.setPosition(x,y);
enemyList.push_back(enemyTemp);
if(enemyList.size() < 1)
{
std::cout << "nothing added" << std::endl;
}
}

```

You see enemyList.push_back(enemyTemp); makes a COPY of the sf::sprite which DOES NOT make a copy of the Texture, which means as soon as the Texture is out of scope it is destroyed.

So is the code that I got to "work" -- I don't think it is organized the best but that is something you will have to work out. Personally I think you will probably need to create and Enemy class to encapsulate the sprite and to ensure that the Texture remains intact when the object is copied (STL vectors do a lot of copying).

```#define SFML_STATIC

#include <SFML/Graphics.hpp>
#include <iostream>
#include <Windows.h>
#include <vector>

class Game {

private:

public:

sf::RenderWindow& window;
sf::Texture enemyImage;
std::vector<sf::Sprite> enemyList;
Game(sf::RenderWindow& wn);
void draw();
};

const int PLAYER_MOVE_SPEED = 3;

Game::Game(sf::RenderWindow& wn) : window(wn) {
{
//Something went wrong
std::cout << "Couldnt Load image for enemy" << std::endl;
}
}

{
sf::Sprite enemyTemp;

enemyTemp.setTexture(enemyImage);
enemyTemp.setScale(0.2,0.2);
enemyTemp.setPosition(x,y);
window.draw(enemyTemp);
enemyList.push_back(enemyTemp);
if(enemyList.size() < 1)
{
std::cout << "nothing added" << std::endl;
}
}

void Game::draw() {
for(size_t i = 0; i < enemyList.size(); i++)
{
window.draw(enemyList[i]);
//std::cout <<i << std::endl;
}
}

int main()
{
sf::RenderWindow window(sf::VideoMode(1024, 768), "SFML works!");
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(true);
Game game(window);

sf::Sprite playerSprite;
sf::Texture playerTexture;

{
//Something went wrong
std::cout << "Couldnt Load image for player" << std::endl;
}
playerSprite.setTexture(playerTexture);
playerSprite.setScale(0.2,0.2);
playerSprite.setPosition(0, 768 - 100);

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

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
playerSprite.move(-PLAYER_MOVE_SPEED,0);
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
playerSprite.move(PLAYER_MOVE_SPEED,0);
}

window.clear();
window.draw(playerSprite);
game.draw();
window.display();
}

TerminateProcess(GetCurrentProcess(), EXIT_SUCCESS);
}
```

This post has been edited by NickDMax: 21 June 2012 - 07:05 AM

### #5 vividexstance

• Tiocfaidh ár lá

Reputation: 792
• Posts: 2,873
• Joined: 31-December 10

## Re: Looping through a vector.

Posted 21 June 2012 - 07:47 AM

I haven't tried out the code, but what about using a static array of Sprites? Also, I know this is nit-picking, but I just want to point out that even though this code works, from Game::addEnemy():
```if(enemyList.size() < 1)
{
std::cout << "nothing added" << std::endl;
}

```

I think this is more explicit:
```if(enemyList.empty())
{
std::cout << "nothing added" << std::endl;
}

```