bcolter
Junior Newbie
|
 |
«
Posted
2009-01-10 17:42:38 » |
|
Hi, This is my first post!
I would like to load an image and control the placement/movement in a JPanel with precision (float). After a gazzilion searches and paging through books it seems that I can only position an image using (int).
Is there a trick I can use... Like somehow attaching the image to a rect, or another image method I can use?
Cheers & Thanks
|
|
|
|
SimonH
|
 |
«
Reply #1 - Posted
2009-01-10 17:49:01 » |
|
The smallest unit for placement is a pixel which is a discrete value (int) but there's nothing to stop you casting a float to an int; 1 2 3 4
| for (float i=0;i<100;i+=0.5f) { g.drawImage(image,(int)i,(int)i,null); } |
|
People make games and games make people
|
|
|
bcolter
Junior Newbie
|
 |
«
Reply #2 - Posted
2009-01-10 17:51:06 » |
|
Indeed... but then I loose the precision. Sorry if this is silly question. ( Hence Newless Clubies)
|
|
|
|
Games published by our own members! Check 'em out!
|
|
cylab
|
 |
«
Reply #3 - Posted
2009-01-10 18:41:37 » |
|
To help us (and probably yourself) to better understand the problem try to answer the following questions:
- What do you want to achieve in your application? - Why would you need to place that image with float coordinates? - What do you expect to gain?
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
bcolter
Junior Newbie
|
 |
