[b2d] Strichfiguren Animationen

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

 

Rocys

Betreff: [b2d] Strichfiguren Animationen

BeitragFr, Aug 13, 2010 15:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,
ich hab ein kleines Programm für alle, die nicht zeichnen können.
Man kann damit 2d Animationen von Strichmännchen (oder ähnlichen Figuren) erstellen, speichern, laden und als Bmp exportieren.

Bedienung:
zu Anfang muss man einen Dateinamen eingeben. Dies kann entweder eine Animation oder ein Template sein.

Linke Maustaste=Punkt auswählen
Rechte Maustaste=Punkt verschieben (geht nur, wenn der Punkt kein Parent hat)
Mausrad=Punkt drehen
q=vorheriges Frame
w=nächstes Frame
e=Animation als Reihe nummerierter Bitmaps exportieren
enter=komplettes Frame ins nächste Frame kopieren und dorthin wechseln
leertaste=nur die Änderungen an einem Punkt ins nächste Frame kopieren und dorthin wechseln
p(gedrückt halten)=Animation abspielen

Ohne ein Template geht das Programm gar nicht, aber wie erstelle ich ein Template? Einfach eine Textdatei erstellen, in die man alle Punkte der Figur einträgt. Das geht wie folgt:
name= erstellt einen neuen Punkt und benennt ihn
x(-1)= gibt die X-Koordinate des Punktes an
y(-1)= gibt die Y-Koordinate des Punktes an
parent= Hier muss man, wenn der Punkt an einem anderen dranhängen soll, den Namen des anderen Punktes angeben (Beispiel siehe weiter unten)
lentgth= Wie weit ist der Punkt von seinem Parent-Punkt entfernt?
angle(-1)= in welchem Winkel steht der Punkt zu seinem Parent-Punkt(danach werden dann auch die Koordinaten berechnet)

Hier mal ein Beispiel-Template:
Code: [AUSKLAPPEN]

name=hip
x(-1)=0
y(-1)=0

name=upperlegleft
parent=hip
length=32
angle(-1)=105

name=upperlegright
parent=hip
length=32
angle(-1)=75

name=lowerlegleft
parent=upperlegleft
length=32
angle(-1)=90

name=lowerlegright
parent=upperlegright
length=32
angle(-1)=90

name=body
parent=hip
length=48
angle(-1)=270

name=head
parent=body
length=16
angle(-1)=270

name=upperarmright
parent=body
length=24
angle(-1)=45

name=upperarmleft
parent=body
length=24
angle(-1)=135

name=lowerarmright
parent=upperarmright
length=24
angle(-1)=90

name=lowerarmleft
parent=upperarmleft
length=24
angle(-1)=90


Und zum Schluss natürlich das Programm:

Code: [AUSKLAPPEN]

Graphics 1024,1024,16,2
SetBuffer BackBuffer()
Global Timer=CreateTimer(60)
Global Grid%=CreateImage(1024,1024)

Global FrameNow%=0
SetBuffer ImageBuffer(Grid)
Local i%
For i=0 To 31
   If i Mod 8=0 Then
      Color 64,64,64
   ElseIf i Mod 4=0 Then
      Color 32,32,32
   Else
      Color 16,16,16
   End If
   
   Line i*32,0,i*32,1024
   Line 0,i*32,1024,i*32
Next
SetBuffer BackBuffer()

Type Pivot
   Field X#[29]
   Field Y#[29]
   Field Name$
   Field Parent.Pivot
   Field length%
   Field Angle%[29]
End Type
Global Selected.Pivot
Local pivot.Pivot
Color 255,255,255
Global AnimationName$=Input("Enter Filename: ")
AnimationLoad(AnimationName)
FlushKeys
Origin 512,512
Repeat
   Cls
   Control
   DrawImage Grid,-512,-512
   AnimationRender
   WaitTimer Timer
   Flip 0
Until KeyDown(1)
FlushKeys()
Cls
Color 255,255,255
Local saveMe$=Input("Save File(y/n)?")
If Lower(saveMe)><"y" Then End
AnimationSave(Input("Enter Filename: "))

Function AnimationCopyFrameToNextFrame(frame%)
   frame=(frame+30)Mod 30
   Local nextFrame%=(frame+1)Mod 30
   Local pivot.Pivot
   For pivot.Pivot=Each Pivot
      pivot\X[nextFrame]=pivot\X[frame]
      pivot\Y[nextFrame]=pivot\Y[frame]
      pivot\Angle[nextFrame]=pivot\Angle[frame]
   Next
   AnimationUpdate(nextFrame)
   Return nextFrame
End Function

Function AnimationExport()
   Cls
   Flip
   Local DistanceBiggest%=-20000,imageSize%
   Local pivot.Pivot,i%
   Local frame%,image%
   For i=0 To 29
      For pivot.Pivot=Each Pivot
         If Abs(pivot\X[i])>DistanceBiggest Then DistanceBiggest=Abs(pivot\X[i])
         If Abs(pivot\Y[i])>DistanceBiggest Then DistanceBiggest=Abs(pivot\Y[i])
         DebugLog DistanceBiggest
      Next
   Next
   Select True
      Case DistanceBiggest<=16
         imageSize=64
      Case DistanceBiggest<=32
         imageSize=128
      Case DistanceBiggest<=64
         imageSize=256
      Case DistanceBiggest<=128
         imageSize=512
      Case DistanceBiggest<=256
         imageSize=1024
      Default
         imageSize=2048
   End Select
   image=CreateImage(imageSize,imageSize)
   SetBuffer ImageBuffer(image)
   Origin imageSize/2,imageSize/2
   For frame=0 To 29
      Cls
      Color 255,255,255
      For pivot.Pivot=Each Pivot
         If pivot\Parent><Null
            Line pivot\X[frame],pivot\Y[frame],pivot\Parent\X[frame],pivot\Parent\Y[frame]   
         End If
      Next
      SaveImage image,AnimationName+frame+".bmp"
   Next
   SetBuffer BackBuffer()
   Origin 512,512
End Function

Function AnimationLoad(FileName$)
   Local Stream%=loadfile(FileName)
   Local trash$,i%
   Local pivot.Pivot
   Local parent.Pivot
   Repeat
      trash$=readMODline(Stream)
      Select MODorder
         Case"name"
            pivot.Pivot=New Pivot
            pivot\Name$=MODvalue
         Case "x"
            If MODparameter=-1 Then
               For i=0 To 29
                  pivot\X[i]=Float(MODvalue)
               Next
            Else
               pivot\X[MODparameter]=Float(MODvalue)
            End If
         Case "y"
            If MODparameter=-1 Then
               For i=0 To 29
                  pivot\Y[i]=Float(MODvalue)
               Next
            Else
               pivot\Y[MODparameter]=Float(MODvalue)
            End If
         Case "angle"
            If MODparameter=-1 Then
               For i=0 To 29
                  pivot\Angle[i]=Int(MODvalue)
               Next
            Else
               pivot\Angle[MODparameter]=Float(MODvalue)
            End If
         Case "length"
            pivot\length=Int(MODvalue)
            
         Case "parent"
            For parent.Pivot=Each Pivot
               If parent\Name=MODvalue Then pivot\Parent=parent
            Next
            
         Default
      End Select
      
   Until Eof(Stream)
   CloseFile(Stream)
   For i=0 To 29
      AnimationUpdate(i)
   Next
End Function

Function AnimationSave(FileName$)
   Local stream%=WriteFile(FileName)
   Local i%,pivot.Pivot
   For pivot.Pivot=Each Pivot
      WriteLine stream,"name="+pivot\Name
      If pivot\Parent>< Null Then WriteLine stream,"parent="+pivot\Parent\Name
      WriteLine stream,"length="+pivot\length
      For i=0 To 29
         WriteLine stream,"angle("+i+")="+pivot\Angle[i]
         WriteLine stream,"x("+i+")="+pivot\X[i]
         WriteLine stream,"y("+i+")="+pivot\Y[i]
      Next
      
   Next
   CloseFile FileName
End Function

Function AnimationRender()
   Local i%,frame%
   Local pivot.Pivot
   For i=FrameNow-1 To FrameNow
      
      frame=(i+30) Mod 30
      For pivot.Pivot=Each Pivot
         Select i
            Case FrameNow-1
               Color 128,64,64
               ;If pivot=Selected Then Color 0,0,255
               
            Case FrameNow
               Color 255,32,32
               If pivot=Selected Then Color 0,255,0
         End Select
         
         Rect pivot\X[frame]-3,pivot\Y[frame]-3,7,7,0
         If pivot\Parent><Null Then
            Line pivot\X[frame],pivot\Y[frame],pivot\Parent\X[frame],pivot\Parent\Y[frame]   
         End If
      Next
   Next
End Function


Function AnimationUpdate(Frame%)
   Local pivot.Pivot
   For pivot.Pivot=Each Pivot
      If pivot><Null Then
         If pivot\Parent><Null Then
            pivot\X[Frame]=pivot\Parent\X[Frame]+Cos(pivot\Angle[Frame])*pivot\length
            pivot\Y[Frame]=pivot\Parent\Y[Frame]+Sin(pivot\Angle[Frame])*pivot\length
         End If
      End If
   Next
End Function


Function Control()
   Local pivot.Pivot
   Local distance#=10000
   If MouseDown(1)>0 Then
      For pivot.Pivot=Each Pivot
         If Sqr((pivot\X[FrameNow]-(MouseX()-512))^2+(pivot\Y[FrameNow]-(MouseY()-512))^2)<distance Then
            Selected=pivot
            
            distance=Sqr((pivot\X[FrameNow]-(MouseX()-512))^2+(pivot\Y[FrameNow]-(MouseY()-512))^2)
            DebugLog distance
         End If
      Next
   End If
   Color 255,255,255
   Text -512,-512,"Frame: "+FrameNow
   If KeyDown(25) Then FrameNow=(FrameNow+1)Mod 30
   If KeyHit(16) Then FrameNow=(FrameNow+29)Mod 30
   If KeyHit(17) Then FrameNow=(FrameNow+1)Mod 30
   If KeyHit(28) Then
      FrameNow=AnimationCopyFrameToNextFrame(FrameNow)
      ;FrameNow=FrameNow+1
   End If
   If KeyHit(18) Then AnimationExport
   If Selected><Null Then
      Color 255,255,255
      Text -512,-490,Selected\Name
   Local MausRad%=MouseZSpeed()
   
   If MausRad><0 Then PivotTurn(Selected,MausRad+MausRad*KeyDown(42)*3,FrameNow)
   If MouseDown(2) Then
      Selected\X[FrameNow]=MouseX()-512
      Selected\Y[FrameNow]=MouseY()-512
      AnimationUpdate(FrameNow)
   End If
   If KeyHit(57) Then
      FrameNow=PivotCopyPivotToNextFrame(Selected,FrameNow)
      ;FrameNow=(FrameNow+1)Mod 30
   End If
End If
End Function

Function PivotTurn(pivot.Pivot,turnSpeed%,frame%)
   Local child.Pivot
   pivot\Angle[frame]=(pivot\Angle[frame]+turnSpeed+360)Mod 360
   For child.Pivot=Each Pivot
      If child\Parent=pivot Then PivotTurn(child,turnSpeed,frame)
   Next
   AnimationUpdate(FrameNow)
End Function

Function PivotCopyPivotToNextFrame(pivot.Pivot,frame%)
   frame=(frame+30)Mod 30
   Local nextFrame%=(frame+1)Mod 30
      pivot\X[nextFrame]=pivot\X[frame]
      pivot\Y[nextFrame]=pivot\Y[frame]
      PivotTurn(pivot,pivot\Angle[frame]-pivot\Angle[nextFrame],nextFrame)
      ;pivot\Angle[nextFrame]=pivot\Angle[frame]
      AnimationUpdate(nextFrame)
      Return nextFrame
      
End Function


   ;--------------------------------------
;--------------------------------------
   .data_parser
;Readmodline vom 14.12.2008
   Global MODorder$,MODvalue$,MODline$,MODparameter$   
   Global DEBUGline%,DEBUGfile$
   .functions_parser
