I want to make an animation of an ellipse growing and shrinking in length. The animation should be continuous, so I want the length of the ellipse to grow to a certain point and then shrink back to its original for as long as the program is running. I already have the animation part of the program done, and I’ve come up with a solution to my problem that doesn’t entirely work. What’s happens is that ellipse expands to roughly the edge of the screen and then snaps back to length of 200 pixels, which also happens to be the width of the ellipse. I didn’t some debugging and found that the value I used to adjust the length was incrementing smoothly, but for whatever reason the animation didn’t reflect that.
Here’s my code
import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Canvas; import javax.swing.JFrame; import java.awt.geom.Ellipse2D; public class Drawing extends Canvas { public static final int FPS = 30; int angle=0; int eccent=0; int x=1; public static void main(String[] args) { JFrame frame = new JFrame("My Drawing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Drawing canvas = new Drawing(); canvas.setSize(400,400); frame.add(canvas); frame.setVisible(true); //Animation loop while(true) { canvas.repaint(); try { Thread.sleep(1000/FPS);} catch(Exception e){} } } public void paint(Graphics g){ Image i=createImage(this.getWidth(), this.getHeight()); Graphics2D g2D=(Graphics2D)i.getGraphics(); g2D.rotate(Math.toRadians(angle), this.getWidth()/2, this.getHeight()/2); g2D.setColor(Color.BLUE); if((eccent<50)&&(x==1)) { eccent++; System.out.println(eccent); g2D.draw(new Ellipse2D.Float(100,150,200,(250+eccent))); if(eccent==50) { x=0; } } else if((eccent>0)&&(x==0)) { eccent--; System.out.println(eccent); g2D.draw(new Ellipse2D.Float(100,150,200,(250-eccent))); if(eccent==0) { x=1; } } g.drawImage(i,0,0,null); } }
Advertisement
Answer
To solve the issue you can change 250-eccent
in your else if
block to 250+eccent
or vice versa depending on the behaviour you want.
The difference mentioned above is the reason for your sudden jump in size. Let’s say for example that your ellipse is correctly growing in size to the point where eccent is 49 so the code entered the first if
block and eccent will be incremented by 1 to become 50, this will create an ellipse with size 250+50
(300 total) then x gets set to 0 because of if(eccent==50){x=0;}
.
So the next time the ellipse is painted x will be 0 so the code will enter the else if
block, and eccent will be decreased by 1 to become 49, and the ellipse size will be 250-49 (201 total).
Notice the jump from 300 to 201 (99 difference) from one loop to the other. This is your issue using a – instead of a + in the else if
block. To solve it simply use 250+eccent
inside both the if
and else if
code blocks.
Also, as noted by others in comments, you should never use Thread.sleep(...)
in the paint method which runs on the GUI/EDT thread, because that will make the application unresponsive to user input and it will not be able to be closed with the normal methods, and the operating system may view it as a frozen/unresponsive application which can cause a prompt in some circumstances. The better solution is to use a timer or another thread to manage the animation.