0
\$\begingroup\$

I just finished writing a parser for TMX data (Tiled maps), and the way Tiled handles rotated tiles is by using three bit flags for flipping an image horizontally, vertically, and diagonally, to allow for rotation. Unless I'm wrong, flipping an image "diagonally" is just rotating 90 degrees CCW (counter-clockwise) and then flipping horizontally.

So I tried to implement this when I create the sub-image of the tileset for each tile:

public Image getImage(Image tileset, int w, int h) {
    if(tid == 0) return null;

    int nh = tileset.getWidth() / w; // Number of tiles in this tileset horizontally.

    // Offsets to be multiplied by tile width and height to get origin point of tile.
    int ox = ((tid - 1) % nh); // Subtract 1 because the TID numbers are 1-indexed (why use 0 to indicate nothing? why not -1? stupid Tiled...)
    int oy = ((tid - 1) / nh);

    Image sub = tileset.getSubImage((ox * w), (oy * h), w, h);

    // If any of the flip bits are set, flip the image.
    if(fh || fv) sub = sub.getFlippedCopy(fh, fv);
    if(fd) {
        // To flip diagonally, rotate counter-clockwise, then flip it horizontally.
        sub.setRotation(-90);
        sub = sub.getFlippedCopy(true, false);
    }

    return sub;
}

Specifically, the area where I set the rotation of the sub-image is what's causing my problem. Despite setting the rotation, the image is not rotated on the canvas. Doing a little digging into the library (what little information there is), it seems that the Image class' internal rotate methods don't actually do anything to the image, and most rotation is done using the Graphics context's rotate methods, which rotate the entire context and then draw the image.

The only problem with that is that if I rotate my graphics context, which is the map I'm constructing using these tiles, then the coordinates I give to draw the tile are no longer correct because of the rotated context, so my tiles come out all over the place.

What would be my solution here for rotating the images? Is there a transformation I can do to the coordinates once the graphics context is rotated so they draw in the correct position? I don't know anything about linear algebra, so I'm not sure what to do from here.

\$\endgroup\$
0
\$\begingroup\$

I doubt anyone will encounter this, but I thought I'd post my solution since I figured it out. First of all, my issue had nothing to do with the transformation I was doing. The problem was that the flip bits I was extracting from the tile ID weren't being read because the "flip horizontal" bit at position 0x80000000 is 2,147,483,648. The max size of an integer is 2,147,483,647... so the tile ID I was extracting was incorrect and the flip horizontal bit was never being extracted. All I needed to do was store the TID in a long variable.

As far as the actual rotation... once I had the correct tile IDs and flip bits, I decided to just use the built-in rotation methods for the graphic context because it's only done once, so rotating by specific values instead of flipping the image in weird ways is just easier.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.