Thanks a lot for this collection of beautiful graphics effects! I really enjoyed all of them!
The rotating gears are one of my favorites, so I decided to give it a personal touch...
Code: Select all
EnableExplicit
InitSprite()
Enumeration
#MainWindow
EndEnumeration
#GEAR_TEETH_SCALE = 6 ; Scale factor for converting teeth count to radius
#GEAR_HUB_RATIO = 4 ; Ratio of gear radius to hub radius
#TOOTH_AMPLITUDE = 15 ; Amplitude of gear teeth
#GEAR_PADDING = 12 ; Additional padding around gear
#ANGLE_INCREMENT = 0.015 ; Angle increment for tooth generation
Structure Gear
sprite.i ; Gear sprite
positionX.l ; X position on canvas
positionY.l ; Y position on canvas
radius.l ; Radius including teeth
rotationSpeed.f ; Speed of rotation (proportional to the teeth count)
EndStructure
Global NewList Gears.Gear()
Macro LimitToothDepth(angle)
Max(Min(Sin(angle), 0.7), -0.6)
EndMacro
Procedure.f Max(a.f, b.f) : If a > b : ProcedureReturn a : EndIf : ProcedureReturn b : EndProcedure
Procedure.f Min(a.f, b.f) : If a < b : ProcedureReturn a : EndIf : ProcedureReturn b : EndProcedure
Procedure CreateGear(centerX.l, centerY.l, teethCount.l, index.l, direction.l, gearColor.l)
Protected *gear.Gear = AddElement(Gears())
If *gear
Protected.f angleStep, gearRadius, hubRadius, phase, radius
Protected.f x, y
gearRadius = (teethCount * #GEAR_TEETH_SCALE) * DesktopResolutionX()
hubRadius = gearRadius * 0.5
centerX * DesktopResolutionX()
centerY * DesktopResolutionY()
*gear\positionX = centerX - gearRadius
*gear\positionY = centerY - gearRadius
*gear\rotationSpeed = direction / teethCount
*gear\radius = gearRadius + #GEAR_PADDING
centerX = gearRadius + #GEAR_PADDING
centerY = gearRadius + #GEAR_PADDING
Protected image = CreateImage(#PB_Any, *gear\radius * 2, *gear\radius * 2, 32, #PB_Image_Transparent)
If StartVectorDrawing(ImageVectorOutput(image))
angleStep = 0
Repeat
radius = gearRadius + #TOOTH_AMPLITUDE * LimitToothDepth(teethCount * angleStep)
x = centerX + radius * Cos(angleStep)
y = centerY + (radius * Sin(angleStep) * direction)
If angleStep = 0 : MovePathCursor(x, y) : EndIf
AddPathLine(x, y)
angleStep + #ANGLE_INCREMENT
Until angleStep >= (2 * #PI) + #ANGLE_INCREMENT
AddPathCircle(centerX, centerY, hubRadius)
AddPathCircle(centerX, centerY, hubRadius * 0.75)
VectorSourceColor(gearColor)
FillPath(#PB_Path_Preserve)
VectorSourceColor(RGBA(0, 0, 0, 64))
StrokePath(6, #PB_Path_Preserve)
VectorSourceColor(RGBA(0, 0, 0, 255))
StrokePath(3)
StopVectorDrawing()
*gear\sprite = CreateSprite(#PB_Any, ImageWidth(image), ImageHeight(image), #PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(*gear\sprite))
DrawAlphaImage(ImageID(image), 0, 0)
StopDrawing()
EndIf
FreeImage(image)
EndIf
EndIf
EndProcedure
DisableExplicit
InitSprite()
InitKeyboard()
screenWidth = 800
screenHeight = 600
windowFlags = #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered
If OpenWindow(#MainWindow, 0, 0, screenWidth, screenHeight, "Gear Animation", windowFlags)
If OpenWindowedScreen(WindowID(#MainWindow), 0, 0, DesktopScaledX(screenWidth), DesktopScaledY(screenHeight))
CreateGear(485, 220, 30, 1, -1, RGBA(205, 127, 50, 255))
CreateGear(215, 240, 15, 2, 1, RGBA(176, 196, 222, 255))
CreateGear(234, 372, 7, 4, -1, RGBA(184, 115, 51, 255))
CreateGear(83, 74, 20, 6, -1, RGBA(192, 192, 192, 255))
CreateGear(746, 414, 24, 3, 1, RGBA(205, 127, 50, 255))
CreateGear(-10, 518, 40, 5, 1, RGBA(170, 169, 173, 255))
CreateGear(705, 93, 12, 7, 1, RGBA(230, 232, 250, 255))
Repeat
Repeat
event = WindowEvent()
If event = #PB_Event_CloseWindow
Break 2
EndIf
Until Not event
currentAngle = ElapsedMilliseconds()
ClearScreen(RGB(128, 128, 128))
ForEach Gears()
With Gears()
RotateSprite(\sprite, currentAngle * \rotationSpeed, #PB_Absolute)
DisplayTransparentSprite(\sprite, \positionX + 15, \positionY + 15, 64, 0) ; shadow
DisplayTransparentSprite(\sprite, \positionX, \positionY)
EndWith
Next
FlipBuffers()
ForEver
EndIf
EndIf