Lingo: tinyTween parentScript
Table of contents
tinyTween parentScript
This Parentscript tweens objects timebased.
There are two flavours: Passive and Active. In passive mode you initialize the script and call an update command from within a behaviour.
The active mode needs a target sprite, initializes and takes care of the tween by itself, using the actorlist/stepframe. When the tween is done, it destroys itself.
MW
version history
1.3.0 - fixed bug on passive mode #start:01.2.0 - added passive mode
1.1.4 - added bounce en elastic tweens, modified destroy function
1.1.3 - fixed blend bug in shortcuts, added #jojo, added #repeat
1.1.2 - fixed rect bug in shortcuts
1.1.1 - added shorcuts
Passive mode
tinyTween object
tinyTween object
n = script("tinyTween").new(propertyList)tween properties in Passive mode
- start (int/float/point/vector/rect)
- end (int/float/point/vector/rect)
- duration (int: tweenDuration in milliseconds)
- delay (int: delay in milliseconds)
- repeat (int: times a tween is repeated, use 0 or "inf" for infinite repeat)
- jojo (int: 1/0, makes the tween go back-and-forth)
- tweenmode (string: see tweenModes)
Example
tinyTween in a behaviour
property pTween
on beginSprite me
pTween = script("tinyTween").new([#start:point(100,100), #end:point(600,200), #duration:4000, #tweenMode:"bounce", #jojo:1, #repeat:"inf"])
end
on exitFrame me
sprite(me.spritenum).loc = pTween.update()
endActive mode
tinyTween object
tinyTween object
n = script("tinyTween").new(spriteObject, propertyList, stringActionOnTweenComplete)Basic tween properties in Active Mode
The following properties are endvalues of the tween, the startvalues are based on the current properties of the sprite.- blend (int)
- loc (point)
- locH (int)
- locV (int)
- rect (rect/list)
- rotation (int)
- duration (int: tweenDuration in milliseconds)
- delay (int: delay in milliseconds)
- repeat (int: times a tween is repeated, use 0 or "inf" for infinite repeat)
- jojo (int: 1/0, makes the tween go back-and-forth)
- tweenmode (string: see tweenModes)
- stringActionOnTweenComplete (string, calls the 'do' command in lingo)
So if sprite "wokkie" on the stage has a blend of 100, then the following code will blend the sprite in 1 second from 100 to 0.
tinyTween basic sample
n = script("tinyTween").new(sprite("wokkie"), [#blend:0, #duration:1000])Advanced tween properties in Active mode
The advanced properties have start- and endvalues.- startBlend (int)
- endBlend (int)
- startLoc (point)
- endLoc (point)
- startLocH (int/float)
- endLocH (int/float)
- startLocV (int/float)
- endLocV (int/float)
- startWidth (int/float)
- endWidth (int/float)
- startHeight (int/float)
- endHeight (int/float)
- startRect (rectangle/list)
For every property (Example 'rotation') you set a startRotation and a endRotation. So:
code sample
n = script("tinyTween").new(sprite(1), [#startRotation:0, #endRotation:360, #duration:2000, #tweenMode:"easeInOutBack", #delay:1000, #repeat:4, #jojo:1])special arguments in Active mode
The argument stringActionOnTweenComplete has the following states:- void of omitted: no action
- string with handlername: calls a 'do' command
This code makes sprite 1 rotate four times and therefore calls four times the handler "doTheWokkie".
code sample
n = script("tinyTween").new(sprite(1), [#startRotation:0, #endRotation:360, #duration:2000, #tweenMode:"easeInOutBack", #delay:1000, #repeat:4, #jojo:1], "doTheWokkie")tweenModes
The tweenmodes are insired by these
tweens.linear
- linear
- easeInSine
- easeOutSine
- easeInOutSine
- easeOutInSine
- easeInQuad
- easeOutQuad
- easeInOutQuad
- easeOutInQuad
- easeInBack
- easeOutBack
- easeInOutBack
- easeOutInBack
- easeInQuart
- easeOutQuart
- easeInOutQuart
- easeOutInQuart
- bounce
- superBounce
- elastic
- superElastic
tinyTween source
Copy this code in a parensScript member and call it "tinyTween"tinyTween source
--@--------------------------------
--@ tinyTween by MW @ Kiss the Frog 2010/2011
--@
--@
--@ timebased tweenScript v 1.3.0 beta
--@
--@ active mode sample usage:
--@ n = script("tinyTween").new(spriteObject, propertyList, stringActionOnTweenComplete)
--@ n = script("tinyTween").new(sprite(1), [#startRotation:0, #endRotation:360, #duration:2000, #tweenMode:"easeInOutBack", #jojo:1, #repeat:0], "onTweenComplete")
--@
--@ passive mode sample usage:
--@
--@ --Behaviour script
--@ property pTween
--@
--@ on beginSprite me
--@ pTween = script("tinyTween").new([#start:point(100,100), #end:point(600,200), #duration:4000, #tweenMode:"elastic", #jojo:1, #repeat:0])
--@ end
--@
--@ on exitFrame me
--@ sprite(me.spritenum).loc = pTween.update()
--@ end
--@
--@---------------------------------
property pSprite --SpriteObject
--reserved
property pStartTime --Integer (milliseconds)
property pEnded --Boolean
property pPassiveMode
--modifiers
property pTweenmode --String
property pAction --String ('do' command)
property pDuration --Integer (milliseconds)
property pDelay --Integer (milliseconds)
property pRepeat --Integer
property pJojo --Integer (0/1)
property pInfinite
property props --proplist
--bezier
property ppath --propList
--sin
property pBounciness
-------------------------
-- PUBLIC ---------------
-------------------------
on new(me,_sprite,prop, _action)
--init
pAction = _action
ppath = [:]
pBounciness = 0
pPassiveMode= 0
if ilk(_sprite) = #propList then --we are going for passive mode!
---------------
--PASSIVE
---------------
prop = _sprite.duplicate()
--setup the tween
setupTinyTween(me,prop)
else
---------------
--ACTIVE
---------------
pSprite = _sprite
--setup the tween
setupTinyTween(me,prop)
--add to actor
(the actorList).add(me)
end if
return me
end
on destroy(me)
--delete instance
n = (the actorList).getPos(me)
if n > 0 then (the actorList).deleteAt(n)
end
-------------------------
-- PRIVATE --------------
-------------------------
on setupTinyTween(me,prop)
if ilk(prop) = #propList then
--Check if we're in passive mode
if voidP(prop.getAprop(#start))= false and voidP(prop.getAprop(#end)) = false then
-----------------------
--PASSIVE MODE
-----------------------
--defaults
pPassiveMode = 1
pTweenmode = "easeInSine"
pDuration = 1000
pDelay = 0
pRepeat = 1
pJojo = 0
pInfinite = false
props = [:]
if not voidP(prop["tweenMode"]) then pTweenMode = prop["tweenMode"]
if not voidP(prop["duration"]) then pDuration = prop["duration"]
if not voidP(prop["jojo"]) then pJojo = prop["jojo"]
if not voidP(prop["repeat"]) then pRepeat = prop["repeat"]
if not voidP(prop["delay"]) then pDelay = prop["delay"]
if not voidP(prop["start"]) then
props.addProp(#start, prop["start"] )
props.addProp(#end, prop["end"] )
props.addProp(#distance, (prop["start"] - prop["end"]))
end if
--[Some checks]----------------------------------
--check for infinite tween
if pRepeat = 0 or pRepeat = "inf" then
pRepeat = 99 --just a number
pInfinite = true
end if
--Check for jojo. If true, the tween will be devided in 'back and Forth' in the given tweentime
if pJojo = 1 then
pRepeat = pRepeat * 2
pDuration = pDuration/2.0
end if
tinyTween(me)
else
-----------------------
--ACTIVE MODE
-----------------------
--defaults
pTweenmode = "easeInSine"
pDuration = 1000
pDelay = 0
pRepeat = 1
pJojo = 0
pInfinite = false
props = [:]
--[general]---------------------------------------
if not voidP(prop["duration"]) then pDuration = prop["duration"]
if not voidP(prop["delay"]) then pDelay = prop["delay"]
if not voidP(prop["tweenMode"]) then pTweenmode = prop["tweenMode"]
if not voidP(prop["jojo"]) then pJojo = prop["jojo"]
if not voidP(prop["repeat"]) then pRepeat = prop["repeat"]
--[Some checks]----------------------------------
--check for infinite tween
if pRepeat = 0 or pRepeat = "inf" then
pRepeat = 99 --just a number
pInfinite = true
end if
--Check for jojo. If true, the tween will be devided in 'back and Forth' in the given tweentime
if pJojo = 1 then
pRepeat = pRepeat * 2
pDuration = pDuration/2.0
end if
--[ShortCuts]-------------------------------------
--Uses the pSprite properties as start-values.
if not voidP(prop["rect"]) then
props.addProp(#left,[#startLeft:pSprite.rect[1], #endLeft:prop["rect"][1],#distanceLeft:pSprite.rect[1] - prop["rect"][1]] )
props.addProp(#top,[#startTop:pSprite.rect[2], #endTop:prop["rect"][2],#distanceTop:pSprite.rect[2] - prop["rect"][2]] )
props.addProp(#right,[#startRight:pSprite.rect[3], #endRight:prop["rect"][3],#distanceRight:pSprite.rect[3] - prop["rect"][3]] )
props.addProp(#bottom,[#startBottom:pSprite.rect[4], #endbottom:prop["rect"][4],#distanceBottom:pSprite.rect[4] - prop["rect"][4]] )
end if
if not voidP(prop["loc"]) then
props.addProp(#locH,[#startLocH:pSprite.loc[1], #endLocH:prop["loc"][1],#distanceH:pSprite.loc[1] - prop["loc"][1]] )
props.addProp(#locV,[#startLocV:pSprite.loc[2], #endLocV:prop["loc"][2],#distanceV:pSprite.loc[2] - prop["loc"][2]] )
end if
if not voidP(prop["locH"]) then props.addProp(#locH,[#startLocH:pSprite.locH, #endLocH:prop["locH"],#distanceH:pSprite.locH - prop["LocH"]] )
if not voidP(prop["locV"]) then props.addProp(#locV,[#startLocV:pSprite.locV, #endLocV:prop["locV"],#distanceV:pSprite.locV - prop["locV"]] )
if not voidP(prop["width"]) then props.addProp(#width,[#startWidth:pSprite.width, #endWidth:prop["width"],#distanceWidth:pSprite.width - prop["width"]] )
if not voidP(prop["height"]) then props.addProp(#height,[#startHeight:pSprite.height, #endHeight:prop["height"],#distanceHeight:pSprite.height - prop["height"]] )
if not voidP(prop["blend"]) then props.addProp(#blend,[#startBlend:pSprite.blend, #endBlend:prop["blend"],#distanceBlend:pSprite.blend - prop["blend"]] )
if not voidP(prop["rotation"]) then props.addProp(#rotation,[#startRotation:pSprite.rotation, #endRotation:prop["rotation"],#distanceRotation:pSprite.rotation - prop["rotation"]] )
if not voidP(prop["left"]) then props.addProp(#left,[#left:pSprite.left, #endLeft:prop["left"],#distanceLeft:pSprite.left - prop["left"]] )
if not voidP(prop["top"]) then props.addProp(#top,[#top:pSprite.top, #endTop:prop["top"],#distanceTop:pSprite.top - prop["top"]] )
if not voidP(prop["right"]) then props.addProp(#right,[#right:pSprite.right, #endRight:prop["right"],#distanceRight:pSprite.right - prop["right"]] )
if not voidP(prop["bottom"])then props.addProp(#bottom,[#bottom:pSprite.bottom, #endBottom:prop["bottom"],#distanceBottom:pSprite.bottom - prop["bottom"]])
--[The Whole nine Yards]---------------------------
--Needs startProperty and EndProperty to work.
if not voidP(prop["startLocH"]) and not voidP(prop["endLocH"]) then props.addProp(#locH,[#startLocH:prop["startLocH"], #endLocH:prop["endLocH"],#distanceH:prop["startLocH"] - prop["endLocH"]] )
if not voidP(prop["startLocV"]) and not voidP(prop["endLocV"]) then props.addProp(#locV,[#startLocV:prop["startLocV"], #endLocV:prop["endLocV"],#distanceV:prop["startLocV"] - prop["endLocV"]] )
if not voidP(prop["startWidth"]) and not voidP(prop["endWidth"]) then props.addProp(#width,[#startWidth:prop["startWidth"], #endWidth:prop["endWidth"],#distanceWidth:prop["startWidth"] - prop["endWidth"]] )
if not voidP(prop["startHeight"]) and not voidP(prop["endHeight"]) then props.addProp(#height,[#startHeight:prop["startHeight"], #endHeight:prop["endHeight"],#distanceHeight:prop["startHeight"] - prop["endHeight"]] )
if not voidP(prop["startBlend"]) and not voidP(prop["endBlend"]) then props.addProp(#blend,[#startBlend:prop["startBlend"], #endBlend:prop["endBlend"],#distanceBlend:prop["startBlend"] - prop["endBlend"]] )
if not voidP(prop["startRotation"]) and not voidP(prop["endRotation"]) then props.addProp(#Rotation,[#startRotation:prop["startRotation"], #endRotation:prop["endRotation"],#distanceBlend:prop["startRotation"] - prop["endRotation"]] )
if not voidP(prop["startLeft"]) and not voidP(prop["endLeft"]) then props.addProp(#left,[#startLeft:prop["startLeft"], #endLeft:prop["endLeft"],#distanceLeft:prop["startLeft"] - prop["endLeft"]] )
if not voidP(prop["startTop"]) and not voidP(prop["endTop"]) then props.addProp(#top,[#startTop:prop["startTop"], #endTop:prop["endTop"],#distanceTop:prop["startTop"] - prop["endTop"]] )
if not voidP(prop["startRight"]) and not voidP(prop["endRight"]) then props.addProp(#right,[#startRight:prop["startRight"], #endRight:prop["endRight"],#distanceRight:prop["startRight"] - prop["endRight"]] )
if not voidP(prop["startBottom"]) and not voidP(prop["endBottom"]) then props.addProp(#bottom,[#startBottom:prop["startBottom"], #endBottom:prop["endBottom"],#distanceBottom:prop["startBottom"] - prop["endBottom"]])
--multiDimensional
if not voidP(prop["startRect"]) and not voidP(prop["endRect"]) then
props.addProp(#left,[#startLeft:prop["startRect"][1], #endLeft:prop["endRect"][1],#distanceLeft:prop["startRect"][1] - prop["endRect"][1]] )
props.addProp(#top,[#startTop:prop["startRect"][2], #endTop:prop["endRect"][2],#distanceTop:prop["startRect"][2] - prop["endRect"][2]] )
props.addProp(#right,[#startRight:prop["startRect"][3], #endRight:prop["endRect"][3],#distanceRight:prop["startRect"][3] - prop["endRect"][3]] )
props.addProp(#bottom,[#startBottom:prop["startRect"][4], #endBottom:prop["endRect"][4],#distanceBottom:prop["startRect"][4] - prop["endRect"][4]] )
end if
if not voidP(prop["startLoc"]) and not voidP(prop["endLoc"]) then
props.addProp(#locH,[#startLocH:prop["startLoc"][1], #endLocH:prop["endLoc"][1],#distanceH:prop["startLoc"][1] - prop["endLoc"][1]] )
props.addProp(#locV,[#startLocV:prop["startLoc"][2], #endLocV:prop["endLoc"][2],#distanceV:prop["startLoc"][2] - prop["endLoc"][2]] )
end if
tinyTween(me)
end if
end if
end
on tinyTween(me,inv)
if pPassiveMode = 1 then
if inv = true then
repeat with i = 1 to props.count
s = props.end
e = props.start
props.start = s
props.end = e
props.distance = s - e
end repeat
end if
else
if inv = true then
repeat with i = 1 to props.count
s = props[i][2]
e = props[i][1]
props[i][1] = s
props[i][2] = e
props[i][3] = s - e
end repeat
end if
repeat with i = 1 to props.count
do "pSprite."&string(props.getPropAt(i))&&" = props[i][1]" --start
end repeat
end if
pStartTime = the milliseconds
pEnded = false
setTween(me)
end
on setTween(me)
case pTweenmode of
--linear
"linear" : SetupBezier(me, point(0,0),point(0,0),point(100,100),point(100,100))
--sine
"easeInSine" : SetupBezier(me, point(0,0),point(10,0),point(100,100),point(100,100))
"easeOutSine" : SetupBezier(me, point(0,0),point(0,0),point(90,100),point(100,100))
"easeInOutSine": SetupBezier(me, point(0,0),point(10,0),point(90,100),point(100,100))
"easeOutInSine": SetupBezier(me, point(0,0),point(60,50),point(40,50),point(100,100))
--Quad
"easeInQuad" : SetupBezier(me, point(0,0),point(20,0),point(100,100),point(100,100))
"easeOutQuad" : SetupBezier(me, point(0,0),point(0,0),point(80,100),point(100,100))
"easeInOutQuad": SetupBezier(me, point(0,0),point(20,0),point(80,100),point(100,100))
"easeOutInQuad": SetupBezier(me, point(0,0),point(70,50),point(30,50),point(100,100))
--Back
"easeInBack" : SetupBezier(me, point(0,0),point(5,0),point(-50,100),point(100,100))
"easeOutBack" : SetupBezier(me, point(0,0),point(150,0),point(95,100),point(100,100))
"easeInOutBack": SetupBezier(me, point(0,0),point(-30,0),point(130,100),point(100,100))
"easeOutInBack": SetupBezier(me, point(0,0),point(130,100),point(-30,0),point(100,100))
--Quart
"easeInQuart" : SetupBezier(me, point(0,0),point(50,0),point(100,100),point(100,100))
"easeOutQuart" : SetupBezier(me, point(0,0),point(0,0),point(50,100),point(100,100))
"easeInOutQuart": SetupBezier(me, point(0,0),point(50,0),point(50,100),point(100,100))
"easeOutInQuart": SetupBezier(me, point(0,0),point(100,50),point(0,50),point(100,100))
--Special
"bounce" : SetupBounceBezier(me, 100)
"superBounce" : SetupBounceBezier(me, 66)
"elastic" : SetupBounceBezier(me, 100)
"superElastic" : SetupBounceBezier(me, 66)
otherwise
--linear
SetupBezier(me, point(0,0),point(0,0),point(100,100),point(100,100))
end case
end
on SetupBezier(me, var1,var2,var3,var4)
ppath = [#p0:var1,#p1:var2,#p2:var3,#p3:var4]
setaProp pPath, #dc, 3 * (pPath.p1 - pPath.p0)
setaProp pPath, #db, 3 * (pPath.p2 - pPath.p1) - pPath.dc
setaProp pPath, #da, pPath.p3 - pPath.p0 - pPath.dc - pPath.db
end
on SetupBounceBezier(me,amount)
pBounciness = amount
end
on GetPosition(me, timetoget)
if pTweenmode contains "bounce" or pTweenmode contains "elastic" then
n = getBouncePosition(me, timetoget)
if pTweenMode contains "elastic" then
return [100 - ((100 - timetoget) * n),0]
else
return [100 - ((100 - timetoget) * abs(n)),0]
end if
else
if ppath = [:] then return -1
if timetoget > 100 then timetoget = 100
if timetoget < 0 then timetoget = 0
if timetoget = 100 then
return ppath.p3
else
vT1 = float (timetoget )/ 100.0
vT2 = vT1 * vT1
vT3 = vT2 * vT1
vNewPosition = pPath.p0
vModPoint = pPath.dc * vT1
vNewPosition = vNewPosition + vModPoint
vModPoint = pPath.db * vT2
vNewPosition = vNewPosition + vModPoint
vModPoint = pPath.da * vT3
vNewPosition = vNewPosition + vModPoint
return vNewPosition
end if
end if
end
on getBouncePosition(me, timetoget)
t = ((0.5 * pi) + (((100)/((2*pi)*pBounciness) * timeToGet )))
n = sin(t)
if t > pi then n = n / ((timetoget * 0.2)*pBounciness/100.0)
return n
end
--update
on update(me)
_time = the milliseconds - pStartTime - pDelay
-- put _time
if _time > pDuration then
-- n = props.duplicate()
if pRepeat > 0 then
if pRepeat > 1 then tinyTween(me, pJojo)
if pInfinite = false then pRepeat = pRepeat - 1
end if
if pJojo = 1 then
return props.start
else
return props.end
end if
else if _time > 0 then
_timeToGet = _time/(pDuration * 1.0) * 100
_tween =GetPosition(me, _timetoget)[1]
return (props.start - ((props.distance/100.0) * _tween))
else
return props.start
end if
end
--Loop
on stepframe(me)
--check is tween is still active
if pEnded = false then
_time = the milliseconds - pStartTime - pDelay
if _time > pDuration then
--set all active properties to endProp
repeat with i = 1 to props.count
do "pSprite."&string(props.getPropAt(i))&&" = props[i][2]"
end repeat
pEnded = true
pBezier = void
if pRepeat > 0 then
if pRepeat > 1 then tinyTween(me, pJojo)
if pInfinite = false then pRepeat = pRepeat - 1
if not voidP(pAction)then do pAction
else
--Tween ends, destroy!
destroy(me)
if not voidP(pAction)then do pAction
end if
else if _time > 0 then
_timeToGet = _time/(pDuration * 1.0) * 100
_tween =GetPosition(me, _timetoget)[1]
repeat with i = 1 to props.count
--Check blend
if string(props.getPropAt(i)) contains "blend" then
n = props[i][1] - ((props[i][3]/100.0) * _tween)
--Fix blends
if n > 100 then n = 100
if n < 0 then n = 0
pSprite.blend = n
else
do "pSprite."&string(props.getPropAt(i))&&" = props[i][1] - ((props[i][3]/100.0) * _tween)"
end if
end repeat
end if
else
destroy(me)
end if
end