Results 1 to 15 of 15
- 12-21-2010, 07:27 PM #1
Member
- Join Date
- Dec 2010
- Posts
- 17
- Rep Power
- 0
Animation randomly changing speed problem - Please Help!
Hi, Can somebody please explain to me why my java animation of a simple oval bouncing about the screen randomly changes speed? Sometimes it goes normal, sometimes slow. Even though I had a specific speed set. I have tried using a Timer and actionListener and also a Thread with the run method. The same thing happens.
Is it because the time is never precise so sometimes the code might execute sooner or later than it should?
Please I need to understand why it just randomly changes speed.
- 12-21-2010, 07:43 PM #2
Let's test out my psychic ability- do you have animation logic in your paintComponent() method?
If you want help with your code, we'll have to see your code.
Make sure it's in SSCCE form, and don't forget the code tags.
- 12-21-2010, 07:53 PM #3
Member
- Join Date
- Dec 2010
- Posts
- 17
- Rep Power
- 0
Java Code:public AnimationWithThreads(){ x=0; y=0; } public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.fillRect(x, y, 40, 40); } public void move(){ if(x<0||x>750){ dx = -dx; } if(y<0||y>520){ dy = -dy; } x += dx; y += dy; } public void run() { while (true) { move(); repaint(); try { Thread.sleep(10); } catch (InterruptedException ex) { // } } } }I have no idea why it's happening, but the funny thing is, sometimes it will work perfectly for a couple of minutes, No matter how many times I run it. I was thinking it may be something to do with NetBeans but then I tried it in textpad and it did the same. Sometimes it's perfect, other times it's not.Java Code:public class Main extends JFrame { public static void main(String[] args){ Main m = new Main(); AnimationWithThreads a = new AnimationWithThreads(); Thread myThread = new Thread(a); m.add(a); myThread.start(); m.setSize(800,600); m.setTitle("HEllo"); m.setDefaultCloseOperation(EXIT_ON_CLOSE); m.setVisible(true); } }
This does the same thing even if I use a Timer and actionListener.
I also did a pong game and the same problem was happening, this is my paint and actionperformed methods from that game
I can't see the small bit of logic if(ingame) doing much, but should I just not have any logic at all?Java Code:public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; drawGame(g2d); g.dispose(); g2d.dispose(); } public void actionPerformed(ActionEvent e) { if(inGame){ checkCollisions(); players.move(); ball.move(); repaint(); } }Last edited by andyman99008; 12-21-2010 at 08:02 PM.
-
Please double check the code that you've posted because it doesn't compile and thus isn't a true SSCCE. YOur animation class is missing stuff.
- 12-21-2010, 08:11 PM #5
Member
- Join Date
- Dec 2010
- Posts
- 17
- Rep Power
- 0
Ok, here is the Animation class with imports
Then the main method I already posted works with this, they are both in separate files.Java Code:import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JPanel; public class AnimationWithThreads extends JPanel implements Runnable { private int x,y,dx=2,dy=2; public AnimationWithThreads(){ x=0; y=0; } public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.fillOval(x, y, 40, 40); } public void move(){ if(x<0||x>750){ dx = -dx; } if(y<0||y>520){ dy = -dy; } x += dx; y += dy; } public void run() { while (true) { move(); repaint(); try { Thread.sleep(5); } catch (InterruptedException ex) { // } } } }
The other code I posted was just showing that I didn't have any logic inside the paint method but I still get the problem.(it was part of another program)Last edited by andyman99008; 12-21-2010 at 08:18 PM.
- 12-21-2010, 08:37 PM #6
Member
- Join Date
- Dec 2010
- Posts
- 17
- Rep Power
- 0
I have no idea how I can fulfill the last part of the SSCCE, How can I show an example of my problem? I have no idea what is causing it.
-
One problem I see is that your speed is fully dependent on the time period of a Thread.sleep, and the accuracy of this is not guaranteed. I'm no animation expert, but you are probably better off having your speed be dependent on the system clock so that if your sleep period is longer or shorter than usual, your animation will take that into account. Myself I'd use a Swing Timer, but to demo with your threading:
Java Code:import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.*; public class HisAnimationMain extends JFrame { public static void main(String[] args) { HisAnimationMain m = new HisAnimationMain(); AnimationWithThreads a = new AnimationWithThreads(); Thread myThread = new Thread(a); m.add(a); myThread.start(); m.setSize(800, 600); m.setTitle("Hello"); m.setDefaultCloseOperation(EXIT_ON_CLOSE); m.setVisible(true); } } class AnimationWithThreads extends JPanel implements Runnable { private static final int SIDE = 40; private static final long SLEEP_DELAY = 5; private static final double SPEED_PER_MILI = 0.2; private static final int PAD = 40; private double x; private double y; private double dx = 1; private double dy = 1; private long latestTime; public AnimationWithThreads() { x = 0; y = 0; latestTime = System.currentTimeMillis(); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.fillRect((int)x, (int)y, SIDE, SIDE); } public void move() { if (x < 0) { dx = Math.abs(dx); } else if (x + SIDE > getWidth()) { dx = -Math.abs(dx); } if (y < 0) { dy = Math.abs(dy); } else if (y + SIDE > getHeight()) { dy = -Math.abs(dy); } long newTime = System.currentTimeMillis(); int deltaTime = (int) (newTime - latestTime); latestTime = newTime; x += dx * SPEED_PER_MILI * deltaTime; y += dy * SPEED_PER_MILI * deltaTime; } public void run() { while (true) { repaint((int)x - PAD, (int)y - PAD, SIDE + 2*PAD, SIDE + 2*PAD); move(); repaint((int)x, (int)y, SIDE, SIDE); try { Thread.sleep(SLEEP_DELAY); } catch (InterruptedException ex) { // } } } }
- 12-21-2010, 09:04 PM #8
Member
- Join Date
- Dec 2010
- Posts
- 17
- Rep Power
- 0
Ok, Couple of questions,
I don't really understand whats happening here, what is the latestTime? I can see that everytime this runs, latestTime will increase but I don't understand it. When newTIme gets the currentTime in milliseconds what does that mean? Say its, 21:00pm, how does it convert to milliseconds?Java Code:long newTime = System.currentTimeMillis(); int deltaTime = (int) (newTime - latestTime); latestTime = newTime; x += dx * SPEED_PER_MILI * deltaTime; y += dy * SPEED_PER_MILI * deltaTime;
I also don't know what you mean by delta , I have heard it before in maths but I forget what it is.
Where did you get the SPEED_PER_MILI from? Is it just an arbitrary number less than 1?
I think the whole time calculations is confusing me the most. Would you be able to right it out in pseudo format? or in logical english or something?
Another thing I don't understand(Because I have never seen it), is in the run method.
What do the calculations inside the repaint parentheses do? Also, why do you have 2 repaints()?
Sorry for all the questions but I think if I can just understand the time thing, it could be much clearer.
Also, Thanks for taking the time to help me.
-
You can't control how many milliseconds there will be in each time slice, you can only suggest it, either with a Timer time delay or a Thread sleep parameter, and so your animation must take this into account. In your animation above, your time slice is 10 msec, and you're having the sprite move 2 pixels (or whatever the unit is), each 10 msec. I did the division of pixels divided by msecs, and turned this into a double constant of 0.2. So regardless of how many msecs pass, I want my sprite to move 0.2 pixels per mSec. So if 10 mSecs pass, then my sprite will move 2, if 15 pass, it will move 3. I get the time slice amount by calling System.currentTimeMillis() and subtracting the result from the last time that I called it. That's all I'm doing there.
- 12-21-2010, 09:49 PM #10
Member
- Join Date
- Dec 2010
- Posts
- 17
- Rep Power
- 0
Ah I see now about how that code works. But I still don't know why you have 2 repaints() and why they have paramaters?
-
- 12-21-2010, 10:10 PM #12
Member
- Join Date
- Dec 2010
- Posts
- 17
- Rep Power
- 0
Oh, so just calling repaint() repaints the entire frame?
So the paramaters specify the exact position on the screen to repaint?
So, for testing purposes, if I set 2 of the numbers in the repaint(...) to 0,0(where the square starts) it will only repaint that so I will end up with a black smudge moving down my screen?
Again, thanks alot for your help
-
Here's a better version of the run method, one that stores the old x and y positions, calls move, and then calls two repaints, one to erase the old sprite and the other to draw the new sprite (they'll likely overlap, so a small spot will be drawn twice, but that doesn't matter much):
Java Code:public void run() { while (true) { int oldX = (int)x; int oldY = (int)y; move(); // repaint a rectangle somewhat bigger than the previous position of sprite // this is to erase old image repaint(oldX - PAD, oldY - PAD, SIDE + 2*PAD, SIDE + 2*PAD); // repaint new position of sprite repaint((int)x, (int)y, SIDE, SIDE); try { Thread.sleep(SLEEP_DELAY); } catch (InterruptedException ex) {} } }
- 12-21-2010, 10:43 PM #14
Member
- Join Date
- Dec 2010
- Posts
- 17
- Rep Power
- 0
wow, I can only say thanks so many times...but seriously, thanks for all your help. I feel like I should be paying you!(But I wont :D)
There is only 1 last question I need to ask, so I understand everything, and that is:
If I was working on a game, with different animations happening at the same time, would it be better(faster) to repaint() the whole screen, or have methods to repaint(...) each animation at there specific locations?
Thanks alot!
-
Similar Threads
-
Changing binding when changing the underlying model object
By ChrisNY in forum NetBeansReplies: 0Last Post: 08-14-2010, 10:09 AM -
Problem with my animation applet
By cblue in forum Java 2DReplies: 0Last Post: 08-24-2009, 04:24 PM -
Animation Delay - Thread problem
By wererabit in forum Advanced JavaReplies: 3Last Post: 04-10-2009, 10:35 PM -
Persistence problem when changing type to java.sql.Time
By Inks in forum JDBCReplies: 0Last Post: 03-08-2009, 01:52 PM -
same animation speed regardless of how power full the PC is.
By Mba7eth in forum New To JavaReplies: 3Last Post: 09-16-2008, 11:55 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks