[MODULE] AnimSprite

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Imhotheb
Beiträge: 192
Registriert: 10.10.2014 13:14
Computerausstattung: Intel 8086, 640 KB RAM, Hercules Video Adapter, 2 x 5 1/4" 360kb Floppy, MS-DOS 3
Wohnort: Wolfenbüttel

[MODULE] AnimSprite

Beitrag von Imhotheb »

Ursprünglich war dieses Modul gedacht um animierte GIF's in Sprites aufzuteilen ... naja, wie das oft so ist ... könnte ich ja noch dies und das hinzufügen ... und das hier ist daraus gerworden. Viel Spass.

Code: Alles auswählen

; ############################################################################################
; #                                                                                          #
; # AnimSprite - Module                                                                      #
; #                                                                                          #
; ############################################################################################
; #                                                                                          #
; #     Author: Imhotheb (Andy)                                                              #
; #       Date: 2017-09-15                                                                   #
; #     Update: 2017-09-17                                                                   #
; #         OS: Windows, Linux (untested), OSX (untested)                                    #
; #   Compiler: 5.60+                                                                        #
; #     32 Bit: Yes                                                                          #
; #     64 Bit: Yes                                                                          #
; #    Unicode: doesn't matter (no Strings used)                                             #
; # Threadsafe: NO (Sprites/Screen are not threadsafe)                                       #
; #                                                                                          #
; ############################################################################################
; #                                                                                          #
; # Beschreibung/Description:                                                                #
; #                                                                                          #
; # Dieses Modul beinhaltet Fuktionen um einfach animierte Sprites (AnimSprites)             #
; # verwenden zu können.                                                                     #
; # AnimSprites können durch andere Sprites oder Bilder erstellt werden. Animierte GIF's     #
; # könne direkt in einen AnimSprite "umgewandelt" und sehr einfach dargestellt werden.      #
; # AnimSprites können (wie "normale" Sprites auch) rotiert, vergrößert/verkleinert und      #
; # "geclipped" werden. Zusätzlich kann die Geschwindigkeit eingestellt werden und           #
; # automatisch an die FPS angepasst werden.                                                 #
; #                                                                                          #
; # ---------------------------------------------------------------------------------------- #
; #                                                                                          #
; # This module includes functions for simple sprite animations (AnimSprites)                #
; # AnimSprites can be created by other sprites or images. Animated GIF's                    #
; # can be directly converted into an AnimSprite and displayed very easily.                  #
; # AnimSprites can be (like "normal" sprites also) rotated, zoomed in / out and             #
; # cutted. In addition, the speed can be set and can automatically adapted to the FPS.      #
; #                                                                                          #
; ############################################################################################
; #                                                                                          #
; # MIT License                                                                              #
; #                                                                                          #
; # Copyright (c) <2017> <Imhotheb>                                                          #
; #                                                                                          #
; # Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der             #
; # zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt,              #
; # sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht,                #
; # sie zu verwenden, zu kopieren, zu verändern, zusammenzufügen, zu veröffentlichen,        #
; # zu verbreiten, zu unterlizenzieren und/oder zu verkaufen, und Personen, denen diese      #
; # Software überlassen wird, diese Rechte zu verschaffen, unter den folgenden Bedingungen:  #
; #                                                                                          #
; # Der obige Urheberrechtsvermerk und dieser Erlaubnisvermerk sind in allen Kopien          #
; # oder Teilkopien der Software beizulegen.                                                 #
; #                                                                                          #
; # DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE GARANTIE BEREITGESTELLT,      #
; # EINSCHLIEßLICH DER GARANTIE ZUR BENUTZUNG FÜR DEN VORGESEHENEN ODER EINEM BESTIMMTEN     #
; # ZWECK SOWIE JEGLICHER RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM FALL   #
; # SIND DIE AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER SONSTIGE ANSPRÜCHE     #
; # HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG EINES VERTRAGES, EINES DELIKTES ODER         #
; # ANDERS IM ZUSAMMENHANG MIT DER SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE           #
; # ENTSTANDEN.                                                                              #
; #                                                                                          #
; # ---------------------------------------------------------------------------------------- #
; #                                                                                          #
; # Permission is hereby granted, free of charge, to any person obtaining a copy of          #
; # this software and associated documentation files (the "Software"), to deal in the        #
; # Software without restriction, including without limitation the rights to use, copy,      #
; # modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,      #
; # and to permit persons to whom the Software is furnished to do so,                        #
; # subject to the following conditions:                                                     #
; #                                                                                          #
; # The above copyright notice and this permission notice shall be included in all copies    #
; # or substantial portions of the Software.                                                 #
; #                                                                                          #
; # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,      #
; # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A            #
; # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       #
; # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION        #
; # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE           #
; # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                   #
; #                                                                                          #
; ############################################################################################
; #                                                                                          #
; # History:                                                                                 #
; #                                                                                          #
; # 170916    initiale Version                                                               #
; #                                                                                          #
; # 1709161 # Dokumentation verbessert                                                       #
; # 1709171 # Überprüfung bei CreateSpriteFromImages() hinzugefügt                           #
; # 1709172 + CreateCopy() hinzugefügt                                                       #
; # 1709173 # Ein Fehler in Add*() wurde behoben                                             #
; # 1709174 # Ein Fehler in GetSprite() wurde behoben                                        #
; # 1709175 # Ein Fehler in NextPos() wurde behoben                                          #
; # 1709175 + Parameter in Display*() für automatischen Richtungswechsel                     #
; #                                                                                          #
; #                                                                                          #
; ############################################################################################




