

Rolling a Ball.
Added on 9/6/1999

How can I make a ball roll across a surface in director? I need the ball sprite to look like it is really rolling along the ground and not just spinning in mid air.
Get the source
Well, its time to dig out those high school geometry books, and lets do some calculating. Since we are working with a round object we can use Director 7 and the rotation property to allow the sprite to "roll". An immediate response would be to just spin the ball around while we move it, but this would kill the illusion. Another natural approach would be to roll the ball based on the length of a side of the bounding box, but this isn't quite right either. For this to work correctly, we need to use the formula for the circumference of a circle...
C = pD
(C = Pi * D)
Where C is the circumference and D is the diameter. Using this we can figure out what percentage of the ball's circumference we have moved along the surface and rotate the ball by the same percentage. If the ball's Diameter were 100 pixels, then the circumference would be approximately 314pixels. If we move the ball along the surface 157 pixels, then the ball would rotate 1/2 turn.
157 / 314 = 0.5
0.5 * 360 = 180
Therefore the ball would rotate 180 degrees. From this we can build a behavior that allows us to move the ball on the X axis (locH) and then use this position relative to its starting position to determine the amount to rotate the ball.
Copyright 1999 Chuck Neal
chuck@mediamacros.com
If you find this code helpful, send me an email and let me know. :)
property spriteNum, diameter, baseH, constraintSprite
on getPropertyDescriptionList me
p_list = [:]
p_list.addProp(#constraintSprite, [#format : #integer, #comment : "Sprite to roll on:", #default : (the currentSpriteNum + 1)])
return p_list
end
on beginSprite me
diameter = sprite(spriteNum).height
baseH = sprite(spriteNum).locH
end
on mouseDown me
startMouseH = the mouseH
startSpriteH = sprite(spriteNum).loch
repeat while the stillDown
hOffset = the mouseH  startMouseH
newLocH = startSpriteH + hOffset
if newLocH < sprite(constraintSprite).left then
newLocH = sprite(constraintSprite).left
else if newLocH > sprite(constraintSprite).right then
newLocH = sprite(constraintSprite).right
end if
get the rotation
percentage = (newLocH  baseH) / (diameter * pi)
sprite(spriteNum).rotation = 360 * percentage
sprite(spriteNum).locH = newLocH
updateStage
end repeat
end
on getBehaviorDescription me
return "This is a simple behavior for rolling a ball along a flat surface. Drop it on the bitmap sprite for the ball and assign the constraint sprite."
end
(Exhibit 1). Grab the ball and move it left and right to see it roll along the ground.
How can you take this to the next step? Try adding the ability to roll up and down as well as left and right. You can take a vector shape and roll along it based upon incremental points on its surface. Try calculating the distance each frame and let them roll on their own. Play with it and have fun.

