So each tetrimino sprite has four sf::RectangleShapes. Upon checking for collision (so many times per second, which is what worries me), I'll create four sf::FloatRects for each sprite on the board, and set their position to the sprites' sf::rectangleshapes' positions. That's a lot of elements which worries me, but I'm pretty sure that will get the job done right?
That's a very tiny number of elements compared to what your computer can handle. Do not worry about it. The collision checks may be a problem, but considering these are just tetronimos, I don't think it'll be an issue anytime soon.
The more serious problem with that sample is it's not very good coding style. Specifically, it doesn't separate data from code at all. The shapes of each piece should be data, and the code that processes those shapes should be completely from them. That's more flexible and less error-prone.
Like a lot of general programming advice, that probably sounded incredibly vague and unactionable, so here's some hastily-written pseudocode that shows what I mean:
const SQUARE_SIZE = 10;
struct Tetronimo {
std::string texture_file,
sf::Vertex2i[4] squares
// write a constructor taking a string and four vertices
};
const line = Tetronimo("line.png", {0,0}, {0,1}, {0,2}, {0,3});
const square = Tetronimo("square.png", {0,0}, {0,1}, {1,0}, {1,1});
...
void GamePiece::SetShape(Tetronimo type){
...
pieceShape.setTexture(imgr.GetImage(type.texture_file));
for(int i = 0; i < 4; i++){
sf::RectangleShape rect;
sf::Vertex2i current_square = type.squares[i];
rect.setPosition(pieceShape.getPosition().x + current_square.x * SQUARE_SIZE,
current_square.y * SQUARE_SIZE);
pieceRectangles_.push_back(rect);
}
// ^ now you only need to write this part once!
}
Hopefully that made sense.
Edit: "expression must have class type" usually means you called a method on something that is not a class. So you probably put the move() in entirely the wrong place. Also, FloatRect doesn't have a move() method.