|
|
|
Page turn
Added on 10/9/2000
|
You may select a second castmember to display the other side of the turned page half way through the animation.
The animation may be executed in a series of enterFrame (dependent upon your movie"s framerate) messages or a repeat loop (faster and smoother). This behaviour is a little low on documentation but a few suggestions are
mentioned for it"s improvement in the opening comments.
Download PC Source Download Mac Source
-- Page Turn Behaviour (using sprite quad property)
-- Julian de Saxe
-- catchTheBaddies@mothcity.com
-- Sorry the documentation is so sparse.
-- Planned for next time I visit this script:
-- Add function to turn the page back again.
-- Add functionality to animate on mouseUp;
-- (detecting which corner of the sprite was closest to the mouse event and
-- calculating the lead-in distance based on the distance from the vertical centre of the sprite)
-- ie. The closer to the middle of the page the less the lead-in.
-- Add isOkToAttach handler.
-- This behaviour doesn't work on Flash sprites.
-- But wouldn't it be so cool to do this with an animated flash movie.
-- Dream up a whole children's story book with every page a lushman's Flash movie
-- sitting in a .dxr on a web page with narration and a soundtrack. Click on the corner to turn the page.
-- Write to Macromedia and beg them to support the quad property of a Flash sprite in their next version of Director!
----------------------------------------------------------------------------------------------------
on getBehaviorTooltip
return "This behavior makes a sprite animate" & RETURN & ¬
"in a simulated page turn (left or right)."
end getBehaviorTooltip
----------------------------------------------------------------------------------------------------
on getBehaviorDescription
vDesc = "PAGE TURN"&RETURN&RETURN
vDesc = vDesc &"A bitmap sprite with this behavior attached will"
vDesc = vDesc &RETURN& "be animated to simulate a page turning."
vDesc = vDesc &RETURN& "Drop it on a sprite and indicate the direction"
vDesc = vDesc &RETURN& "you wish the page to turn (left to right OR"
vDesc = vDesc &RETURN& "right to left)."
vDesc = vDesc &RETURN& "Then choose the corner that should begin turning first (TOP or BOTTOM)."
vDesc = vDesc &RETURN& "This gives the animation the appearance of being turned from"
vDesc = vDesc &RETURN& "one of the corners."
vDesc = vDesc &RETURN& "Select the distance that this corner will travel before the other"
vDesc = vDesc &RETURN& "corner begins to turn."
vDesc = vDesc &RETURN& "This is expressed as a percentage of the total width of"
vDesc = vDesc &RETURN& "the sprite."
vDesc = vDesc &RETURN& "Choose the amplitude of the arc of the curve for the top and bottom"
vDesc = vDesc &RETURN& "of the page."
vDesc = vDesc &RETURN& "ie. how high or low the locus of the corner rises or falls below the top or bottom."
vDesc = vDesc &RETURN& "of the page."
vDesc = vDesc &RETURN& "The higher the value the further the page appears to rise out of the stage (towards your nose)."
vDesc = vDesc &RETURN& "Select the speed of the animation."
vDesc = vDesc &RETURN& "This will vary according to whether you choose to play the animation in a frame"
vDesc = vDesc &RETURN& "based animation or a repeat loop."
vDesc = vDesc &RETURN& "If you wish to change castmembers half way through the animation"
vDesc = vDesc &RETURN& "check the box and select a bitmap castmember from the pop-up menu."
vDesc = vDesc &RETURN& "NB. This is useful to have the page look as though the other side of the page"
vDesc = vDesc &RETURN& "is authentic. However, the image of the castmember needs to be reversed in the vertical axis"
vDesc = vDesc &RETURN& "because the quad property of the sprite at this stage in the animation will reverse the image."
vDesc = vDesc &RETURN& "back to it's proper appearance."
vDesc = vDesc &RETURN& "Choose whether you want the animation to be frame based or occur in a repeat loop."
vDesc = vDesc &RETURN& "Choosing repeat loop makes the animation much faster and smoother and is more consistent"
vDesc = vDesc &RETURN& "over a range of machines."
vDesc = vDesc &RETURN& "ps. This behaviour contains no error checking."
return vDesc
end getBehaviorDescription
----------------------------------------------------------------------------------------------------
property pSprite -- sprite object reference
property pSpriteRect -- original rect of sprite
property pCurrentQuad -- quad point reference
property pOrigQuad -- original sprite quad values
property pSwitch -- initially FALSE. Set to TRUE to begin animation
property pFrameOrRpt -- allows designer to decide to execute animation in repeat loop or frame based
property pMyAnimFactor -- factor of pi to calculate quad points
property pTurnPage -- left to right or right to left?
property pLeadCorner -- leading corner is th corner that starts turning first (top or bottom?)
property pTurnDirection
property pTotalX
property pLeadInTime -- distance that the first corner travels before the second corner begins to animate.
property pSpeed -- number of steps
property pTotalDistance -- the counter ( = 2 * sprite.width)
property pDistance
property pTopAmplitude -- height (amplitude) of curve (top of page)
property pBottomAmplitude -- height (amplitude) of curve (bottom of page)
property pOtherPage
property pChangeMember
property pAdvanceWhenFinished
----------------------------------------------------------------------------------------------------
on getPropertyDescriptionList me
if the currentSpriteNum = 0 then exit
theMember = sprite(the currentSpriteNum).member
theMemberNumber = theMember.number
vPDList = [:]
setaProp vPDList, #pTurnDirection, [#comment: "direction of page turn : ", #format: #string, #range:["LeftToRight","RightToLeft"], #default: "LeftToRight"]
addProp vPDList, #pLeadCorner, [#comment: "leading corner : ", #format: #string, #range:["Top","Bottom"], #default: "top"]
addProp vPDList, #pLeadInTime, [#comment: "lead in time : ", #format: #float, #range:[#min:0,#max:1], #default: 0.25]
addProp vPDList, #pTopAmplitude, [#comment: "amplitude of top curve : ", #format: #float, #range:[#min:0.0000,#max:1.000], #default: 0.07]
addProp vPDList, #pBottomAmplitude, [#comment: "amplitude of bottom curve : ", #format: #float, #range:[#min:0,#max:1], #default: 0.22]
addProp vPDList, #pSpeed, [#comment: "speed of animation : ", #format: #integer, #range:[#min:1,#max:150], #default: 1]
addProp vPDList, #pChangeMember, [#comment: "change member half way ? ", #format: #boolean, #default: 0]
addProp vPDList, #pOtherPage, [#comment: "other side of page (image) : ", #format: #graphic, #default: theMemberNumber+1]
addProp vPDList, #pFrameOrRpt, [#comment: "how do you want to execute the animation : ", #format: #string, #range:["frame based", "repeat loop"], #default: "frame based"]
addProp vPDList, #pAdvanceWhenFinished, [#comment: "advance to the next frame when finished : ", #format: #boolean, #default: TRUE]
return vPDList
end getPropertyDescriptionList
----------------------------------------------------------------------------------------------------
on beginSprite me
mInitialise(me)
end
----------------------------------------------
on enterFrame me
if pSwitch then
if pDistance < pTotalDistance then
do pTurnPage
pSprite.quad = pCurrentQuad --- draw sprite
updateStage
set pDistance = pDistance + pSpeed
else if pDistance >= pTotalDistance then
set pDistance = pTotalDistance
do pTurnPage
pSprite.quad = pCurrentQuad --- draw sprite
updateStage
if pAdvanceWhenFinished then
go to the frame + 1
end if
pSwitch = FALSE
end if
if pChangeMember then
if pDistance > pTotalDistance/2 then
pSprite.member = pOtherPage
pChangeMember = FALSE
end if
end if
end if
end enterFrame
----------------------------------------------
on endSprite me
puppetSprite pSprite.spriteNum, FALSE
updateStage
end
----------------------------------------------
on mLeftToRightBottom me
vTopPoint = pOrigQuad[1]
vBottomPoint = pOrigQuad[4]
-- move bottom point
if pDistance <= pTotalX then
vXb = pDistance
vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
vBottomPoint.locH = pSpriteRect.left + abs(vXb)
vBottomPoint.locV = pSpriteRect.bottom + vYb -- change operator to alter view.
else if pDistance > pTotalX then
vXb = pTotalX
vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
vBottomPoint.locH = pSpriteRect.left + abs(vXb)
vBottomPoint.locV = pSpriteRect.bottom + vYb -- change operator to alter view.
end if
-- move top point
if pDistance >= pLeadInTime AND pDistance <= pTotalDistance then
set vXt = pDistance - pLeadInTime
vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
vTopPoint.locH = pSpriteRect.left + abs(vXt)
vTopPoint.locV = pSpriteRect.top + vYt -- change operator to alter view.
end if
pCurrentQuad[1] = vTopPoint
pCurrentQuad[4] = vBottomPoint
end
----------------------------------------------
on mLeftToRightTop me
vTopPoint = pOrigQuad[1]
vBottomPoint = pOrigQuad[4]
-- move top point
if pDistance <= pTotalX then
set vXt = pDistance
vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
vTopPoint.locH = pSpriteRect.left + abs(vXt)
vTopPoint.locV = pSpriteRect.top + vYt -- change operator to alter view.
else if pDistance > pTotalX then
vXt = pTotalX
vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
vTopPoint.locH = pSpriteRect.left + abs(vXt)
vTopPoint.locV = pSpriteRect.top + vYt -- change operator to alter view.
end if
-- move bottom point
if pDistance >= pLeadInTime AND pDistance <= pTotalDistance then
vXb = pDistance - pLeadInTime
vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
vBottomPoint.locH = pSpriteRect.left + abs(vXb)
vBottomPoint.locV = pSpriteRect.bottom + vYb -- change operator to alter view.
end if
pCurrentQuad[1] = vTopPoint
pCurrentQuad[4] = vBottomPoint
end
----------------------------------------------
on mRightToLeftTop me
vTopPoint = pOrigQuad[2]
vBottomPoint = pOrigQuad[3]
-- move top point
if pDistance <= pTotalX then
set vXt = pDistance
vYt = pTopAmplitude*sin(pMyAnimFactor*(vXt-pTotalX)) --
vTopPoint.locH = pSpriteRect.right - abs(vXt)
vTopPoint.locV = pSpriteRect.top + vYt -- change operator to alter view.
else if pDistance > pTotalX then
vXt = pTotalX
vYt = pTopAmplitude*sin(pMyAnimFactor*(vXt-pTotalX))
vTopPoint.locH = pSpriteRect.right - abs(vXt)
vTopPoint.locV = pSpriteRect.top + vYt -- change operator to alter view.
end if
-- move bottom point
if pDistance >= pLeadInTime AND pDistance <= pTotalDistance then
vXb = pDistance - pLeadInTime
vYb = pBottomAmplitude*sin(pMyAnimFactor*(vXb-pTotalX))
vBottomPoint.locH = pSpriteRect.right - abs(vXb)
vBottomPoint.locV = pSpriteRect.bottom + vYb -- change operator to alter view.
end if
pCurrentQuad[2] = vTopPoint
pCurrentQuad[3] = vBottomPoint
end
----------------------------------------------
on mRightToLeftBottom me
vTopPoint = pOrigQuad[2]
vBottomPoint = pOrigQuad[3]
-- move bottom point
if pDistance <= pTotalX then
vXb = pDistance
vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
vBottomPoint.locH = pSpriteRect.right - abs(vXb)
vBottomPoint.locV = pSpriteRect.bottom + vYb -- change operator to alter view.
else if pDistance > pTotalX then
vXb = pTotalX
vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
vBottomPoint.locH = pSpriteRect.right - abs(vXb)
vBottomPoint.locV = pSpriteRect.bottom + vYb -- change operator to alter view.
end if
-- move top point
if pDistance >= pLeadInTime AND pDistance <= pTotalDistance then
vXt = pDistance - pLeadInTime
vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
vTopPoint.locH = pSpriteRect.right - abs(vXt)
vTopPoint.locV = pSpriteRect.top + vYt -- change operator to alter view.
-- test else
else if pDistance = pTotalDistance then
vXt = pTotalDistance
vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
vTopPoint.locH = pSpriteRect.right - abs(vXt)
vTopPoint.locV = pSpriteRect.top + vYt -- change operator to alter view.
end if
pCurrentQuad[2] = vTopPoint
pCurrentQuad[3] = vBottomPoint
end
----------------------------------------------
on mInitialise me
pSprite = sprite (me.spriteNum)
pSpriteRect = pSprite.rect
pOrigQuad = duplicate(pSprite.quad)
pCurrentQuad = duplicate(pOrigQuad)
pTotalX = (pSprite.right - pSprite.left)*2 -- twice the width of the sprite (ie total distance travelled in x)
pLeadInTime = integer(pLeadInTime * pSprite.width) -- the 'lead-in' is expressed as a percentage of sprite.width
pTotalDistance = pTotalX + pLeadInTime -- total number of pixels in x (top and bottom)
pDistance = 0
pMyAnimFactor = pi/(pTotalX)
pTopAmplitude = integer(pSprite.height * pTopAmplitude) -- amplitude of top corner arc
pBottomAmplitude = integer(pSprite.height * pBottomAmplitude) -- amplitude of bottom corner arc
pTurnPage = "m"&pTurnDirection&pLeadCorner&&"me" -- handler defined by author parameters
pSwitch = FALSE
end
----------------------------------------------
on animate me
if pSwitch then
repeat while pDistance < pTotalDistance
do pTurnPage
pSprite.quad = pCurrentQuad --- draw sprite
updateStage
set pDistance = pDistance + pSpeed
if pChangeMember then
if pDistance > pTotalDistance/2 then
pSprite.member = pOtherPage
updateStage
pChangeMember = FALSE
end if
end if
end repeat
repeat while pDistance >= pTotalDistance
set pDistance = pTotalDistance
do pTurnPage
pSprite.quad = pCurrentQuad --- draw sprite
updateStage
if pAdvanceWhenFinished then
go to the frame + 1
end if
pSwitch = FALSE
exit repeat
end repeat
end if
return
end
on turnPage me
case pFrameOrRpt of
"frame based":
pSwitch = TRUE
"repeat loop":
pSwitch = TRUE
animate me
end case
end turnPage
|
|