Function readMODline$(lcl_datei)
   ;diese Funktion laedt aus dem Stream (datei) eine Zeile und teilt die Zeile in
   ;Part links vom Gleichzeichen modorder$    und den
   ;   wenn in diesem Part eine Zahl in klammern steht, wird sie zum modparameter$
   ;Part rechts vom Gleichzeichen modvalue$
   ;ausserdem wird der Debuglinecounter einen erhoeht
   ;lokale Variablen
   Local lcl_line$            ;die Zeile, die bearbeitet wird
   Local lcl_pos%            ;die Position, die bearbeitet wird
   DEBUGline=DEBUGline+1
   lcl_line$=Replace$(ReadLine(lcl_datei),Chr$(9),"")      ;loescht alle Tabulatoren
   MODorder$="NULL"                  
   MODvalue$="0"
   MODparameter$=0
   If Instr(lcl_line$,";",1)<>0 Then lcl_line$=Left$(lcl_line$,Instr(lcl_line$,";",1)-1)   ;loescht alles hinter dem Semikolon
   MODline$=lcl_line$
   lcl_pos=Instr(lcl_line$,"=",1)         ;guckt, wo das "=" ist
   If lcl_pos>0 Then      ;nur wenn es ein "=" gibt
      MODorder$=Left$(lcl_line$,lcl_pos-1)   ;modorder$ ist alles Links vom gleich
      If Instr(MODorder$,"(",1)>0 Then   ;wenn es in der Order eine Klammer gibt
         MODorder$=Replace$(MODorder$,")","")   ;die hintere Klammer wird geloescht
         MODorder$=Lower$(MODorder)
         MODparameter$=(Right$(MODorder$,Len(MODorder$)-Instr(MODorder$,"(",1)))      ;der modparameter$ kriegt den Wert hinter "("
         MODorder$=Lower(Left$(lcl_line$,Instr(MODorder$,"(",1)-1))   ;die Modorder$ den Wert vor der Klammer
      End If
      MODvalue$=Right$(lcl_line$,Len(lcl_line$)-lcl_pos)   ;modvalue$ wird alles nach dem "="
   End If
   MODorder=Lower(MODorder)
   
   Return lcl_line$   ;die Zeile ohne Tabulatoren und Kommentare wird zurueck geliefert
End Function

Function loadfile(lcl_filename$)
   ;laedt eine Datei und gibt den Stream zurueck
   ;fuer Debugzwecke wird die Debugzeilennummer auf 0 gesetzt und das debugfile$ auf den Dateinamen gesetzt
   ;lokale Variablen
   Local lcl_stream            ;der Stream, der gelesen wird
   lcl_stream=ReadFile(lcl_filename$)
   If lcl_stream=0 Then RuntimeError "File does not exist: "+lcl_filename$
   DEBUGfile$=lcl_filename$
   DEBUGline=0
   Return lcl_stream
End Function

Function runerror(lcl_Txt$)
   ;beendet das Programm per Fehlermeldung und gibt die gelesene Datei wieder und die Zeile
   RuntimeError lcl_Txt$+Chr$(13)+DEBUGfile$+" Line #"+DEBUGline+": "+Chr$(13)+Chr$(34)+MODline$+Chr$(34)
End Function


~EDITIERT~

Mittlerweile sollte eigentlich bekannt sein, dass das Foren-Layout nicht mit überlangen, ununterbrechbaren Zeilen in Codeboxen zurechtkommt. Kommt aber immer wieder vor. Ich hab die entsprechende Kommentar-Zeile gekürzt.
mfG Holzchopf

das wurgel

BeitragSa, Aug 14, 2010 3:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Schonmal nicht schlecht.

Ein paar Verbesserungsvorschläge:
- Ne GUI reinmachen
- Punkte hinzufügen und neu Verbinden ermöglichen
- Relative Childkoordinaten
- Stufenlose Übergänge zwischen den Frames. Auf diese Weise könnte man Bilder mit einstellbarer Framelänge exportieren. Also z.B. zeichnen_x=x[floor(frame#)-1]*(1-(frame# Mod 1)) + x[floor(frame#)]*(frame# Mod 1)
1 ist ungefähr 3

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group