Slick Forums

Discuss the Slick 2D Library
It is currently Thu Apr 18, 2019 2:17 pm

All times are UTC




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Wed Dec 07, 2011 9:45 am 
Offline

Joined: Tue Dec 06, 2011 7:10 pm
Posts: 5
The centerOfRotation in Image is currently broken.

Code:
   Image img = new Image(400,400);
   img.centerOfRotation(5,5);
   System.out.println("Center is: "+img.getCenterOfRotationX+", "+img.centerOfRotation());

Output:
Center is: 200, 200

The expected output was of course 5,5.

A quick peek in the Image.java revealed this:
Code:
   public float getCenterOfRotationX() {
      init();
      
      return centerX;
   }


Where init() in turn sets centerX to width/2.

After looking at the code for a while I get the impression that someone added init() to pretty much every method at some point, possibly to fix some other bug. I hope I am not stepping on any toes here, but this honestly looks very quick and dirty. Would be nice if the bug was fixed and even nicer if Image got rid of 15 calls to init or so.


Top
 Profile  
 
PostPosted: Wed Dec 07, 2011 11:39 am 
And why would the expected output be 5,5? An image of width and height of 400, would have a center at 200,200.


Top
  
 
PostPosted: Wed Dec 07, 2011 12:09 pm 
Offline

Joined: Tue Dec 06, 2011 7:10 pm
Posts: 5
Oh. A little typo there. The line that says "centerOfRotation(5,5)" should really be saying "setCenterOfRotation(5,5)". That is also what I expect it to return or it wouldn't be much point being able to set it at all.


Top
 Profile  
 
PostPosted: Fri Dec 09, 2011 8:00 am 
Offline
Game Developer
User avatar

Joined: Thu Mar 03, 2011 6:22 pm
Posts: 534
the init calls are actual pretty neat and also it's just a call which will be skipped if the image is initialized ;) Try getting a value from your object, and then setting the center so you know that init was called at least once and will not be invoked again (unless you have some fancy reinit code that is :))

Setting the center is okay, maybe there is just an init call missing before setting them to ensure it's initialized.

_________________
Current Projects:
Image Mr. Hat I
Image Vegan Vs. Zombies
Projects:
RadicalFish Engine - Build on top of Slick2D, Ideas, Bugs? Open an Issue ticket!


Top
 Profile  
 
PostPosted: Mon Dec 12, 2011 1:52 pm 
Offline

Joined: Tue Dec 06, 2011 7:10 pm
Posts: 5
Right you are. Init returns when already inited. Unfortunately setCenterOfRotation gets a bit unreliable when things aren't already inited.
A call to init() at the top of setCenterOfRotation() would solve it!
Code:
   public void setCenterOfRotation(float x, float y) {
      init();//PLEASE SOMEONE ADD THIS LINE!
      centerX = x;
      centerY = y;
   }


Top
 Profile  
 
PostPosted: Sat Dec 17, 2011 6:35 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
Since we're on the subject, the center is also cast to an int which causes subtle issues with scaling and rotation. Because of that I've been avoiding Image's centerX/centerY altogether.

Code:
protected Image(Image other) {
      this.width = other.getWidth();
      this.height = other.getHeight();
      this.texture = other.texture;
      this.textureWidth = other.textureWidth;
      this.textureHeight = other.textureHeight;
      this.ref = other.ref;
      this.textureOffsetX = other.textureOffsetX;
      this.textureOffsetY = other.textureOffsetY;
   
      centerX = width / 2; <---- should be width / 2.0f
      centerY = height / 2; <---- should be height / 2.0f
      inited = true;
}


Same goes for init(), getScaledCopy() and getSubImage()


Top
 Profile  
 
PostPosted: Sat Dec 17, 2011 7:00 pm 
Offline
Game Developer

Joined: Sun Nov 12, 2006 11:18 pm
Posts: 890
Location: Germany
davedes wrote:
Since we're on the subject, the center is also cast to an int which causes subtle issues with scaling and rotation. Because of that I've been avoiding Image's centerX/centerY altogether.

Code:
   
      centerX = width / 2; <---- should be width / 2.0f
      centerY = height / 2; <---- should be height / 2.0f




That's not true.
Do something like:
Code:
float test = 32.4f / 2;

in some test method. test will have a float value of 16.2.

Java always takes the more precise operand for the result of the operation. So in this case the int 2 will be cast automatically to a float 2.0f.
So centerX and centerY will have proper float values. At least for the two lines you've mentioned.

_________________
Right Angle Games | Marte Engine
Back to the past | Star Cleaner | SpiderTrap


Top
 Profile  
 
PostPosted: Sun Dec 18, 2011 6:35 am 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
Look again -- Image stores width and height as an integer.

Example:
Code:
int width = 5;
float f = width / 2;
System.out.println(f); --> returns 2 instead of 2.5


Top
 Profile  
 
PostPosted: Sun Dec 18, 2011 10:43 am 
Offline
Game Developer

Joined: Sun Nov 12, 2006 11:18 pm
Posts: 890
Location: Germany
Aaah, you're right, davedes. Sorry, I missed that (width and height being int). Then your suggestions are of course all valid.

Seems Image needs a bit of an overhaul...

_________________
Right Angle Games | Marte Engine
Back to the past | Star Cleaner | SpiderTrap


Top
 Profile  
 
PostPosted: Sun Mar 04, 2012 10:19 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
Fixed in the development branch. Will be included in the main branch on next merge.


Top
 Profile  
 
PostPosted: Tue Mar 06, 2012 9:51 pm 
Offline
User avatar

Joined: Tue May 03, 2011 7:45 pm
Posts: 13
Location: Poland, Cracow
Didn't want to make a new thread, but... Center of rotation doesn't use the image scale when drawing, so it's off when drawing a scaled image.


Top
 Profile  
 
PostPosted: Tue Mar 06, 2012 10:56 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
Added a fix in dev branch.

Now when you call the following, the centerX/centerY will be scaled accordingly:
Code:
draw(x, y, width, height, filter)
draw(x, y, width, height)
draw(x, y, scale)
draw(x, y, scale, filter)
drawFlash(x, y, width, height, filter)
drawFlash(x, y, width, height)
draw(x, y, x2, y2, srcx, srcy, srcx2, srcy2, filter) --> where the scale is calculated using (x2-x, y2-y) as the desired width/height


I've left drawWarped and drawSheared untouched as scaling the center in that situation might be undesirable.

getScaledCopy now scales the centerX/Y accordingly, as well, to produce consistent results with the draw functions.

On a side note:
IMO Image.copy() should also copy rotation, alpha, corner colors (shallow copy, so same Color objects?), etc. However I don't think these should be copied with getSubImage, since the user expects the sub-image to act like a "fresh" image if that makes sense. Let me know what you think about that.


Top
 Profile  
 
PostPosted: Wed Mar 07, 2012 8:11 am 
Offline
Game Developer
User avatar

Joined: Thu Mar 03, 2011 6:22 pm
Posts: 534
Yepp, sub image should stay like it is. This is how all my ressource managning relies on :)

_________________
Current Projects:
Image Mr. Hat I
Image Vegan Vs. Zombies
Projects:
RadicalFish Engine - Build on top of Slick2D, Ideas, Bugs? Open an Issue ticket!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group