-- TURN TOWARDS MOUSE -- -- HISTORY -- -- 14 Sep 1998: written for the D7 Behaviors Palette by James Newton -- 3 Nov 1998: descriptions improved -- NOTES FOR DEVELOPERS -- -- The main handler is Turn me. This simply caclulates the difference -- between the loc of the sprite and the mouseLoc. It then asks the -- custom GetAngle function to convert this into an angle expressed in -- degrees. GetAngle will return an angle of zero if the -- mySpriteToFace is on a horizontal line to the right of mySprite. -- The angle increases clockwise. -- Director 7 treats trigonometry in radians and sprite rotation in -- degrees. -- Turn me is only called if the behavior is active. Just when this -- is determined by the myActivePeriod parameter. In order to make -- the choices clear in the getPropertyDescriptionList handler, -- myActivePeriod is initially in the form of a string. A string is -- slow to handle, and the data it contains will need to be consulted --on every prepareFrame. In order to optimize performance, the -- strings are converted to symbols in the Initialize handler. -- Symbols are simply integers disguised as a single word. They are -- thus both fast and expressive. -- The Activate handler first tests if the mouse has been either -- clicked or released, and then runs through a 'case' statement to -- return a TRUE | FALSE value depending on the mouse's current state. -- IF the value returned is TRUE, then the Turn will be called. -- PROPERTIES -- property mySprite -- error checking property getPDLError -- author-defined parameters property myOrientation -- TRUE if sprite turns away from mouse property myActivePeriod -- #always | #mouseDown | #mouseUp | ... property myResetFlag -- TRUE if sprite is to revert to its initial position -- property myInitialAngle -- Angle of sprite at start of span property myMouseDown -- TRUE while the mouse is down -- EVENT HANDLERS -- on beginSprite me Initialize me end beginSprite on prepareFrame me if Activate (me) then Turn me else if myResetFlag then if mySprite.rotation <> myInitialAngle then mySprite.rotation = myInitialAngle end if end if end prepareFrame -- CUSTOM HANDLERS -- on Initialize me -- sent by beginSprite mySprite = sprite(me.spriteNum) memberType = mySprite.member.type -- Error checking if not PermittedMemberTypes(me).getPos(memberType) then ErrorAlert (me, #invalidMemberType, memberType) end if -- End of error checking case memberType of #flash, #vectorShape: mySprite.scaleMode = #autoSize end case myMouseDown = mouseDown() myInitialAngle = mySprite.rotation -- Convert strings myOrientation = (myOrientation = "away from the mouse") case myActivePeriod of "always": myActivePeriod = #always "when the mouse is clicked": myActivePeriod = #mouseClick "when the mouse is released": myActivePeriod = #mouseRelease "while the mouse is down": myActivePeriod = #mouseDown "while the mouse is up": myActivePeriod = #mouseUp end case myResetFlag = (myResetFlag = "return to the initial position") end Initialize on Activate me newStatus = (myMouseDown <> mouseDown()) if newStatus then myMouseDown = mouseDown() end if case myActivePeriod of #always: return TRUE #mouseClick: return newStatus AND mouseDown() #mouseRelease: return newStatus AND mouseUp() #mouseDown: return mouseDown() #mouseUp: return mouseUp() end case end Activate on Turn me slope = the mouseLoc - mySprite.loc angle = GetAngle (me, slope) if myOrientation then angle = angle + 180 end if if mySprite.rotation <> angle then mySprite.rotation = angle end if end Turn on GetAngle me, slope deltaH = slope[1] deltaV = slope[2] if deltaH then slope = float (deltaV) / deltaH angle = atan (slope) if deltaH < 0 then angle = angle + pi end if else if deltaV > 0 then angle = pi / 2 else if deltaV < 0 then angle = (3 * pi) / 2 else angle = 0 end if -- Convert to degrees for .rotation angle = (angle * 180) / pi return angle end GetAngle -- ERROR CHECKING -- -- ERROR CHECKING -- on ErrorAlert me, theError, data -- sent by getPropertyDescriptionList, Initialize case theError of #getPDLError: alert \ "Error: This behavior works only with the following members types: "&\ PermittedMemberTypes(me)&RETURN&RETURN&\ "Hit OK and then delete this behavior from the sprite."&RETURN&\ "For more information on deleting Behaviors, see the Help system." if the optionDown then return [ \ #getPDLError: \ [ \ #comment: "ERROR: Wrong member type. Click 'Cancel'.", \ #format: #string, \ #range: [""], \ #default: "" \ ] \ ] end if #invalidMemberType: -- Determine the behavior's name behaviorName = string (me) delete word 1 of behaviorName delete the last word of behaviorName delete the last word of behaviorName alert \ "BEHAVIOR ERROR: Frame "&the frame&", Sprite "&me.spriteNum&RETURN&RETURN&\ "Behavior "&behaviorName&" only functions with the following member types:"&RETURN&permittedMemberTypes()&RETURN&RETURN&\ "Current type = #"&data halt end case end ErrorAlert on PermittedMemberTypes me -- sent by: -- getBehaviorDescription -- getPropertyDescriptionList -- Initialize return [#bitmap, #flash, #vectorShape, #text] end PermittedMemberTypes -- AUTHOR-DEFINED PARAMETERS -- on getPropertyDescriptionList me if not the currentSpriteNum then exit -- Error check: does current sprite contain appropriate member type? theMember = sprite(the currentSpriteNum).member memberType = theMember.type permittedTypes = PermittedMemberTypes(me) if not permittedTypes.getPos(memberType) then return errorAlert (me, #getPDLError, permittedTypes) end if -- No errors detected: continue as usual ... return \ [ \ #myOrientation: \ [ \ #comment: "Turn", \ #format: #string, \ #range: ["towards the mouse", "away from the mouse"], \ #default: "towards" \ ], \ #myActivePeriod: \ [ \ #comment: EMPTY, \ #format: #string, \ #range: \ [ \ "while the mouse is down", \ "while the mouse is up", \ "when the mouse is clicked", \ "when the mouse is released", \ "always" \ ], \ #default: "while the mouse is down" \ ], \ #myResetFlag: \ [ \ #comment: "Otherwise", \ #format: #string, \ #range: ["return to the initial position", "remain in the new position"], \ #default: "return to the initial position" \ ] \ ] end getPropertyDescriptionList on getBehaviorTooltip me return \ "Use with Bitmap, Flash and Vector Shape members."&RETURN&RETURN&\ "Orients a sprite to face towards or away from"&RETURN&\ "the mouse pointer, even if the sprite is moving."&RETURN&RETURN&\ "You can make the sprite face the mouse at all"&RETURN&\ "times, or only when the mouse is up or down."&RETURN&\ "When the mouse is in the other state, the sprite"&RETURN&\ "can either revert to its original postion, or"&RETURN&\ "remain in the position it was in when the mouse"&RETURN&\ "state changed."&RETURN&RETURN&\ "The member is considered to face right at rest." end getBehaviorTooltip on getBehaviorDescription me return \ "TURN TOWARDS MOUSE"&RETURN&RETURN&\ "Orients a sprite to face (or turn away from) the mouse pointer, "&\ "even if the sprite is moving."&RETURN&RETURN&\ "You can choose whether the sprite always turns to face the mouse, "&\ "or only when the mouse button is up or down. When the mouse is "&\ "in the other state, the sprite will either return to its initial "&\ "position, or remain in the position it was in when the mouse "&\ "state changed."&RETURN&RETURN&\ "The graphic member is considered to face right when it is at rest."&\ RETURN&RETURN&\ "PERMITTED MEMBER TYPES:"&RETURN&\ PermittedMemberTypes(me)&RETURN&RETURN&\ "PARAMETERS:"&RETURN&\ "* Turn the mouse"&RETURN&\ "* "&RETURN&\ "* Otherwise: " end getBehaviorDescription