Is there a way to make the rotation of an image smooth when controlling with keys in keyboard?
In this code, there are two images rotating on the screen. The first image can be rotated by pressing the "D" and "A" key while the second image is automatically rotated. In this example, the second image is smoothly rotating while the first image has a jerky feel to its rotation.
I don't think the fact that you're typing on the keyboard to start the rotation has anything to do with the problem. If you display a graphic, and then later rotate it by 90 degrees and display it again, then what you see is going to change instantly from the original image to the 90-degree-rotated image. If you want to see all of the intermediate stages of the rotation, then it's up to you to display those intermediate stages. So rotate the image by 1 degree (for example), display it, wait a bit, rotate the image by 1 degree again, display again, wait a bit again, repeat until the whole 90-degree rotation is finished.
You would need to tailor the "1 degree" parameter and the "a bit" parameter to match what you want for the smoothness and the speed of the rotation.
There are two possible causes for the jerkiness that I can think of:
one is that Java is too slow to do the painting within the 20 milliseconds from the timer, and thus what you see might be incomplete drawings.
However, that is not the case here. A weakness in your code is the relation between how many times keyPressed is invoked, and how many times paint is executed.
If you add a counter to the paint method, and another counter to the keyPressed method, and print these values in the paint method, you will see a diverge of the two.
So, adjust your code such that whenever paint is invoked, the variables 'rotation' and 'rotationTwo' are updated only once since the last repaint.
Another way is to do the updating of the graphics in a separate Thread, and when the updating is finished, invoke repaint on the panel, or use the timer. This way, you give the updating process the full 20 ms (or whatever your timer is set to).
Lastly: follow Pauls advice and try different values of your parameters (make them variables in your code, so that you can adjust them with ease).
posted 2 months ago
I fixed it. First, I observed that the rotation increment in keylistener was slower than the rotation increment in the timer. So, I created a boolean flag that sets to true if the key is pressed and false if the key is released. Then, I do the rotation of the first image in the timer. If the boolean flag is true, then the first image rotates as long as the boolean flag is true and stop if false. I only apply my solution on the right rotation, though, it can be easily applied on the left rotation. This solution is not that elegant though. Is there another alternative to this solution like a mathematical formula that produces the same result?
Elya Matsunomi wrote:So, I created a boolean flag that sets to true if the key is pressed and false if the key is released. Then, I do the rotation of the first image in the timer. If the boolean flag is true, then the first image rotates as long as the boolean flag is true and stop if false.
Another solution would be to start the timer as soon as the key is pressed, and stop the timer as soon as it's released. In this case probably "starting" the timer would involve creating a new Timer and starting it, and "stopping" the timer would involve stopping that Timer -- I don't remember the method to do that but maybe it's "cancel()" or something like that.
Paul Clapham wrote:Another solution would be to start the timer as soon as the key is pressed, and stop the timer as soon as it's released. (...)
There are two objects rotating, one continously, so you need a Timer anyway. What you can do is having an ActionListener that handles the keyPressed event, and adding or removing that AL to or from the timer in the keyPressed method.. See the API for the Swing Timer. But that is more complicated than OP's solution, although OP's solution can be simplified.
You can't have everything. Where would you put it?
global solutions you can do at home or in your backyard