BobieBobie Posted July 27, 2018 Share Posted July 27, 2018 Good day. I need help with making a smooth animation. But first some entry information. I am trying to smoothly move rectangle from left to right. A pretty simple task I thought: use RenderGameOverlayEvent and redraw rectangle every tick. But animation looks pretty ugly, not smooth at all. I did research for 2 days and found something called "partialTicks". @diesieben07 wrote that this can be used to create smooth animations. But I ran into a problem. Here is a formula that @diesieben07 has mentioned: Quote actualValue = previousTickValue + (currentValue - lastTickValue) * partialTicks What's the problem? Maybe I do not understand something, but as I can see "actualValue" will always be 0 because the initial value is 0F and there is no next value. It is hard to explain, but I want to apply my code with comments. NOTE: I have already registered my events in the main class. Private Gist link: GitHub Gist URL Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 1 minute ago, diesieben07 said: You need to store two values: current and lastTick. Every tick (not frame, so 20 times a second regardless of framerate, this makes the animation run at a constant speed) you copy current to lastTick and then compute the next value and store that in current. Every frame you use the formula actual = lastTick + (current - lastTick) * partialTicks to compute the position you actually render at. This way you will get a smooth animation which still runs at a constant speed, regardless of framerate. Ok, I got it, but here is the thing: when I am starting to draw, there is no last tick, cause it only started to draw, I believe you can understand me. What shell I do? Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Wait wait, I think I got it. I need to test it! Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 @diesieben07, I got the logic, but imagine that current and lastTick get 0, so that accordingly to the formula actual = 0 + (0 - 0) * 0.xxxxx always equals zero. So current value will be 0. Next time it will repeat, again and again. Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 (edited) Am I on the right way?: private float current = 1, lastTick = 1; // "1" is wrong, cause it will lead to 0. It is obvious. /*....*/ this.lastTick = this.current; this.current = this.lerp(partialTicks); this.currentNotification.draw(this.current); /*....*/ private float lerp(float partialTicks) { return this.lastTick + (this.current - this.lastTick) * partialTicks; } Edited July 27, 2018 by BobieBobie Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 OK, I am a bit closer. You said 8 minutes ago, diesieben07 said: Then every tick you copy current to lastTick How can I get every tick? As far as I know RenderGameOverlayEvent is called every FRAME, right? So how can I manage to get every TICK? Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Did everything you wrote: I am updating current every tick and rendering every frame. I logged the offset to the console and noticed that offset is not equal. I mean this: Spoiler [13:52:56] [Client thread/INFO] [Notifications Mod]: Offset: 0.0 [13:52:56] [Client thread/INFO] [Notifications Mod]: Offset: 3.6461377 [13:52:56] [Client thread/INFO] [Notifications Mod]: Offset: 15.162073 [13:52:57] [Client thread/INFO] [Notifications Mod]: Offset: 20.078074 [13:52:57] [Client thread/INFO] [Notifications Mod]: Offset: 24.206429 [13:52:57] [Client thread/INFO] [Notifications Mod]: Offset: 28.769346 [13:52:57] [Client thread/INFO] [Notifications Mod]: Offset: 41.525272 [13:52:58] [Client thread/INFO] [Notifications Mod]: Offset: 47.11528 [13:52:58] [Client thread/INFO] [Notifications Mod]: Offset: 52.34848 [13:52:58] [Client thread/INFO] [Notifications Mod]: Offset: 57.0762 [13:52:58] [Client thread/INFO] [Notifications Mod]: Offset: 61.14977 [13:52:58] [Client thread/INFO] [Notifications Mod]: Offset: 66.20457 Here is an updated code: Every RenderGameOverlayEvent.Post: float actualValue = this.lastTick + (this.current - this.lastTick) * partialTicks; this.currentNotification.draw(actualValue); ClientTickEvent: @SubscribeEvent public void onClientTick(TickEvent.ClientTickEvent event) { if (event.phase != TickEvent.Phase.END) return; NotificationsMod.NMANAGER.updateCurrent(); } updateCurrent method: public void updateCurrent() { if (this.currentNotification == null) return; this.lastTick = this.current; this.current += 2F; // Bigger number - faster animation } Even if I do this.current++; animation/offset are not "pretty". Is that normal? Or am I stupid? Quote Link to comment Share on other sites More sharing options...
Cadiboo Posted July 27, 2018 Share Posted July 27, 2018 (edited) have a look at this, https://github.com/Cadiboo/WIPTech/blob/d5504c15d23c66b220064c93ce8fa27c3c457fd0/src/main/java/cadiboo/wiptech/util/Utils.java#L336-L389 It might not be exactly what your looking for, but its 99% perfect and I spent a lot of time on it so I can say that it works very well Sorry, read the post wrong. Its probably only about 20% what you want but its still useful Edited July 27, 2018 by Cadiboo oops Quote About Me Spoiler My Discord - Cadiboo#8887 My Website - Cadiboo.github.io My Mods - Cadiboo.github.io/projects My Tutorials - Cadiboo.github.io/tutorials Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support. When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible. Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme) Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Ok. Imagine drawing a rectangle with built-in drawRect function from Gui class. I am trying to move it SMOOTHLY across the screen. To be more simple: have you ever seen Windows 10 Notifications, that appear from the right bottom side of the screen? Thats what I am trying to recreate. Now it is moving "unstable", not smooth. Maybe I need to change incrementation of current value to much smaller value, but if I will do that - the speed of animation will be VEEERY slow. Reminding Windows 10 notification. Fast and smooth. Offset? That is a number which represents how far will the rectangle move on the next frame. Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 https://gist.github.com/BobieBobie/a9b53635845f661bb428834c5a4e25f0 Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 I will post a video as soon as possible. Quote Link to comment Share on other sites More sharing options...
jabelar Posted July 27, 2018 Share Posted July 27, 2018 (edited) EDIT: Made a correction based on diesieben07's comment. The reason you're confused is that your code is called every render frame, not every tick. Instead you must handle both ticks and renders. The partial ticks helps you convert and synchronize between them. This is how I would name the fields in my equation to make it clearer: currentFramePos = previousTickPos + (currentTickPos - previousTickPos) * partialTicks Then the steps would be as follows: 1) Start by initializing all of the position fields to the starting position. Don't intialize partialTicks as that is a parameter you'll get from the render event. 2) In a tick-handling (not a render!) event you would set the previousTickPos to currentTickPos, then add whatever motion you want to currentTickPos. 3) In a render-handling event you would set the currentFramePos using the formula: currentFramePos = previousTickPos + (currentTickPos - previousTickPos) * partialTicks The reason you do all this is that you need to draw in render events but you need to set the motion speed in a tick event, so you need to handle both ticks and renders and use partialTicks to convert. Edited July 28, 2018 by jabelar Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/ Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Captured two videos for you. First one is mine, second one shows desired version. P.S. Look only on the top left corner, it contains "notification". https://www.dropbox.com/s/kuh50e4tvnqn1kg/my notif.mp4?dl=0 https://www.dropbox.com/s/xle16vgqqjvz4kn/desired one.mp4?dl=0 Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 P.S.S In my version I have disabled restrictions on movement, so you can easily notice lagging animation. Quote Link to comment Share on other sites More sharing options...
Draco18s Posted July 27, 2018 Share Posted July 27, 2018 So your problem right now is that it starts moving and never stops? Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given. Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Of course no. Compare both animations. Mine is laggy, not smooth. And the other one is so smooth. No lagging at all. Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted July 27, 2018 Share Posted July 27, 2018 1 hour ago, BobieBobie said: Of course no. Compare both animations. Mine is laggy, not smooth. And the other one is so smooth. No lagging at all. How is your FPS? And the world TPS should be 20, is it? Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Just now, Animefan8888 said: How is your FPS? And the world TPS should be 20, is it? On the first, weak machine around 20 frames. On another around 70. Both have the same issue. And I can notice why. PartialTicks are unequal, so that xOffset is unstable, which causes jumping animation. Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted July 27, 2018 Share Posted July 27, 2018 16 minutes ago, BobieBobie said: PartialTicks are unequal, so that xOffset is unstable, which causes jumping animation. Partial ticks is just a float value that is updated every frame to determine how much time is left between the last tick and the next tick on a scale of 0-1. It should only be unstable if your FPS or TPS is unstable. Have you tried incrementing by 1 instead of 2 and seeing how that functions. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Just now, Animefan8888 said: Partial ticks is just a float value that is updated every frame to determine how much time is left between the last tick and the next tick on a scale of 0-1. It should only be unstable if your FPS or TPS is unstable. Have you tried incrementing by 1 instead of 2 and seeing how that functions. Of course, nothing changed except the speed. Rewatch the second video. I am having lower FPS there (100+ players nearby) and animations are damn smooth. I cannot achieve that. Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted July 27, 2018 Share Posted July 27, 2018 1 hour ago, BobieBobie said: Of course, nothing changed except the speed. Rewatch the second video. I am having lower FPS there (100+ players nearby) and animations are damn smooth. I cannot achieve that. Using just this I can get a smooth animation, and most of this was copied over from your code. Spoiler @EventBusSubscriber public class ForumsTest extends Gui { private static float current, previous; @SubscribeEvent public static void clientTick(ClientTickEvent event) { if (event.phase != Phase.END) return; if (current >= 200) current = 0; previous = current; current += 2; } @SubscribeEvent public static void renderOverlay(RenderGameOverlayEvent.Post event) { if (event.getType() != ElementType.CHAT) return; float actual = previous + (current - previous) * event.getPartialTicks(); drawRect((200 * -1) + Math.round(actual), 0, 200 + Math.round(actual), 60, 0xff000000); } } Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 1 hour ago, diesieben07 said: Also stop using 1.7.10. Already moving to 1.10. Quote Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Just now, diesieben07 said: Why 1.10.x? You are moving from one outdated version to another outdated version. I cannot migrate to the latest version, because not all of the required mods currently support newer versions. Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted July 27, 2018 Share Posted July 27, 2018 18 minutes ago, BobieBobie said: I cannot migrate to the latest version, because not all of the required mods currently support newer versions. Doesn't change the fact that, what I did worked from an earlier message. 2 hours ago, Animefan8888 said: Using just this I can get a smooth animation, and most of this was copied over from your code. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
BobieBobie Posted July 27, 2018 Author Share Posted July 27, 2018 Just now, Animefan8888 said: Doesn't change the fact that, what I did worked from an earlier message. Glad to hear that. Tomorrow morning I will test your code on third machine(much better performance) and see if the animation is smooth. Ty again. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.