-- dial behavior
-- creates a rotating needle that can sweep continuus full circles,
-- arc lengths, random movements, or move to amounts as sent from
-- other handlers
-----------------------------------------------------------------
-- alan
-- assumes quadrant states of
-- v
-- |
-- 2 | 1 > 0 degrees is the positive h axis
-- --------- h > angles are positive in the counter
-- 3 | 4 clockwise direction
-- | > v axis is positive upward
-- myOriginLoc : symbol param for which corner of the
-- starting sprte is the axis of rotation;
-- [#topLeft,#bottomRight,#topRight,#bottomLeft]
-- myOrigin : point location of the origin
-- myVertex : point location of the end of the needle
-- myTheta : angle of rotation measured counter
-- colckwise from positive h axis
-- myRadius : radius of circle of rotation
-- myMode : symbol representing the type of dial
-- [#arcSweep,#fullSweep,#randomSweep,#externalTrigger]
-- myMin : starting angle location for arcSweep or range for
-- randomSweep
-- myMax : ending angle location for arcSweep or range for
-- randomSweep
-- myDelay : number of ticks between updates
-- myClock : runing time in ticks since last update
-- myDirection : clockwise or counter-clockwise
-- myIncrement : number of degrees to move between updates
-- myTrails : boolean flag for drawing with trails
-- myState : flag to indicate whether we have finished for an arc
-- theRadtoDeg : constant for converting between radians and degrees
-----------------------------------------------------------------
on beginSprite me
-- initialize the constant for angle conversion
set theRadToDeg = 180.0 / pi()
-- initialize state to active
set myState = #go
-- initialize clock
set myClock = the ticks
-- set increment to negative for clockwise sweeps
if myDirection = "Clockwise" then set myIncrement = - myIncrement
-- initialize trails state
set the trails of sprite the spriteNum of me = myTrails
-- find the vertex and the points according to the initial sprite and
-- flag sent from BH dialog box
if myOriginLoc = #topLeft then
-- sprite with origin at top left of rect ( member "line24" in quadrant 4)
set myOrigin = point( getAt( the rect of sprite the spriteNum of me,1),¬
getAt( the rect of sprite the spriteNum of me,2) )
set myVertex = point( getAt( the rect of sprite the spriteNum of me,3),¬
getAt( the rect of sprite the spriteNum of me,4) )
else if myOriginLoc = #bottomRight then
-- sprite with origin at bottom right of rect ( member "line24" in quadrant 2)
set myOrigin = point( getAt( the rect of sprite the spriteNum of me,3),¬
getAt( the rect of sprite the spriteNum of me,4) )
set myVertex = point( getAt( the rect of sprite the spriteNum of me,1),¬
getAt( the rect of sprite the spriteNum of me,2) )
else if myOriginLoc = #topRight then
-- sprite with origin at top right of rect ( member "line13" in quadrant 3)
set myOrigin = point( getAt( the rect of sprite the spriteNum of me,3),¬
getAt( the rect of sprite the spriteNum of me,2) )
set myVertex = point( getAt( the rect of sprite the spriteNum of me,1),¬
getAt( the rect of sprite the spriteNum of me,4) )
else
-- sprite with origin at bottom left of rect ( member "line13" in quadrant 1)
set myOrigin = point( getAt( the rect of sprite the spriteNum of me,1),¬
getAt( the rect of sprite the spriteNum of me,4) )
set myVertex = point( getAt( the rect of sprite the spriteNum of me,3),¬
getAt( the rect of sprite the spriteNum of me,2) )
end if
-- determine the initial angle of the vertex
if the locV of myOrigin = the locV of myVertex then
-- case where the line is horizontal
if the locH of myOrigin > the locH of myVertex then
set myTheta = 0
else
set myTheta = 180
end if
set myRadius = abs( the locH of myOrigin - the locH of myVertex )
else if the locH of myOrigin = the locH of myVertex then
-- case where the line is vertical
if the locV of myOrigin > the locV of myVertex then
set myTheta = 270
else
set myTheta = 90
end if
set myRadius = abs( the locV of myOrigin - the locV of myVertex )
else
-- all other cases, need to determine angle with arctangent
set myTheta = theRadToDeg * atan ( 1.0 * (the locV of myOrigin - the locV of myVertex) / (the locH of myVertex - the locH of myOrigin))
-- determines quadrant of vertex point
-- 1 = NE, 2 = NW, 3=SW, 4=SE
if the locV of myVertex < the locV of myOrigin then
-- we are in quads 1 or 2
if the locH of myVertex < the locH of myOrigin then
-- quad 2
set myTheta = 180 + myTheta
else
-- quad 1, no adjustment
end if
else
-- we are in quads 3 or 4
if the locH of myVertex < the locH of myOrigin then
-- quad 3
set myTheta = 180 + myTheta
else
-- quad 4
set myTheta = 360 + myTheta
end if
end if
-- keep track of the starting angle
set myMin = myTheta
-- calculate radius with distance formula
set myRadius = sqrt ( power( the locH of myVertex - the locH of myOrigin , 2) + ¬
power( the locV of myVertex - the locV of myOrigin , 2) )
end if
end
on prepareFrame me
-- called on every frame update to generate new locations
-- First check if this motion is active
if myState = #go then
-- only update if we have passed our delay interval
if the ticks - myClock > myDelay then
if myMode = #arcSweep then
-- update to new value
set myTheta = myTheta + myIncrement
-- need two tests for ending condition
if myIncrement > 0 then
-- test for counter-clockwise movement
if myTheta < myMin + myMax then
move( me, myTheta)
else
set myState = #stop
end if
else
-- test for clockwise movement
if myTheta > myMin - myMax then
move(me, myTheta)
else
set myState = #stop
end if
end if
else if myMode = #fullSweep then
-- full sweeps, just increment and draw
set myTheta = myTheta + myIncrement
move(me, myTheta)
else if myMode = #randomSweep then
-- random sweeps, calculate for range withing specified
-- inputs, in appropriate direction from starting point
if myIncrement > 0 then
set myTheta = myMin + random(myMax)
else
set myTheta = myMin - random(myMax)
end if
move(me, myTheta)
end if
-- update the clock
set myClock = the ticks
end if
updateStage
end if
end
on move me, newTheta
-- general purpose call to move the needle to the new value (degrees)
set myTheta = newTheta
-- correct for angles that go negative
if myTheta < 0 then set myTheta = 360 + myTheta
-- we need to work off of a local variable so we can test quadrants
set localTheta = myTheta
-- reduce the local theta to less than 360
repeat while localTheta >= 360
set localTheta = localTheta - 360
end repeat
-- 0 degree angle special case
if localTheta = 0 then
-- update new vertex point
set myVertex = myOrigin + point(integer( myradius),0)
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line13"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = rect(the locH of myOrigin, the locV of myVertex, the locH of myVertex, the locV of myOrigin + the lineSize of sprite (the spriteNum of me) )
else if localTheta < 90 then
-- quadrant 1
-- update new vertex point
set myVertex = myOrigin + point( integer(myRadius * cos (localTheta / theRadToDeg )), - integer(myRadius * sin (localTheta / theRadToDeg)))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line13"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = rect(the locH of myOrigin, the locV of myVertex, the locH of myVertex, the locV of myOrigin)
else if localTheta = 90 then
-- 90 degree angle special case
-- update new vertex point
set myVertex = myOrigin - point( 0, integer( myradius))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line24"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = rect(the locH of myVertex - the lineSize of sprite (the spriteNum of me), the locV of myVertex, the locH of myOrigin, the locV of myOrigin)
else if localTheta < 180 then
-- quadrant 2
-- update new vertex point
set myVertex = myOrigin + point( integer(myRadius * cos (localTheta / theRadToDeg )), - integer(myRadius * sin (localTheta / theRadToDeg)))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line24"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = rect(the locH of myVertex, the locV of myVertex, the locH of myOrigin, the locV of myOrigin)
else if localTheta = 180 then
-- 180 degree angle special case
-- update new vertex point
set myVertex = myOrigin - point(integer( myradius),0)
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line13"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = rect(the locH of myVertex, the locV of myOrigin - the lineSize of sprite (the spriteNum of me), the locH of myOrigin, the locV of myVertex)
else if localTheta < 270 then
-- quadrant 3
-- update new vertex point
set myVertex = myOrigin + point( integer(myRadius * cos (localTheta / theRadToDeg )), - integer(myRadius * sin (localTheta / theRadToDeg)))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line13"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = rect(the locH of myVertex, the locV of myOrigin, the locH of myOrigin, the locV of myVertex)
else if localTheta = 270 then
-- 270 degree angle special case
-- update new vertex point
set myVertex = myOrigin + point( 0, integer( myradius))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line24"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = rect(the locH of myVertex, the locV of myVertex, the locH of myOrigin + the lineSize of sprite (the spriteNum of me), the locV of myOrigin)
else
-- quadrant 4
-- update new vertex point
set myVertex = myOrigin + point( integer(myRadius * cos (localTheta / theRadToDeg )), - integer(myRadius * sin (localTheta / theRadToDeg)))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line24"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = rect(the locH of myVertex, the locV of myVertex, the locH of myOrigin, the locV of myOrigin)
on getBehaviorDescription
return "Creates a rotating needle dial on line sprites. Cast must include 2 members named " && QUOTE & "line24" & QUOTE && "and " && QUOTE & "line13" & QUOTE & RETURN & "PARAMETERS:" & RETURN & "• Origin Location - Select which corner of the line sprites rect is the axis of rotation." & RETURN & "• Type of Dial - Select from the choices. #arcSweep = movement in constrained arc length; #fullSweep=continuous 360 degree rotation; #randomSweep=movement to random degree offset (within range specified); #externalTrigger=movement will be sent by another handler via a sendSprite command" & RETURN & "• arc sweep - Select how far the needle will move from its initial position (in degrees)." & RETURN & "• increment per move - how many degrees the needle will move on each frame update. "& RETURN & "• direction - spin direction relative to the initial position." & RETURN & "• delay time - length of time between updates." & RETURN & "• trails - draw line with trails on." & RETURN & "NOTES:" & RETURN & "If the needle does not move as expected, the most likely cause is the origin location is not properly set. Drawing with trails can be erratic if other sprites animate over the specified sprites."
end
Contact
MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA