This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
クデル's profile picture

Animations

Started by クデル, 09 July 2015 - 05:57 AM
クデル #1
Posted 09 July 2015 - 07:57 AM
I have noticed animations in various operating systems such as OneOS and NinOS, and I was just wondering exactly how these are accomplished? Is it just a buffer being redrawn in a different location?
InDieTasten #2
Posted 09 July 2015 - 08:28 AM
Minor hint(as I don't know how they handle this either): Performance is one of the key drawbacks when it comes to animations in CC, as the rendering does consume quite a fuck of time. So in order to create animations that are smooth, you want to have as few calls to write as possible. There are several APIs for accomplishing that(only writing things that have changed) out there. The surface api is one of the most commonly used, when not using a custom routine for that.

It claims to use the least amount of drawing calls possible, although I don't know if thats correct or confirmed. I'm pretty sure there are still some things you could do to reduce it even further. I don't know the techniques used by the api
MKlegoman357 #3
Posted 09 July 2015 - 08:47 AM
Such OSes are usually written with OOP in mind to help reduce the code and complexity of it. When an animation happens certain objects that need to be animated just get their position, color, dimensions changed gradually over time, most of the time with the help of "timer" events, rather than using sleep() directly, as the OS has to be operable while performing animations.
クデル #4
Posted 09 July 2015 - 09:39 AM
Minor hint(as I don't know how they handle this either): Performance is one of the key drawbacks when it comes to animations in CC, as the rendering does consume quite a fuck of time. So in order to create animations that are smooth, you want to have as few calls to write as possible. There are several APIs for accomplishing that(only writing things that have changed) out there. The surface api is one of the most commonly used, when not using a custom routine for that.

It claims to use the least amount of drawing calls possible, although I don't know if thats correct or confirmed. I'm pretty sure there are still some things you could do to reduce it even further. I don't know the techniques used by the api

Thanks, I'll definitely be using the surface api!

Such OSes are usually written with OOP in mind to help reduce the code and complexity of it. When an animation happens certain objects that need to be animated just get their position, color, dimensions changed gradually over time, most of the time with the help of "timer" events, rather than using sleep() directly, as the OS has to be operable while performing animations.

Interesting, I basically just want a menu that slides in from the left, so I think I can just get away with moving each object in question over by a single pixel whenever x time passess.
Grim Reaper #5
Posted 10 July 2015 - 05:00 AM
I'm not one to usually promote myself or my code, but surface doesn't always use the minimum number of writes.

I while ago, I wrote a frame buffer API that minimizes the number of terminal calls used in drawing common content. Now, this is where you have to make a decision: When I say "common content," I mean large portions of similarly colored text/background. For example, most programs that utilize some kind of GUI have backgrounds and boxes and whatnot that is all fairly similarly colored. In these sorts of situations, my API makes quicker work of rendering than does surface. However, in a situation that requires A LOT of different background and text colors, my API can be significantly slower. For example, when I do tests, I have every character on the screen be a random text and background color such that no two characters have the same colors, most of the time. When this happens, surface is definitely quicker.

However, I'd like to stress that this is rarely the case; like I said before, most programs make use of largely similar color combinations across large areas. So, choose wisely :)/>
Bomb Bloke #6
Posted 10 July 2015 - 08:03 AM
One rather simple way of animating is to use a window as a display buffer. The idea is that you set it to "invisible" most of the time, then after drawing each frame, you toggle it to visible - then immediately back again, until such time as you've finished drawing the next frame to it. Repeat as need be.

See, an "invisible" window isn't removed from the screen; it simply won't display any changes you make to it until such time as you make it visible again. As of CC 1.74, redrawing a window (done automatically when you toggle from invisible to visible) takes about the same amount of time as term.clear(), no matter how complex the content it contains.

Prior to that build window redrawing is a lot slower, but the method still helps reduce flicker even if you happen to be using something older.

To add another animation API to the list of suggestions, this one's mine. Primarily for displaying GIFs, you can also use it to display a series of paintutils images. Eg:

os.loadAPI("GIF")

local myAnimation = GIF.buildGIF(paintutils.loadImage("someImage"), paintutils.loadImage("someOtherImage"), etc)

-- Set how long each frame should display for (default is a tenth of a second):
myAnimation[1].delay = 1
myAnimation[2].delay = 0.5
-- etc

-- Do the animation:
GIF.animateGIF(myAnimation)

Every now and then I come back and tweak that API. Currently I feel it needs a way to more readily halt its animations. I suppose I could just make it respect the looping flag GIF files specify.