Hi everyone
I’ve been using Codea a lot over the last two weeks and wanted a way to do really simple animations in games.
I had a few goals in mind for this library:
- Be dead simple to make something flash, bounce, squash, and so on
- Make games feel nicer by having lots of reactive animations for every action
- Allow animations to stack while still allowing user or simulated control over positioning
- Don’t interfere with regular sprite movement
- Be exactly like the regular Codea primitives (ellipse, rect, sprite, text)
- Allow subclassing for more custom behaviour
This library is built on top of tween()
, and I’m considering including it in Codea (1.5.3 maybe). So it will get nice things like documentation and autocompletion.
I’m posting it here first to get your feedback and thoughts on its development. I’ll be maintaining the library on Github so that anyone can fork/contribute to the project.
–
###VIDEO###
–
###GET IT###
Juice Auto Installer (thanks @Briarfox)
http://gist.github.com/TwoLivesLeft/5690562
Edit: tab order should be: juice, juiceobject, juicemover, juicerect/ellipse/sprite/text, Main
Juice Library Source
https://gist.github.com/TwoLivesLeft/5690550
–
###INSTRUCTIONS###
- Paste this file into the Main tab of a new project called “Juice” (make sure you name it exactly)
- Run the project once
- Run it again to finish the installation
–
###JUICE###
Here are some small bits of sample code to demonstrate how it works:
function setup() myRect = juice.rect( WIDTH/2, HEIGHT/2, 70 ) myRect.fill = color( 255, 0, 0 ) end function draw() background(20,20,40) myRect:draw() end function touched(touch) if touch.tapCount == 1 and touch.state == ENDED then myRect:spin( 2 ) end end ``` The basic Codea primitives are mirrored as objects in the juice library, they areobj = juice.rect( x, y, w, h ) obj = juice.ellipse( x, y, w, h ) obj = juice.sprite( name, x, y, w, h ) obj = juice.text( string, x, y ) ``` All juice primitives support the following APIs for quick animation, all arguments are optional (calling with no arguments tries to use some sensible defaults).-- This spins the object "rotations" times obj:spin( rotations, duration, easing, callback ) -- This bounces the object and allows it to hover for "hold" duration -- call1 is called at the top of the bounce -- call2 is called when the bounce finishes obj:bounce( height, hold, call1, call2 ) -- This pulses the object by "amount" for a specified number of "repeats" -- The "hold" value specifies how long to pause at the extremity of the pulse -- call1 is called when the object is fully pulsed -- call2 is called when the object is returned to its original state obj:pulse( amount, repeats, hold, call1, call2 ) -- This squashes the object, pausing for "hold" amount of time -- at the extreme of the squash, duration is the total time of the squash -- call1 and call2 are called during and after the squash obj:squash( amount, hold, duration, call1, call2 ) -- This knocks an object in a direction obj:knock( direction, duration, callback ) -- Flashes the object white a certain number of times obj:flash( hold, repeats, call1, call2 ) -- Fade object out obj:fadeOut( duration, callback ) -- Fade object in obj:fadeIn( duration, callback ) -- Fade object to specific alpha value obj:fadeTo( alpha, duration, callback ) -- Rotate to a specific angle obj:rotateTo( angle, duration, easing, callback ) -- Rotate by an angle obj:rotateBy( angle, duration, easing, callback ) -- Move to a specific position obj:moveTo( pos, duration, easing, callback ) -- Move by a certain amount obj:moveBy( pos, duration, easing, callback ) -- Scale to a specific value -- The amount to scale can be a number or a vec2 -- If a single number is provided then uniform scaling is assumed obj:scaleTo( scale, duration, easing, callback ) -- Scale by a specific value -- The amount to scale can be a number or a vec2 -- If a single number is provided then uniform scaling is assumed obj:scaleBy( scale, duration, easing, callback ) ``` The library has a basic demonstration included. And I've been using this in a game I've been making to add a lot of quick motion and reaction animations to simulated characters. -- ###HOW IT WORKS### The basic design of the library is as follows: `juice.move` This is the basic element of animation, it contains a position (vec2), angle (number) and scale (vec2). Every animation in juice creates a new "move" and animates the move over time. `juice.object` This is the base class for all juice objects. A juice.move object can be applied to a juice.object to modify its state. Every juice.object keeps a list of a currently executing moves, and before drawing applies them all to generate its visible position. `juice.mover` This is a subclass of juice.object that adds all the handy animations to it. `juice.rect`, `juice.ellipse`, `juice.sprite`, and `juice.text` These are subclasses of juice.mover that add initialisation and drawing of Codea primitives.