Java - Image Rotation and more..

Started by
6 comments, last by tariqwalji 13 years, 7 months ago
Hello,

I'm currently developing a simple game with Java. It's a top down shooter prototype where your only objective is to kill everyone who appears on the screen. Nothing fancy or over complicated, just a simplistic game to sharpen my skills before I move on to C++.

However, I'm facing a lot of trouble in two areas:
1. Rotating sprites
2. Figuring out the player facing direction in relation to the mouse position

The first problem is somewhat simple. I can actually rotate the image using the code snippet below, but it will get really ugly if I rotate it long enough.

    public void rotate(int angle) {        BufferedImage biRotate = new BufferedImage(getHeight(), getWidth(), BufferedImage.TYPE_INT_RGB);        Graphics2D g = biRotate.createGraphics();               g.rotate(Math.toRadians((double)angle), getWidth()/2, getHeight()/2);        g.drawImage(anim.getImage(), 0, 0, null);        g.dispose();        anim.setImage(biRotate);    }


I did some research to see how the Slick engine would engage this matter, but they use LWJGL and not pure Java as I am using right now. I also tried the similar (equal?) method of using AffineTransform and the results were pretty much the same. So, anyone would recommend another approach?

Also, I thought about creating a spritesheet (tilemap) with some of the rotated sprites in it. This seems unnecessary and would result in LOTS of sprites for every character of the game, spaceship or any other creature I might add later. However, I'm new to Game Development in general and would like to hear your opinions.

Another option would be pre-computing all the images for every rotation angle and storing it somewhere. This, again, could be an over complicated approach as I would have to control many images.

Thanks,
Felipe Kurkowski

PS.: I'm not a native speaker so I apologize in advance for any grotesque mistake. Please, don't forget to point them out so I can keep on learning the language.
Advertisement
I would make your rotation a member of your class (as you'll probably want it in more places for things like shooting and moving). It should have a range of 0 to 2pi to prevent overflowing if you go in the same direction a lot. Then you could handle the visual rotation as part of your draw code.

I'm kind of confused about what you mean by "Really Ugly." can you elaborate on what exactly it does? or take a screenshot perhaps.
Hello.

Yeah, you're right, I was just trying the method before adding it to the respective class. Anyway, what I meant by "really ugly" was that the image will lose quality after I rotate it. This probably occurs because the rotate function of the Graphics class is manipulating the pixels directly. I've uploaded one simple sprite image showing its original state and what happens when I rotate it:

rotation


Any ideas?
Quote:Original post by kurkowski
    public void rotate(int angle) {        BufferedImage biRotate = new BufferedImage(getHeight(), getWidth(), BufferedImage.TYPE_INT_RGB);        Graphics2D g = biRotate.createGraphics();               g.rotate(Math.toRadians((double)angle), getWidth()/2, getHeight()/2);        g.drawImage(anim.getImage(), 0, 0, null);        g.dispose();        anim.setImage(biRotate);    }

You're rotating the image and then discarding the original image and replacing it with the rotated version. And with each rotation you loose quality so eventually it will look terrible.

Keep the original image unchanged at all times and just draw it at different angles as needed. Eg.

public void draw(Graphics2D g){  g.rotate(angle);  g.draw(originalImage);}
The problem is that doing this you're not only rotating the sprite you want, but the whole image (or all the sprites that were drawn before the one calling the draw methodo). Also, if multiple sprites are rotating, the screen will go on a crazy wirlwind.

I will take a deep look at this later, thanks for all your help so far. Keep the suggestions coming! :)
Quote:Original post by kurkowski
The problem is that doing this you're not only rotating the sprite you want, but the whole image (or all the sprites that were drawn before the one calling the draw methodo). Also, if multiple sprites are rotating, the screen will go on a crazy wirlwind.

Ah, you're not resetting the state correctly then. Either use rotate() with the negative angle, or use getTransform/setTransform to restore the transform to how it was before you rotated it.
Yeah,

I was just coming here to post that I've found the solution (and it's exactly what you said). Anyway, I'm actually creating a copy of the graphics context to accomplish the same thing. The code below shows a solution if anyone ever faces some similar problem.

 public void draw(Graphics2D g) {        Graphics2D g2d = (Graphics2D)g.create();        g2d.rotate(Math.toRadians(rotation), (int)px+getWidth()/2, (int)py+getHeight()/2);        g2d.drawImage(anim.getImage(), (int)px, (int)py, null);        g2d.dispose();    }


Alternatively, you can just manipulate the original graphics context, as OrangyTang said. The final code would be something like this:

 public void draw(Graphics2D g) {        g.rotate(Math.toRadians(rotation), (int)px+getWidth()/2, (int)py+getHeight()/2);        g.drawImage(anim.getImage(), (int)px, (int)py, null);        g.rotate(-Math.toRadians(rotation), (int)px+getWidth()/2, (int)py+getHeight()/2);    }

Wouldn't constantly creating and disposing of your graphics object be inefficient performance wise especially if you are doing it every frame?

I think using a single Graphics2D is probably a better option in the long run (correct me if I'm wrong).

This topic is closed to new replies.

Advertisement