Code: Select all
;------------------------------------------------------
;
;- Animated Sprites
; author: citystate (novaseer@hotmail.com)
;
; create an animated sprite: *sprite.spr=newSprite(SpriteNumber,Default_Action$)
; and then add frames: *sprite\AddSprite(SpriteNumber,Action$)
; create additional actions: *sprite\NewAction(New_Action$)
; display the sprite: *sprite\DisplaySprite(x,y)
; and add frames to it as above.
; each time you display the animated sprite, it will show the next frame;
; until it reaches the last one, where the sprite will freeze,
; unless it is set to repeat: *sprite\Repeating(#True)
;
; change the current action: *sprite\SetAction(Action$)
;
; I've included a simple demo in the code, left and right click change the animation, and Alt-F4
; quits the program - enjoy
;
;------------------------------------------------------
Global NewMap map_()
;-Structures
Structure sp_1
List Sprite.i()
EndStructure
Structure sp
vt.i
Map action.sp_1()
rep.b
def.s
cur.s
w.w
h.w
EndStructure
;-Interfaces
Interface Spr
AddSprite(SpriteID,action$)
Collision(spriteID,x,y,my_x,my_y)
CurrentSprite()
DisplaySprite(x,y,intensity=0,color=0)
NewAction(action$)
Repeating(yes)
SetAction(action$)
Stopped()
ToString.s()
EndInterface
;-Declares
Declare NewSprite(SpriteNo,defaultAction$="default")
Declare sp_AddSprite(*o.sp,SpriteID,action$)
Declare sp_Collision(*o.sp,spriteID,x,y,my_x,my_y)
Declare sp_CurrentSprite(*o.sp)
Declare sp_DisplaySprite(*o.sp,x,y,intensity=0,color=0)
Declare sp_NewAction(*o.sp,action$)
Declare sp_Repeating(*o.sp,yes)
Declare sp_SetAction(*o.sp,action$)
Declare sp_Stopped(*o.sp)
Declare.s sp_ToString(*o.sp)
;-Datasection
DataSection
sp_vt:
Data.i @sp_AddSprite()
Data.i @sp_Collision()
Data.i @sp_CurrentSprite()
Data.i @sp_DisplaySprite()
Data.i @sp_NewAction()
Data.i @sp_Repeating()
Data.i @sp_SetAction()
Data.i @sp_Stopped()
Data.i @sp_ToString()
EndDataSection
Procedure sp_AddSprite(*o.sp,SpriteID,action$)
*mi.sp_1=FindMapElement(*o\action(),action$)
If *mi=0 And action$
*mi=AddMapElement(*o\action(),action$)
EndIf
If *mi And IsSprite(SpriteID)
AddElement(*mi\Sprite())
*mi\Sprite()=SpriteID
EndIf
EndProcedure
Procedure sp_Collision(*o.sp,spriteID,x,y,my_x,my_y)
sp=sp_CurrentSprite(*o)
If IsSprite(sp) And IsSprite(SpriteID)
ProcedureReturn SpritePixelCollision(SpriteID,x,y,sp,my_x,my_y)
EndIf
EndProcedure
Procedure sp_CurrentSprite(*o.sp)
ProcedureReturn *o\action(*o\cur)\Sprite()
EndProcedure
Procedure sp_DisplaySprite(*o.sp,x,y,intensity=0,color=0)
ne=NextElement(*o\action(*o\cur)\Sprite())
If ne=0
If *o\rep=1
ne=FirstElement(*o\action(*o\cur)\Sprite())
Else
ne=LastElement(*o\action(*o\cur)\Sprite())
*o\rep=2
EndIf
EndIf
If ne:sp=sp_CurrentSprite(*o):EndIf
If IsSprite(sp)
If intensity
If color
DisplayTransparentSprite(sp,x,y,intensity,color)
Else
DisplayTransparentSprite(sp,x,y,intensity)
EndIf
Else
DisplayTransparentSprite(sp,x,y)
EndIf
EndIf
EndProcedure
Procedure sp_NewAction(*o.sp,action$)
If action$ And FindMapElement(*o\action(),action$)=0
AddMapElement(*o\action(),action$)
EndIf
EndProcedure
Procedure sp_Repeating(*o.sp,yes)
*o\rep=Bool(yes)
EndProcedure
Procedure sp_SetAction(*o.sp,action$)
If FindMapElement(*o\action(),action$)
*o\cur=action$
FirstElement(*o\action(action$)\Sprite())
EndIf
EndProcedure
Procedure sp_Stopped(*o.sp)
ProcedureReturn Bool(*o\rep=2)
EndProcedure
Procedure.S sp_ToString(*o.sp)
a$="[Spr:"+Str(*o)+"]"+#CRLF$+"ACTION"+#TAB$+"FRAMES"+#CRLF$
ForEach *o\action()
a$+MapKey(*o\action())+#TAB$+Str(ListSize(*o\action()\Sprite()))+#CRLF$
Next
ProcedureReturn a$
EndProcedure
Procedure NewSprite(SpriteNo,defaultAction$="default")
If defaultAction$ And IsSprite(SpriteNo)
*i.sp=AllocateMemory(SizeOf(sp))
InitializeStructure(*i,sp)
*i\vt=?sp_vt
*i\w=SpriteWidth(SpriteNo)
*i\h=SpriteHeight(SpriteNo)
*i\def=defaultAction$
*i\cur=defaultAction$
sp_AddSprite(*i,SpriteNo,defaultAction$)
AddMapElement(map_(),Str(*i))
EndIf
ProcedureReturn *i
EndProcedure
;------------------------------------------------------
Procedure newCursor(col)
im=CreateSprite(-1,21,21)
StartDrawing(SpriteOutput(im))
LineXY(0,0,20,15,#White)
LineXY(20,15,15,20,#White)
LineXY(0,0,15,20,#White)
FillArea(10,10,#White,col)
StopDrawing()
TransparentSpriteColor(im,0)
ProcedureReturn im
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
Procedure newCursorBusy(col,ang)
im=CreateSprite(-1,21,21,#PB_Sprite_AlphaBlending)
r=Red(col)
g=Green(col)
b=Blue(col)
c0=RGBA(r,g,b,0)
c5=RGBA(r,g,b,255)
StartDrawing(SpriteOutput(im))
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0,21,21,0)
DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Gradient)
GradientColor(0,c0)
GradientColor(1,c5)
ConicalGradient(10,10,0)
Circle(10,10,10,1)
DrawingMode(#PB_2DDrawing_AllChannels)
Circle(10,10,6,0)
StopDrawing()
RotateSprite(im,ang,#PB_Absolute)
ProcedureReturn im
EndProcedure
InitSprite()
InitMouse()
OpenWindow(0,0,0,300,600,"")
OpenWindowedScreen(WindowID(0),0,0,300,600)
*mouseSpr.Spr=NewSprite(newCursor(#Blue/2))
*mouseSpr\Repeating(1)
For i=1 To 360 Step 9
im=newCursorBusy(#White,i)
*mouseSpr\AddSprite(im,"busy")
Next
Debug *mouseSpr\ToString()
Repeat
ExamineMouse()
x=MouseX()
y=MouseY()
m1=MouseButton(1)
m2=MouseButton(2)
If m1 And om=0
*mouseSpr\SetAction("busy")
om=1
EndIf
If m2 And om=1
*mouseSpr\SetAction("default")
om=0
EndIf
ClearScreen(#Blue)
*mouseSpr\DisplaySprite(x,y)
Delay(0)
FlipBuffers()
Until WindowEvent()=#PB_Event_CloseWindow
CompilerEndIf