«
Reply #4 - Posted
2009-01-10 18:57:57 » |
|
I'm writing a simple app to simulate gravity on an object for a Physics project The problem occurs in the Maths when the ball is at the top of the fall... because I have to cast to (int) for movement, it stalls until the value is greater than 0.5 or less than -0.5... So it just hangs there. Here is the code for the movement of the ball... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| private final long DELAY = 20; private float a = 9.8f; private float t = DELAY / 1000.0f;
public void cycle(){ myBall.setY((int)(myBall.getY() + (t * (myBall.getVY() + a * t)))); myBall.setVY(myBall.getVY() + a * t); if(myBall.getY() > getHeight() - myBall.getRadius() * 2){ myBall.setVY(-myBall.getVY()*myBall.getElast()); }
|
/Edit - Added the variables... note getVY returns a float (myball current velocity)
|
|
|
|
jezek2
|
 |
«
Reply #5 - Posted
2009-01-10 20:14:07 » |
|
You could try TexturePaint and filling a rectangle with it.
|
|
|
|
SimonH
|
 |
«
Reply #6 - Posted
2009-01-10 20:18:45 » |
|
Indeed... but then I loose the precision. Make sure to keep all variables as floats throughout your calculations and only cast to int in the actual drawImage() call. That should sort it!
|
People make games and games make people
|
|
|
bcolter
Junior Newbie
|
 |
«
Reply #7 - Posted
2009-01-10 20:38:25 » |
|
Many many thanks to everyone who replied!
Cheers
|
|
|
|
brackeen
|
 |
«
Reply #8 - Posted
2009-01-10 21:12:51 » |
|
You want to draw an image at sub-pixel locations? I think Project SceneGraph has that built-in. I'm not sure about JavaFX, I saw one demo (the puzzle demo) it looked like some pixel-snapping was going on. For straight Java2D, this method that might work by using transforms: Graphics2D#drawImage(Image, AffineTransform, ImageObserver)You may have to set up some RenderingHints to get it to work correctly (bilinear filtering, etc)
|
|
|
|
Eli Delventhal
|
 |
«
Reply #9 - Posted
2009-01-11 02:18:06 » |
|
Have a look at this: http://www.otcsw.com/planetarysimulator.phpAll the masses, positions, and velocities of the planets are doubles. Then when I draw it I just say g.fillOval(int)x,(int)y,(int)radius*2,(int)radius*2). There is no reason to draw at a sub-pixel level. Your monitor can only show things on a pixel-by-pixel basis; nothing can be drawn in between two pixels. SimonH is right - as long as you keep everything stored as a float or double and then merely draw as int, it will look fine.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
cylab
|
 |
«
Reply #10 - Posted
2009-01-11 11:47:23 » |
|
I think his problem is the visual imperfection of very small position changes, so the ball "hops" to the next pixel from time to time. Either way is to accept this limitation or use subpixel placement, that recalculates the real pixels by multisampling.
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
brackeen
|
 |
«
Reply #11 - Posted
2009-01-11 17:06:30 » |
|
There is no reason to draw at a sub-pixel level. Your monitor can only show things on a pixel-by-pixel basis; nothing can be drawn in between two pixels.
Well.... not exactly. Drawing at sub-pixel level makes anti-aliased images appear to have smoother animation when moving slowly. It can be accomplished with bilinear interpolation. Of course, it makes pixel-art look like crap. Flash has a pixelSnapping on/off property for Bitmap objects. Apple's Core Animation always enables sub-pixel placement. JavaFX, I couldn't find any info about it, but I think Nodes always snap to the nearest pixel.
|
|
|
|
bcolter
Junior Newbie
|
 |
«
Reply #12 - Posted
2009-01-11 17:23:43 » |
|
I used the cast method as suggested by SimonH (gave me the answer in the first post, but I didn't quite grasp it)... 1
| g2.drawImage(myBall.getBall(),(int)myBall.getX(),(int)myBall.getY(),null); |
... and everything works perfectly. Thank you very much, a wonderful first experience on this forum. / happily goes back to coding
|
|
|
|
brackeen
|
 |
«
Reply #13 - Posted
2009-01-11 20:55:39 » |
|
I used the cast method as suggested by SimonH (gave me the answer in the first post, but I didn't quite grasp it)... 1
| g2.drawImage(myBall.getBall(),(int)myBall.getX(),(int)myBall.getY(),null); |
... and everything works perfectly. Thank you very much, a wonderful first experience on this forum. / happily goes back to coding Welcome to java-gaming.org, where someone like myself typically pops into a thread and derails the conversation into something completely different.
|
|
|
|
trembovetski
|
 |
«
Reply #14 - Posted
2009-01-11 22:22:16 » |
|
> I'm not sure about JavaFX
JavaFX uses floats everywhere, and there's no "pixel snapping" for shapes. Try placing a Rectangle on 1.1,1.1 you will see that becomes AA-ed to achieve that.
For Images, there's a hint in the scenegraph to allow subpixel positioning (also depends on filtering mode set in ImageView: ImageView.smooth), but I don't think it's exposed on the FX level right now.
By default non-integer translations for images is off since it's slow on some earlier (1.5) jdks.
Dmitri
|
|
|
|
trembovetski
|
 |
«
Reply #15 - Posted
2009-01-11 22:25:50 » |
|
To answer the original question: use affine transform to place the image with high precision. Also make sure to set bilinear rendering hint (the default is nearest neighbor). But be aware that with earlier jdks (pre-1.6) performance will suck.
Dmitri
|
|
|
|
appel
|
 |
«
Reply #16 - Posted
2009-01-13 02:57:19 » |
|
Could use g.translate(float x, float y) !!! Example: g.translate(myImageX, myImageY); g.drawImage(myImage, 0, 0); g.translate(-myImageX, -myImageY); Thank you thank you! 
|
|
|
|
|
brackeen
|
 |
«
Reply #18 - Posted
2009-01-13 15:05:25 » |
|
> I'm not sure about JavaFX
JavaFX uses floats everywhere, and there's no "pixel snapping" for shapes. Try placing a Rectangle on 1.1,1.1 you will see that becomes AA-ed to achieve that.
For Images, there's a hint in the scenegraph to allow subpixel positioning (also depends on filtering mode set in ImageView: ImageView.smooth), but I don't think it's exposed on the FX level right now.
By default non-integer translations for images is off since it's slow on some earlier (1.5) jdks.
Dmitri
Okay, that explains why I was seeing pixel-snapping on my Mac+Java 1.5 on the puzzle demo. Yup, that "smooth" variable is exposed in ImageView - good to know, thanks Dmitri!
|
|
|
|
|