Wookiederk
Wookiederk

Reputation: 47

Rotating a BufferedImage and Saving it into a pixel array

I am trying to properly rotate a sword in my 2D game. I have a sword image file, and I wish to rotate the image at the player's location. I tried using Graphics2D and AffineTransform, but the problem is that the player moves on a different coordinate plane, the Screen class, and the Graphics uses the literal location of the pixels on the JFrame. So, I realized that I need to render the sword by rotating the image itself, and then saving it into a pixel array for my screen class to render. However, I don't know how to do this. Here is the code for my screen rendering method:

public void render(double d, double yOffset2, BufferedImage image, int colour,
        int mirrorDir, double scale, SpriteSheet sheet) {
    d -= xOffset;
    yOffset2 -= yOffset;

    boolean mirrorX = (mirrorDir & BIT_MIRROR_X) > 0;
    boolean mirrorY = (mirrorDir & BIT_MIRROR_Y) > 0;

    double scaleMap = scale - 1;
    for (int y = 0; y < image.getHeight(); y++) {
        int ySheet = y;
        if (mirrorY)
            ySheet = image.getHeight() - 1 - y;
        int yPixel = (int) (y + yOffset2 + (y * scaleMap) - ((scaleMap * 8) / 2));
        for (int x = 0; x < image.getWidth(); x++) {
            int xPixel = (int) (x + d + (x * scaleMap) - ((scaleMap * 8) / 2));
            int xSheet = x;
            if (mirrorX)
                xSheet = image.getWidth() - 1 - x;

            int col = (colour >> (sheet.pixels[xSheet + ySheet
                    * sheet.width])) & 255;
            if (col < 255) {
                for (int yScale = 0; yScale < scale; yScale++) {
                    if (yPixel + yScale < 0 || yPixel + yScale >= height)
                        continue;
                    for (int xScale = 0; xScale < scale; xScale++) {
                        if (x + d < 0 || x + d >= width)
                            continue;
                        pixels[(xPixel + xScale) + (yPixel + yScale)
                                * width] = col;

                    }
                }
            }
        }
    }
}

Here is one of my poor attempts to call the render method from the Sword Class:

public void render(Screen screen) {

    AffineTransform at = new AffineTransform();
    at.rotate(1, image.getWidth() / 2, image.getHeight() / 2);

    AffineTransformOp op = new AffineTransformOp(at,
        AffineTransformOp.TYPE_BILINEAR);
    image = op.filter(image, null);

    screen.render(this.x, this.y, image, SwordColor, 1, 1.5, sheet);

    hitBox.setLocation((int) this.x, (int) this.y);
    for (Entity entity : level.getEntities()) {
        if (entity instanceof Mob) {
            if (hitBox.intersects(((Mob) entity).hitBox)) {
                // ((Mob) entity).health--;
            }
        }

    }
}

Thank you for any help you can provide, and please feel free to tell me if theres a better way to do this.

Upvotes: 1

Views: 346

Answers (1)

trashgod
trashgod

Reputation: 205875

You can rotate() the image around an anchor point, also seen here in a Graphics2D context. The method concatenates translate(), rotate() and translate() operations, also seen here as explicit transformations.

Addendum: It rotates the image, but how do I save the pixels of the image as an array?

Once you filter() the image, use one of the ImageIO.write() methods to save the resulting RenderedImage, for example.

Upvotes: 3

Related Questions