Reputation: 133
I am trying to use vectors in sfml C++ and I am semi-failing because I am not able to create a vector consisting of 4 RectangleShapes :( I am skipping some lines of the code which are not causing the problem
This is the code which is working but it is least optimized in my opinion
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <vector>
#include <iostream>
#include "mainCharacter.h" // it consists the mainCharacter class
class classBackground{
public:
sf::Texture texture;
sf::Sprite image;
sf::RectangleShape rectTopBorder,rectBotBorder,rectLeftBorder,rectRightBorder;
std::vector<sf::RectangleShape> rect;
classBackground(){
texture.loadFromFile("wagon.png");
image.setTexture(texture);
image.setPosition(300,250);
rectTopBorder.setSize(sf::Vector2f(230,5));
rectTopBorder.setPosition(image.getPosition());
rectTopBorder.move(0,60);
rectBotBorder.setSize(sf::Vector2f(230,5));
rectBotBorder.setPosition(image.getPosition());
rectBotBorder.move(0,225);
rectLeftBorder.setSize(sf::Vector2f(5,170));
rectLeftBorder.setPosition(image.getPosition());
rectLeftBorder.move(0,60);
rectRightBorder.setSize(sf::Vector2f(5,170));
rectRightBorder.setPosition(image.getPosition());
rectRightBorder.move(225,60);
rect.push_back(rectTopBorder);
rect.push_back(rectBotBorder);
rect.push_back(rectLeftBorder);
rect.push_back(rectRightBorder);
}
};
//in the main function
classMainCharacter mainCharacter; ///another class which has collision detection
classBackground background;
///in the loop
for(int i = 0; i<=3; i++){
mainCharacter.collision(background.rect[i]); ///colision is a function in the mainCharacter class (detects collision)
}
And this is the code which I want to work but my game is crushing :(
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <vector>
#include <iostream>
#include "mainCharacter.h" // it consists the mainCharacter class
class classBackground{
public:
sf::Texture texture;
sf::Sprite image;
std::vector<sf::RectangleShape> rect; // it doesn't work if I write rect(4) or rect = {rect1,rect2,rect3,rect3} or even rect(4)={rect1,....}
classBackground(){
texture.loadFromFile("wagon.png");
image.setTexture(texture);
image.setPosition(300,250);
rect[0].setSize(sf::Vector2f(230,5));
rect[0].setPosition(image.getPosition());
rect[0].move(0,60);
rect[1].setSize(sf::Vector2f(230,5));
rect[1].setPosition(image.getPosition());
rect[1].move(0,225);
rect[2].setSize(sf::Vector2f(5,170));
rect[2].setPosition(image.getPosition());
rect[2].move(0,60);
rect[3].setSize(sf::Vector2f(5,170));
rect[3].setPosition(image.getPosition());
rect[3].move(225,60);
}
};
//in the main function
classMainCharacter mainCharacter; ///another class which has collision detection
classBackground background;
///in the loop
for(int i = 0; i<=3; i++){
mainCharacter.collision(background.rect[i]); ///colision is a function in the mainCharacter class (detects collision)
}
what am I doing wrong? :( I tried to defined the rects before vector and then inserting into the vector but it also doesn't work (in such way vector<...> rect = {......}).
Upvotes: 0
Views: 1902
Reputation: 24249
In the first version, you were successfully creating a vector of 4 elements by using push_back
.
In the second version, you never allocate space for your 4 elements, so when you try and assign values to the elements of the vector, that's your crash.
If you really don't want to use push_back
you can instead use resize
to set the size of the vector.
Here's a simplified version of what you're trying to do
#include <vector>
class classBackground {
std::vector<int> rect;
public:
classBackground() {
rect.resize(4);
rect[0] = 1;
rect[1] = 2;
rect[2] = 3;
rect[3] = 4;
}
};
int main() {
classBackground cb;
// there, it worked.
}
Demo: http://ideone.com/YYq0oA
Alternatively if you have C++11 and your vector is always going to be 4 elements large, which in this case it seems like it might be, you should consider using std::array
instead.
#include <array>
class classBackground {
std::array<int, 4> rect;
public:
classBackground() {
rect[0] = 1;
rect[1] = 2;
rect[2] = 3;
rect[3] = 4;
}
};
int main() {
classBackground cb;
// there, it worked.
}
Array works like vector in most ways, you just can't change the size, but it can potentially be more efficient.
Upvotes: 1
Reputation: 92
Well even if I would not expect to much difference between the two versions, an answer is worth telling anyway as your problem has neither to do with performance nor with sfml at all but is more general.
What you try is to instantiate a class member at its declaration, what is not possible. But what you can do is either one of the following methods:
1) Use the default member initializer with the C++ 11 unified initialization syntax like so (wich may only be syntactic sugar for (2) prior to this: http://en.cppreference.com/w/cpp/language/data_members#Member_initialization):
std::vector<sf::RectangleShape> rect{4}
2) Use the initializer list in the constructor:
classBackground() : rect(4) {...}
3) Or call the resize method in the constructor:
classBackground(){
rect.resize(4);
...
}
The last one might be the worst as it first calls the standard constructor of vector<...> and changes it afterwards.
Upvotes: 1