0

So in my tetris game, I'm working on rotation. I've found an algorithim that works for every piece but the square piece (ironically, the only one that doesn't even need to rotate). I know I could just check to see if the piece isn't a square then rotate it if it isn't, but that's just cheap. So here's the code:

pieceShape.setTexture(imgr.GetImage("square.png"));
        for(int i = 0; i < 4; i++){
            sf::RectangleShape rect;
            if(i < 2)
                rect.setPosition(pieceShape.getPosition().x, i * 10);
            else
                rect.setPosition(pieceShape.getPosition().x + 10, (i - 2) * 10);
            rect.setSize(sf::Vector2f(10, 10));
            rect.setFillColor(sf::Color::Blue);
            pieceRectangles_.push_back(rect);
        }
        originCount = 10;

Here, I'm creating all four blocks that make up a square piece. 10 is the width of each box (4 boxes per square) in pixels. For all other pieces, I set originCount to 5 so the origin falls in the middle of the first box created. The originCount comes into play in the RotateRight/Left functions:

void GamePiece::RotateRight(){
    int newx, newy;
    sf::Vector2f origin(pieceRectangles_[0].getPosition().x + originCount, pieceRectangles_[0].getPosition().y + originCount);
    for(int i = 0; i < 4; i++){
        newx = (pieceRectangles_[i].getPosition().y + origin.x - origin.y);
        newy = (origin.x + origin.y - pieceRectangles_[i].getPosition().x - 10);
        pieceRectangles_[i].setPosition(newx, newy);
    }
}

In theory, the origin has now been set to the middle of the square's sprite, and the boxes should rotate about that point (i.e. appear to not even move). But the boxes shoot to the left 10 pixels on the first click, go up maybe 2 pixels on click two, etc. I'm clearly missing something, but what?

jburn7
  • 125
  • 2
  • 3
  • 15
  • Why do you rotate the square? I've never noticed any change, in any of the Tetris related games, when I rotated the square. Will it look different when you rotate it 90 degrees? – Thomas Matthews Sep 30 '14 at 22:26
  • No, but I'm a stickler for convention. I'd rather have one method with no exceptions that can rotate (or not rotate) all of my pieces, rather than adding an ugly exception for rotating when the active piece is a square. – jburn7 Sep 30 '14 at 22:33
  • 1
    in ordinary rotation 90 degrees right, x coordinate goes to minus y, and y-coordinate goes to x. so first transform to coordinate system with origin at the piece's origin, math_x = piece[i].x() - originoffset. then rotated_math_y = -math_x. then newy = rotated_math_y + origin_offset. and ditto for the other. – Cheers and hth. - Alf Sep 30 '14 at 22:43
  • @jburn7 A better way to follow convention would be to make `RotateRight` virtual and override it in the `Square` class to do nothing. – Kyle Strand Oct 10 '14 at 17:05

1 Answers1

1

You calculate origin incorrectly. After the first rotation the coordinates of pieceRectangles_[0] will be (0, 10), so next time origin will be calculated as (10, 20), which is not what you want.

Anton Savin
  • 40,838
  • 8
  • 54
  • 90