DeclareModule AnimSprite
  
  #POS_First  = 0     ; Position: Anfang
  #POS_Last   = -1    ; Position: Ende
    
  ; Erzeugt einen leeren AnimSprite
  Declare Create()  ; liefert einen Pointer mit Mem_Struct zurück
  
  ; Erzeuge ein AnimSprite von mehreren Bildern (PB-Image mit SetImageFrame(), im Moment nur GIF's)
  Declare CreateFromImages(Image.i,                             ;= PB-Image
                            Width.i = -1,                        ;= Breite ... bei -1 bzw. #PB_Default wird die Breite des PB-Image ermittelt (mit ImageWidth())
                            Heigth.i = -1,                       ;= Höhe ... bei -1 bzw. #PB_Default wird die Höhe des PB-Image ermittelt (mit ImageHeigth())
                            Mode.i = #PB_Sprite_AlphaBlending,   ;= CreateSprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
                            TransparentSpriteColor = #Black,     ;= Hintergrundfarbe die Transparent wird ... siehe TransparentSpriteColor()
                            *LoadCallBack = #Null)               ;= CallBack für Ladeanzeige (ein Parameter (Interger) für Fortschritt) ... z.B. LCB(Value.i)
                                                                 ;  der Wert wird bei jedem Einzelbild aktualisiert ... (0 bis 1000)
    
  ; Zeigt ein AnimSprite transparent auf einem Screen an ... siehe DisplayTransparentSprite()
  Declare DisplayTransparent(*AnimSprite,                       ;= AnimSprite
                             x, y,                               ;= Koordinaten (Pixel)
                             Intensity = 255,                    ;= Intensität (0 = Transparent / 255 = Undurchsichtig)
                             Color = -1,                         ;= Farbe zum Darstellen des Sprite (RGB())
                             AutoDirection = #False)             ;= Automatischer Richtungswechsel (ändert automatisch Speed in +/-)
  
  
  ; Zeigt ein AnimSprite auf einem Screen an ... siehe DisplaySprite()
  Declare Display(*AnimSprite,                                  ;= AnimSprite
                  x, y,                                          ;= Koordinaten (Pixel)
                  AutoDirection = #False)                        ;= Automatischer Richtungswechsel (ändert automatisch Speed in +/-)
  
  ; Dreht einen AnimSprite ... siehe RotateSprite()
  Declare Rotate(*AnimSprite,                                   ;= AnimSprite
                 Angel.f,                                        ;= Winkel in Grad (0 bis 360 im Uhrzeigersinn)
                 Mode = #PB_Relative)                            ;= #PB_Absolute oder #PB_Relative
  
  ; Vergrößert/Verkleinert einen AnimSprite ... siehe ZoomSprite()
  Declare Zoom(*AnimSprite,                                     ;= AnimSprite
               Width,                                            ;= neue Breite / anfängliche Breite mit #PB_Default
               Heigth)                                           ;= neue Höhe / anfängliche Höhe mit #PB_Default
  
  ; Fügt einen Clip-Bereich hinzu ... siehe ClipSprite()
  Declare Clip(*AnimSprite,                                     ;= AnimSprite
               x = #PB_Default, y = #PB_Default,                 ;= Startposition ... #PB_Default entfernt das Clipping
               Width = #PB_Default, Heigth = #PB_Default)        ;= Größe ... #PB_Default entfernt das Clipping
  
  ; kopiert den AnimSprite mit allen Werten (Position / Speed / etc.) ... siehe CopySprite() ... WICHTIG: *OUT muss VORHER mit AnimSprite::Create() erzeugt worden sein !!
  Declare Copy(*In,                                             ;= zu Kopierender AnimSprite
               *Out,                                             ;= Ausgabe AnimSprite (muss mit AnimSprite::Create() erzeugt worden sein)
               Mode = #PB_Sprite_AlphaBlending,                  ;= CreateSprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
               TransparentSpriteColor = #Black)                  ;= Hintergrundfarbe die Transparent wird ... siehe TransparentSpriteColor()
  
  ; erzeugt einen AnimSprite mit dem Inhalt von *In
  Declare CreateCopy(*In,                                       ;= zu Kopierender AnimSprite
                     Mode = #PB_Sprite_AlphaBlending,            ;= CreateSprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
                     TransparentSpriteColor = #Black)            ;= Hintergrundfarbe die Transparent wird ... siehe TransparentSpriteColor()
  
  ; ändert die Richtung und Geschwindigkeit des Wechsel
  Declare SetSpeed(*Animsprite,                                 ;= AnimSprite
                   Speed.f)                                      ;= neue Geschwindigkeit/Richtung ( +1 = Vorwärts / -1 = Rückwärts / 0 = Standbild)
  
  ; gibt die aktuelle Geschwindkeit zurück
  Declare.f GetSpeed(*AnimSprite)                               ;= AnimSprite
  
  ; ändert die aktuelle Position
  Declare SetPos(*AnimSprite,                                   ;= AnimSprite
                 Pos.f)                                          ;= neue Position
  
  ; gibt die aktuelle Position zurück
  Declare.f GetPos(*AnimSprite)                                 ;= AnimSprite
  
  ; kopiert mehrere Bilder (PB-Image mit SetImageFrame(), im Moment nur GIF's) in einen AnimSprite
  Declare CopyFromImages(Image.i,                               ;= PB-Image
                         *Out,                                   ;= Ausgabe AnimSprite
                         Width.i = -1,                           ;= Breite ... bei -1 bzw. #PB_Default wird die Breite des PB-Image ermittelt (mit ImageWidth())
                         Heigth.i = -1,                          ;= Höhe ... bei -1 bzw. #PB_Default wird die Höhe des PB-Image ermittelt (mit ImageHeigth())
                         Mode.i = #PB_Sprite_AlphaBlending,      ;= CreateSprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
                         TransparentSpriteColor = #Black,        ;= Hintergrundfarbe die Transparent wird ... siehe TransparentSpriteColor()
                         *LoadCallBack = #Null)                  ;= CallBack für Ladeanzeige (ein Parameter (Interger) für Fortschritt) ... z.B. LCB(Value.i)
                                                                 ;  der Wert wird bei jedem Einzelbild aktualisiert ... (0 bis 1000)
  
  ; fügt einen Sprite zu einem AnimSprite hinzu
  Declare AddSprite(*AnimSprite,                                ;= AnimSprite
                    Sprite,                                      ;= #Sprite (PB-ID), nicht SpriteID()
                    Pos = AnimSprite::#POS_Last,                 ;= Position (folgende Sprites werden nach Hinten verschoben)
                    Copy = #False,                               ;= #True = der Sprite wird kopiert / #False = der Sprite wird direkt verwendet (und mit Free() auch gelöscht!!)
                    Mode = #Null)                                ;= CopySprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending) ... siehe CopySprite()
  
  ; kopiert ein (PB-)Image und fügt einen Sprite hinzu
  Declare AddImage(*AnimSprite,                                 ;= AnimSprite
                   Image,                                        ;= (PB-)Image
                   Pos = AnimSprite::#POS_Last,                  ;= Position (folgende Sprites werden nach Hinten verschoben)
                   Width = -1,                                   ;= Breite ... bei -1 bzw. #PB_Default wird die Breite des (PB-)Image ermittelt (mit ImageWidth())
                   Heigth = -1,                                  ;= Höhe ... bei -1 bzw. #PB_Default wird die Höhe des (PB-)Image ermittelt (mit ImageHeigth())
                   Mode = #PB_Sprite_AlphaBlending,              ;= CreateSprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
                   TransparentSpriteColor = #Black)              ;= Hintergrundfarbe die Transparent wird ... siehe TransparentSpriteColor()
  
  ; lädt einen Sprite aus einer Datei ... siehe LoadSprite()
  Declare AddLoadSprite(*AnimSprite,                            ;= AnimSprite
                        File.s,                                  ;= Dateiname
                        Pos = AnimSprite::#POS_Last,             ;= Position (folgende Sprites werden nach Hinten verschoben)
                        Mode = #Null)                            ;= LoadSprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
  
  ; fotografiert den Bildschirminhalt ... siehe GrabSprite()
  Declare AddGrabSprite(*AnimSprite,                            ;= AnimSprite
                        x, y,                                    ;= Startposition auf dem Bildschirm
                        Width, Heigth,                           ;= Größe
                        Pos = AnimSprite::#POS_Last,             ;= Position (folgende Sprites werden nach Hinten verschoben)
                        Mode = #Null)                            ;= GrabSprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
  
  ; lädt einen Sprite aus dem angegeben Speicherbereich ... siehe CatchSprite()
  Declare AddCatchSprite(*AnimSprite,                           ;= AnimSprite
                         *Ptr,                                   ;= Startadresse des Sprite/Images
                         Pos = AnimSprite::#POS_Last,            ;= Position (folgende Sprites werden nach Hinten verschoben)
                         Mode = #Null)                           ;= CatchSprite(..., Mode) (#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
  
  ; vertauscht die Position von zwei Sprites
  Declare SwitchSprite(*AnimSprite,                             ;= AnimSprite
                       Pos1, Pos2)                               ;= Positionen die getauscht werden (0 bis AnimSprite::MaxPos)
  
  ; löscht einen einzelnnen Sprite
  Declare DelSprite(*AnimSprite,                                ;= AnimSprite
                    Pos)                                         ;= Sprite-Position die gelöscht wird, verbleibende Sprites werden automatisch in ihrer Position angepasst
  
  ; löscht den AnimSprite, gibt alle mit ihm verbundenen Sprites und reservierten Speicher frei
  Declare Free(*AnimSprite)                                     ;= AnimSprite
  
  ; gibt die größtmögliche Position zurück
  Declare MaxPos(*AnimSprite)                                   ;= AnimSprite
  
  ; gibt die (PB-)ID eines einzelnen Sprite zurück (NICHT die SpriteID()!!)
  Declare GetSprite(*AnimSprite,                                ;= AnimSprite
                    Pos)                                         ;= Position des Sprite
  
  ; (er-)setzt einen anderen Sprite ein ... VORISCHT: der bereits eingetragene Sprite wird NICHT gelöscht und verbleibt im Speicher
  Declare SetSprite(*AnimSprite,                                ;= AnimSprite
                    Pos,                                         ;= Position für #Sprite
                    Sprite)                                      ;= #Sprite (PB-ID), nicht SpriteID()
  
  ; gibt die Breite eines Sprites zurück
  Declare Width(*AnimSprite,                                    ;= AnimSprite
                Pos = 0)                                         ;= Position
  
  ; gibt die Höhe eines Sprites zurück
  Declare Heigth(*AnimSprite,                                   ;= AnimSprite
                 Pos = 0)                                        ;= Position
  
  ; setzt einen Teiler für die Geschwindigkeit ... nützlich um verschiedene FPS auszugleichen ... für ALLE AnimSprites gütlig
  Declare SetSpeedDivider(Div.f)
  
  ; automatische Geschwindigkeitsanpassung ein-/ausschalten
  Declare AutoSpeed(Enabled = #True)                            ; #True / #False
  
  ; gibt den aktuellen Geschwindigkeitsteiler zurück 
  Declare.f GetSpeedDivider()
  
  ; gibt die Anzahl der einzelnen Sprites eines AnimSprites zurück
  Macro Size(__AnimSprite__)                                    ;= AnimSprite
    (AnimSprite::MaxFrame(__AnimSprite__) + 1)
  EndMacro
  
EndDeclareModule


Module AnimSprite    
  EnableExplicit
  
  ; Interne Konfiguration
  Structure Modul_Config
    Use_Speed_Divider.i
    Speed_Divider.f
  EndStructure  
  Global Conf.Modul_Config
  Conf\Speed_Divider = 1
    
  ; Interne Deklarationen
  ; ---------------------
  ; Macro für die Anzeige von Fehlern
  Macro DebugLog(__Text__)
    Debug __Text__
  EndMacro
  ; Struktur eines AnimSprite(-"Objekt/Handle/WhatEver")
  Structure Mem_Struct
    Frame_Max.i         ; Höchster Wert für Array (tatsächliche Größe = Frame_Max + 1)
    Pos.f               ; Aktuelle Position im Array
    Speed.f             ; Geschwindigkeit (Wechsel der einzelnen Sprites), bestimmt auch die Richtung (+/-)
    ;Width.i            ; Breite
    ;Heigth.i           ; Höhe
    ;Array Angle.f(0)   ; Gespeicherter Winkel für Sprite
    Array Sprite.i(0)  ; Sprite-Array
  EndStructure
  ; Prototyp für Ladestand
  Prototype LoadCallBack(Value.i)
  ; erzeuget ein Sprite aus einem (PB-)Image
  Procedure CreateSpriteFromImage(Image, Width = -1, Heigth = -1, Mode = #PB_Sprite_AlphaBlending, TransparentSpriteColor = #Black)
    Protected ret = #False
    
    If IsImage(Image)
      If Width < 0
        Width = ImageWidth(Image)
      EndIf
      If Heigth < 0
        Heigth = ImageHeight(Image)
      EndIf
      
      ret = CreateSprite(#PB_Any, Width, Heigth, Mode)
      If ret
        If StartDrawing(SpriteOutput(ret))
          DrawingMode(#PB_2DDrawing_AlphaBlend)
          DrawImage(ImageID(Image), 0, 0, Width, Heigth)
          StopDrawing()
          If mode & #PB_Sprite_AlphaBlending
            TransparentSpriteColor(ret, TransparentSpriteColor)
          EndIf        
        Else
          DebugLog("AnimSprite::CopyFromImage(): StartDrawing() failed")
        EndIf
      Else
        DebugLog("AnimSprite::CopyFromImage(): CreateSprite() failed")
      EndIf
      
    Else
      DebugLog("AnimSprite::CopyFromImage(): Image(" + Str(Image) + ") is not an image")
    EndIf
    
    ProcedureReturn ret
  EndProcedure
  ; fügt einen NICHT INITIALISIERTEN Sprite ein
  Procedure InsSprite(*AnimSprite.Mem_Struct, Pos = AnimSprite::#POS_Last)    
    Protected i, ret = #False
    
    If Pos < 0
      Pos = *AnimSprite\Frame_Max + 1
;     ElseIf Pos > *AnimSprite\Frame_Max + 1
;       Pos = *AnimSprite\Frame_Max + 1
    EndIf    
    
    If *AnimSprite
      *AnimSprite\Frame_Max + 1
      ReDim *AnimSprite\Sprite(*AnimSprite\Frame_Max)      
      For i = *AnimSprite\Frame_Max To Pos + 1 Step -1
        *AnimSprite\Sprite(i) = *AnimSprite\Sprite(i - 1)
      Next
      ; Reset Position
      AnimSprite::SetPos(*AnimSprite, 0)
      ret = *AnimSprite\Frame_Max
    Else
      DebugLog("AnimSprite::InsSprite(): *AnimSprite is NULL")
    EndIf
    
    ProcedureReturn ret    
  EndProcedure
  ; verschiebt die interne Position
  Procedure NextPos(*AnimSprite.Mem_Struct, AutoDirection = #False)
    Protected Speed.f
    
    If Conf\Use_Speed_Divider
      If Conf\Speed_Divider <> 0
        Speed = *AnimSprite\Speed / Conf\Speed_Divider
      Else
        Speed = *AnimSprite\Speed
      EndIf      
    Else
      Speed = *AnimSprite\Speed
    EndIf
    
      
    *AnimSprite\Pos + Speed
    If *AnimSprite\Speed > 0
      If Int(*AnimSprite\Pos) > *AnimSprite\Frame_Max
        If AutoDirection
          *AnimSprite\Speed = 0 - *AnimSprite\Speed
          *AnimSprite\Pos - Speed
        Else
          *AnimSprite\Pos = 0
        EndIf        
      EndIf
    ElseIf *AnimSprite\Speed < 0    
      If Int(*AnimSprite\Pos) < 0
        If AutoDirection
          *AnimSprite\Speed = 0 - *AnimSprite\Speed
          *AnimSprite\Pos - Speed
        Else
          *AnimSprite\Pos = *AnimSprite\Frame_Max
        EndIf
      EndIf
    EndIf    
    
  EndProcedure

  
  Procedure CopyFromImages(Image, *Out.Mem_Struct, Width = -1, Heigth = -1, Mode = #PB_Sprite_AlphaBlending, TransparentSpriteColor = #Black, *LoadCallBack = #Null)
    Protected i
    If *LoadCallBack
      Protected LCB.LoadCallBack = *LoadCallBack
    EndIf
    
    If *Out
      *Out\Frame_Max = ImageFrameCount(Image) - 1
      ReDim *Out\Sprite(*Out\Frame_Max)
      
      ; Jedes Einzelbild als Sprite erzeugen (nur bei GIF's)
      For i = 0 To *Out\Frame_Max
        SetImageFrame(Image, i)
        *Out\Sprite(i) = CreateSpriteFromImage(Image, Width, Heigth, Mode, TransparentSpriteColor)
        If LCB
          LCB((i + 1) * 1000 / *Out\Frame_Max)
        EndIf    
      Next
      
      ; Standartwerte setzen
      *Out\Speed = 1
      *Out\Pos = 0
    Else
      DebugLog("AnimSprite::CopyFromImages(): *Out is NULL")
    EndIf
    
    ProcedureReturn i + 1
  EndProcedure
  Procedure DisplayTransparent(*AnimSprite.Mem_Struct, x, y, Intensity = 255 , Color = -1, AutoDirection = #False)
    
    If *AnimSprite
      If *AnimSprite\Frame_Max >= 0
        DisplayTransparentSprite(*AnimSprite\Sprite(Int(*AnimSprite\Pos)), x, y, Intensity, Color)
        NextPos(*AnimSprite, AutoDirection)    ; nächste Position setzen
      Else
        DebugLog("AnimSprite::DisplayTransparent(): *AnimSprite is Not valid")
      EndIf  
    Else
      DebugLog("AnimSprite::DisplayTransparent(): *AnimSprite is NULL")
    EndIf
    
  EndProcedure
  Procedure Display(*AnimSprite.Mem_Struct, x, y, AutoDirection = #False)
 
    If *AnimSprite
      If *AnimSprite\Frame_Max >= 0
        DisplaySprite(*AnimSprite\Sprite(Int(*AnimSprite\Pos)), x, y)
        NextPos(*AnimSprite, AutoDirection)    ; nächste Position setzen
      Else
        DebugLog("AnimSprite::Display(): *AnimSprite is Not valid")
      EndIf  
    Else
      DebugLog("AnimSprite::Display(): *AnimSprite is NULL")
    EndIf
    
  EndProcedure
  Procedure Rotate(*AnimSprite.Mem_Struct, Angle.f, Mode = #PB_Relative)
    Protected i, ret = #False
    
    If *AnimSprite
      If *AnimSprite\Frame_Max >= 0
        For i = 0 To *AnimSprite\Frame_Max
          RotateSprite(*AnimSprite\Sprite(i), Angle, Mode)
        Next
        ret = #True
      Else
        DebugLog("AnimSprite::Rotate(): *AnimSprite is Not valid")
      EndIf  
    Else
      DebugLog("AnimSprite::Rotate(): *AnimSprite is NULL")
    EndIf
    
    ProcedureReturn ret
  EndProcedure
  Procedure Zoom(*AnimSprite.Mem_Struct, Width, Heigth)
    Protected i, ret = #False
    
    If *AnimSprite
      If *AnimSprite\Frame_Max >= 0
        For i = 0 To *AnimSprite\Frame_Max
          ZoomSprite(*AnimSprite\Sprite(i), Width, Heigth)
        Next
        ret = #True
      Else
        DebugLog("AnimSprite::Zoom(): *AnimSprite is Not valid")
      EndIf  
      
    Else
      DebugLog("AnimSprite::Zoom(): *AnimSprite is NULL")
    EndIf
    
    ProcedureReturn ret
  EndProcedure
  Procedure Clip(*AnimSprite.Mem_Struct, x = #PB_Default, y = #PB_Default, Width = #PB_Default, Heigth = #PB_Default)
    Protected i
    If *AnimSprite
      If *AnimSprite\Frame_Max >= 0
        For i = 0 To *AnimSprite\Frame_Max
          ClipSprite(*AnimSprite\Sprite(i), x, y, Width, Heigth)
        Next
      Else
        DebugLog("AnimSprite::Clip(): *AnimSprite is NOT valid")
      EndIf  
    Else
      DebugLog("AnimSprite::Clip(): *AnimSprite is NULL")
    EndIf
    
  EndProcedure  
  Procedure Copy(*In.Mem_Struct, *Out.Mem_Struct, Mode = #PB_Sprite_AlphaBlending, TransparentSpriteColor = #Black)
    Protected i
    
    If *In
      If *In\Frame_Max >= 0
        If *Out
          ReDim *Out\Sprite(*In\Frame_Max)
          ;  ReDim *Out\Angle(*In\Frame_Max)
          
          For i = 0 To *In\Frame_Max
            *Out\Sprite(i) = CopySprite(*In\Sprite(i), #PB_Any, Mode)
            ;    *Out\Angle(i) = *In\Angle(i)
            If Mode & #PB_Sprite_AlphaBlending
              TransparentSpriteColor(*Out\Sprite(i), TransparentSpriteColor)
            EndIf        
          Next
          *Out\Frame_Max = *In\Frame_Max
          *Out\Pos = *In\Pos
          *Out\Speed = *In\Speed
        Else
          DebugLog("AnimSprite::Copy(): *Out is NULL")
        EndIf
      Else
        DebugLog("AnimSprite::DisplayTransparent(): *In (AnimSprite) is Not valid")
      EndIf  
      
    Else
      DebugLog("AnimSprite::Copy(): *In is NULL")
    EndIf
    
  EndProcedure
 
  Procedure SetPos(*AnimSprite.Mem_Struct, Pos.f)
    
    If Pos < 0        ; Für #POS_Last
      Pos = *AnimSprite\Frame_Max
    ElseIf Pos > *AnimSprite\Frame_Max
      Pos = *AnimSprite\Frame_Max
    EndIf
    
    *AnimSprite\Pos = Pos
  EndProcedure
  Procedure.f GetPos(*AnimSprite.Mem_Struct)
    
    ProcedureReturn *AnimSprite\Pos
  EndProcedure
  Procedure SetSpeed(*Animsprite.Mem_Struct, Speed.f)
    
    *Animsprite\Speed = Speed    
  EndProcedure
  Procedure.f GetSpeed(*AnimSprite.Mem_Struct)
    
    ProcedureReturn *AnimSprite\Speed
  EndProcedure
  
  Procedure MaxPos(*AnimSprite.Mem_Struct)
    
    ProcedureReturn *AnimSprite\Frame_Max
  EndProcedure
  Procedure GetSprite(*AnimSprite.Mem_Struct, Pos)
    Protected ret = #False
    
    If Pos <= *AnimSprite\Frame_Max And Pos >= 0
      If IsSprite(*AnimSprite\Sprite(Pos))
        ret = *AnimSprite\Sprite(Pos)        
      EndIf      
    EndIf
      
    ProcedureReturn ret
  EndProcedure
  Procedure SetSprite(*AnimSprite.Mem_Struct, Pos, Sprite)
    If IsSprite(Sprite)
      *AnimSprite\Sprite(Pos) = Sprite
    EndIf
    
  EndProcedure
  Procedure Width(*AnimSprite.Mem_Struct, Pos = 0)
    Protected ret = 0
    
    If Pos <= *AnimSprite\Frame_Max And Pos >= 0
      If IsSprite(*AnimSprite\Sprite(Pos))
        ret = SpriteWidth(*AnimSprite\Sprite(Pos))
      EndIf
    EndIf
    
    ProcedureReturn ret
  EndProcedure
  Procedure Heigth(*AnimSprite.Mem_Struct, Pos = 0)
    Protected ret = 0
    
    If Pos <= *AnimSprite\Frame_Max And Pos >= 0
      If IsSprite(*AnimSprite\Sprite(Pos))
        ret = SpriteHeight(*AnimSprite\Sprite(Pos))
      EndIf
    EndIf
    
    ProcedureReturn ret
  EndProcedure
  
  Procedure AddSprite(*AnimSprite.Mem_Struct, Sprite, Pos = AnimSprite::#POS_Last, Mode = #Null, Copy = #False)

    If Pos < 0
      Pos = *AnimSprite\Frame_Max + 1
    EndIf
    
    If Pos <= *AnimSprite\Frame_Max + 1 And Pos >= 0
      If IsSprite(Sprite)
        If Copy
          Sprite = CopySprite(Sprite, #PB_Any, Mode)
        EndIf
        InsSprite(*AnimSprite, Pos)
        *AnimSprite\Sprite(Pos) = Sprite        
      Else
        DebugLog("AnimSprite::AddSprite(): Sprite (ID:" + Str(Sprite) + ") is not a sprite")
      EndIf
    EndIf
    
  EndProcedure
  Procedure AddImage(*AnimSprite.Mem_Struct, Image, Pos = AnimSprite::#POS_Last, Width = -1, Heigth = -1, Mode = #PB_Sprite_AlphaBlending, TransparentSpriteColor = #Black)
    
    If Pos < 0
      Pos = *AnimSprite\Frame_Max + 1
    EndIf
    
    If Pos <= *AnimSprite\Frame_Max + 1 And Pos >= 0
      If IsImage(Image)
        InsSprite(*AnimSprite, Pos)
        *AnimSprite\Sprite(Pos) = CreateSpriteFromImage(Image, Width, Heigth, Mode, TransparentSpriteColor)        
      Else
        DebugLog("AnimSprite::AddImage(): Image (ID:" + Str(Image) + ") is not an image")
      EndIf
    EndIf
    
  EndProcedure
  Procedure AddLoadSprite(*AnimSprite.Mem_Struct, File.s, Pos = AnimSprite::#POS_Last, Mode = #Null)
    
    If Pos < 0
      Pos = *AnimSprite\Frame_Max + 1
    EndIf
    
    If Pos <= *AnimSprite\Frame_Max + 1 And Pos >= 0
      If FileSize(File) > 0
        InsSprite(*AnimSprite, Pos)
        *AnimSprite\Sprite(Pos) = LoadSprite(#PB_Any, File, Mode)
      Else
        DebugLog("AnimSprite::AddLoadSprite(): Error reading file (" + File + ")")
      EndIf
    EndIf
    
  EndProcedure
  Procedure AddGrabSprite(*AnimSprite.Mem_Struct, x, y, Width, Heigth, Pos = AnimSprite::#POS_Last, Mode = #Null)
    
    If Pos < 0
      Pos = *AnimSprite\Frame_Max + 1
    EndIf
    
    If Pos <= *AnimSprite\Frame_Max + 1 And Pos >= 0
        InsSprite(*AnimSprite, Pos)
        *AnimSprite\Sprite(Pos) = GrabSprite(#PB_Any, x, y, Heigth, Width, Mode)
    EndIf
    
  EndProcedure
  Procedure AddCatchSprite(*AnimSprite.Mem_Struct, *Ptr, Pos = AnimSprite::#POS_Last, Mode = #Null)
    Protected Sprite
    
    If Pos < 0
      Pos = *AnimSprite\Frame_Max + 1
    EndIf
    
    If Pos <= *AnimSprite\Frame_Max + 1 And Pos >= 0
      Sprite = CatchSprite(#PB_Any, *Ptr, Mode)      
      If IsSprite(Sprite)
        InsSprite(*AnimSprite, Pos)
        *AnimSprite\Sprite(Pos) = Sprite        
      Else
        DebugLog("AnimSprite::AddCatchSprite(): Sprite(@" + Str(*Ptr) + ") could not be read")
      EndIf
    EndIf
    
  EndProcedure
  
  Procedure Create()
    Protected *Dummy.Mem_Struct = AllocateStructure(Mem_Struct)    
    
    If *Dummy
      *Dummy\Frame_Max = -1
      *Dummy\Pos = -1
      *Dummy\Speed = 0
      *Dummy\Sprite(0) = 0
    Else
      DebugLog("AnimSprite::Create(): Allocate memory failed")
    EndIf    
    
    ProcedureReturn *Dummy
  EndProcedure
  Procedure CreateFromImages(Image, Width = -1, Heigth = -1, Mode = #PB_Sprite_AlphaBlending, TransparentSpriteColor = #Black, *LoadCallBack = #Null)
    Protected *AnimSprite = AnimSprite::Create()    
    
    If *AnimSprite
      CopyFromImages(Image, *AnimSprite, Width, Heigth, Mode, TransparentSpriteColor, *LoadCallBack)
    EndIf      
    
    ProcedureReturn *AnimSprite
  EndProcedure
  Procedure CreateCopy(*In.Mem_Struct, Mode = #PB_Sprite_AlphaBlending, TransparentSpriteColor = #Black)
    Protected *AnimSprite = AnimSprite::Create()
    
    If *AnimSprite
      AnimSprite::Copy(*In, *AnimSprite, Mode, TransparentSpriteColor)
    EndIf
    
    ProcedureReturn *AnimSprite
  EndProcedure  
  Procedure SwitchSprite(*AnimSprite.Mem_Struct, Pos1, Pos2)
    Protected Temp_Sprite
    
    If Pos1 <= *AnimSprite\Frame_Max And Pos1 >= 0
      If Pos2 <= *AnimSprite\Frame_Max And Pos2 >= 0
        Temp_Sprite = *AnimSprite\Sprite(Pos1)
        *AnimSprite\Sprite(Pos1) = *AnimSprite\Sprite(Pos2)
        *AnimSprite\Sprite(Pos2) = Temp_Sprite
      EndIf
    EndIf
    
  EndProcedure
  Procedure DelSprite(*AnimSprite.Mem_Struct, Pos)
    Protected i
    
    If Pos <= *AnimSprite\Frame_Max And Pos >= 0
      If IsSprite(*AnimSprite\Sprite(Pos))
        FreeSprite(*AnimSprite\Sprite(Pos))        
      EndIf
      
      For i = Pos To *AnimSprite\Frame_Max
        *AnimSprite\Sprite(i) = *AnimSprite\Sprite(i + 1)
      Next
      
      *AnimSprite\Frame_Max - 1
      ReDim *AnimSprite\Sprite(*AnimSprite\Frame_Max)
    EndIf
        
  EndProcedure
  Procedure Free(*AnimSprite.Mem_Struct)
    Protected i, ret = #False
    
    For i = 0 To *AnimSprite\Frame_Max
      If IsSprite(*AnimSprite\Sprite(i))
        FreeSprite(*AnimSprite\Sprite(i))
        ret = #True
      Else
        ret = #False
        DebugLog("AnimSprite::Free(): Can't free Sprite(" + Str(*AnimSprite\Sprite(i)) + ")")
        Break
      EndIf
      
    Next
    
    If ret
      FreeStructure(*AnimSprite)
    EndIf
    
    ProcedureReturn ret
  EndProcedure
  
  Procedure SetSpeedDivider(Div.f)
    Conf\Speed_Divider = Div
  EndProcedure
  Procedure.f GetSpeedDivider()
    ProcedureReturn Conf\Speed_Divider
  EndProcedure
  Procedure AutoSpeed(Enabled = #True)
    Conf\Use_Speed_Divider = Enabled
  EndProcedure
  
  
EndModule
Das komplette .pbi (mit Beispiel) gibt hier: https://www.dropbox.com/s/myw4g7mfofilq ... e.pbi?dl=0
Zuletzt geändert von Imhotheb am 17.09.2017 19:46, insgesamt 5-mal geändert.
weil einfach einfach einfach ist ... mach' ich es anders
Benutzeravatar
Imhotheb
Beiträge: 192
Registriert: 10.10.2014 13:14
Computerausstattung: Intel 8086, 640 KB RAM, Hercules Video Adapter, 2 x 5 1/4" 360kb Floppy, MS-DOS 3
Wohnort: Wolfenbüttel

Re: [MODULE] AnimSprite

Beitrag von Imhotheb »

Da der Rest auch nicht in einen Beitrag passt, hier ein Link zum kompletten .pbi:
https://www.dropbox.com/s/myw4g7mfofilq ... e.pbi?dl=0
weil einfach einfach einfach ist ... mach' ich es anders
Antworten