[Mini-Tut] Animation per Sprite3D: rollender Ball

Hier kannst du häufig gestellte Fragen/Antworten und Tutorials lesen und schreiben.
Benutzeravatar
KeyKon
Beiträge: 1412
Registriert: 10.09.2004 20:51
Computerausstattung: Laptop: i5 2,8 Ghz, 16GB DDR3 RAM, GeForce 555GT 2GB VRAM
PC: i7 4,3 Ghz, 32GB DDR3 RAM, GeForce 680 GTX 4GB VRAM
Win10 x64 Home/Prof
PB 5.30 (64bit)
Wohnort: Ansbach
Kontaktdaten:

Beitrag von KeyKon »

Sowas in der Art?:

Code: Alles auswählen

InitSprite()
InitKeyboard()
InitSprite3D()

; heute mal nur ein Windowed-Screen
; anstatt eines Fullscreens
OpenWindow( 0, #PB_Ignore,0, 800,600, "Animations-Demo")
  OpenWindowedScreen( WindowID(0), 0,0, 800,600, 0,0,0 )

; jetzt erzeugen wir einen lustigen bunten Ball als Sprite


BallUmfang.d = 64*2*#PI ;Umfang des Balls ausrechnen

CreateSprite( 2,128,128) ; Schablone für den Ball
  TransparentSpriteColor(2,0)
  StartDrawing(SpriteOutput(2))
    Box(0,0,128,128,RGB(255,0,255))
    Circle(64,64,64,0)
  StopDrawing()


CreateSprite( 3, 128, 128) ; "Textur für den Ball
  TransparentSpriteColor( 3, RGB( 255, 0, 255 ) ) ; Transparenzfarbe PUR
  StartDrawing( SpriteOutput(3) )
    Box(0,0,128,128, #Blue) ; Hintergrund in PUR
    For x = 1 To 10
      Circle(Random(128),Random(128),10,#Yellow)
    Next
  StopDrawing()


UseBuffer(3) 
DisplayTransparentSprite(2,0,0) ;Denn Ball mit der Schablone aus der Textur ausschneiden
UseBuffer(#PB_Default)


CopySprite(3,0,#PB_Sprite_Texture) ;Das ganze zu einem Sprite im Texture-Mode kopieren
TransparentSpriteColor(0,RGB(255,0,255))

FreeSprite(2) ;Hilfssprites löschen
FreeSprite(3) ;  "

CreateSprite( 1, 128, 128, #PB_Sprite_Texture) ; Lichtreflexion erstellen
  
  StartDrawing( SpriteOutput(1) )
    Box(0,0,128,128, 0)
    For n=0 To 31
      Circle( 64-n, 64-n, 64 - 1.5*n, RGB( 7*n, 7*n, 7*n) )
    Next
  StopDrawing()


; jetzt machen wir'n Sprite3D draus, um den Ball rotieren zu können
CreateSprite3D( 0, 0 )
CreateSprite3D( 1, 1 )

BallX.d = -128
BallY.d = 170
BallR.d = 0
Mov.d = 1
Way.d = 0
SetFrameRate(60)
Repeat
;************************************
; Eventhandling wird fürn WindowedScreen gebraucht,
; fürn Fullscreen ist das überflüssig.
  Repeat
    Event = WaitWindowEvent(10)
    If Event = #PB_Event_CloseWindow
      EXIT = 1
    EndIf
  Until Event = #Null
;************************************
 
  ClearScreen( $200810 )          ; Screen löschen
  ; Farbe ist RGB( 16, 8, 32 ) als HEX geschrieben
 
  Mov*1.01                        ; Bewegunggeschwindigkeit potenzieren
  BallX + Mov                     ; Waagrechte Bewegung hinzufügen
  BallY = BallX*3/4               ; Senkrechte Position im Verhältnis zur Waagrechte Position setzen
  Way = Sqr(Pow(Mov,2)+Pow(Mov*3/4,2)) ; Tatsächlich zurückgelegte Strecke in Pixeln
  BallR = (BallR + (Way/BallUmfang*360)) ; DrehungsWinkel im Verhältnis zur BallBewegung und Umfang dazurechnen
 
 
  If BallR > 360                  ; ist der Winkel über 360°
    BallR-360                     ; wieder auf 0 setzen...
  EndIf
 
  If BallX > 900                  ; rechts unten verschwunden?
    BallX = -128                  ; links oben hinsetzen
    Mov = 1
  EndIf
;********
  Start3D()
    RotateSprite3D( 0, BallR, 0 )       ; aktuelle Rotation
    
    Sprite3DBlendingMode(5,6)           ; auf normalen Blendingmode stellen
    
    DisplaySprite3D( 0, BallX, BallY )  ; Ball anzeigen
    
    Sprite3DBlendingMode(5,4)           ; Auf Mischmodus stellen
    
    DisplaySprite3D( 1, BallX, BallY )  ; Lichtreflexion drüberlegen
    
  Stop3D()
;********
  FlipBuffers( #PB_Screen_SmartSynchronization )
Until EXIT
(\/) (°,,,°) (\/)
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3857
Registriert: 13.09.2004 17:48
Kontaktdaten:

Beitrag von bobobo »

schon besser
‮pb aktuell5.7 - windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Donie1704
Beiträge: 4
Registriert: 27.02.2010 16:53

Re: [Mini-Tut] Animation per Sprite3D: rollender Ball

Beitrag von Donie1704 »

Woran liegt das, dass die Animation gestoppt wird wenn ich den Cursor bewege?
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: [Mini-Tut] Animation per Sprite3D: rollender Ball

Beitrag von STARGÅTE »

Eine Bewegung mit dem Mauszeiger erzeugt ein "dauerfeuer" an Eregnissen im Fenster:
Diese schleife für diese Events

Code: Alles auswählen

; Eventhandling wird fürn WindowedScreen gebraucht,
; fürn Fullscreen ist das überflüssig.
Repeat
    Event = WaitWindowEvent(10)
    If Event = #PB_Event_CloseWindow
      EXIT = 1
    EndIf
  Until Event = #Null
wird also so lange du die Maus bewegst nicht verlassen, statt aber auch sicher, das keine Events verlorne gehen, falls man sie doch auswerten möchte.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Donie1704
Beiträge: 4
Registriert: 27.02.2010 16:53

Re: [Mini-Tut] Animation per Sprite3D: rollender Ball

Beitrag von Donie1704 »

und wie könnte man im Beispiel des Balles nun das umgehen, dass die Animation gestoppt wird...
Kann man irgendwie die Mouse abschalten oder so?
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: [Mini-Tut] Animation per Sprite3D: rollender Ball

Beitrag von TomS »

Eine Repeat-Schleife reicht.

Code: Alles auswählen

Repeat
    event=WaitWindowEVent(timeout)
    If event = #PB_Event_CloseWindow
        Exit=1
    Else
        ClearScreen($000000)
        ;Dein Code
        FlipBuffers()
    EndIf
Until Exit=1
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: [Mini-Tut] Animation per Sprite3D: rollender Ball

Beitrag von NicTheQuick »

Also ich als Linux-User finde das ja doch ganz schön blöd. 'InitSprite3D()' geht nur mit Subsystem 'opengl' und 'UseBuffer()' geht nur mit SDL. Beides zusammen geht aber nicht. Wieso kann man 'UseBuffer()' nicht auch in 'opengl' integrieren?
Bild
Andi
Beiträge: 73
Registriert: 27.05.2008 17:29
Wohnort: Berlin

Re: [Mini-Tut] Animation per Sprite3D: rollender Ball

Beitrag von Andi »

Ich habe das Ganze mal um konstante(!) Beschleunigung (also nicht à la mov*1.02) und Reflektion an den Rändern bei entsprechender Umkehr der Beschleunigumg erweitert:

Code: Alles auswählen

InitSprite()
InitKeyboard()
InitSprite3D()

rad = 64 ;Radius des Kreises
SF.f = 360/(2*#PI*rad) ;Synchronisierung von Translation und Rotation

w_sprite = rad*2
h_sprite = rad*2

#sprite = 0
#sprite_3D = 0

OpenScreen(640, 480, 16, "Animations-Demo")

;Definition des Sprites:
CreateSprite(#sprite, w_sprite, h_sprite, #PB_Sprite_Texture)

;Basteln des Sprites: 
StartDrawing( SpriteOutput(#sprite) )
   For n=0 To (rad/2 - 1)
      Circle( rad+n, rad+n, rad - 2*n, RGB( 0, 8*n, 248) )
    Next
StopDrawing()

;Sprite3D erstellen:
CreateSprite3D(#sprite_3D, #sprite)

x_pos.f = 0.0       ;x-Position
x_speed.f = 1.0    ;Veränderung der x-Position ("Geschwindigkeit")
y_pos = 170        ;y-Position
rotat.f = 0.0       ;Rotationswinkel
rotat_change.f = 1.0

a_Const.f = 15.0 ;Beschleunigung
t.f = 0.0            ;Zeit
t_incr.f = 0.01 ;Zeitinkrement: Wenn man diesen Wert zu groß wählt, werden schnell sehr große
                    ;x-Positionswerte erreicht, sodass man nur wenig von der Bewegung sieht.
a_dir = 1        ;Bei der Reflektion am rechten Bildschirm wird der Wert -1 gesetzt. Damit erreicht
                    ;man eine abnehmende Geschwindigkeit 

SetFrameRate(60) 

Repeat

   ClearScreen(#Black) 
   
  t = t + (a_dir *t_incr) ;wenn rechter Rand erreicht, ist a_dir=-1; bewirkt abnehmende Geschw.
  x_a.f= a_dir * (a_Const*Pow(t,2))  ;Veränderung der x-Position aufgrund Beschleunigung
  ;(nach Reflektion am rechten Rand dreht sich Richtung von x_a um, weil dann a_dir=-1)
   
   x_pos = x_pos + x_speed + x_a
   
   If x_pos > 640-w_sprite ;rechter Rand ist erreicht
      x_speed = -1 
      a_dir = -1 
   EndIf  
   If x_pos < 0   ;linker Rand ist erreicht
      x_speed =  1
      a_dir = 1 
      ;Bewegung geht wieder von vorn los. Daher:
      t = 0
      x_pos = 0
      Delay(100)
   EndIf   
   
   If x_speed = 1  : rotat_change =  1*SF + x_a*SF  : EndIf 
   If x_speed = -1 : rotat_change = -1*SF + x_a*SF  : EndIf   
   rotat = rotat + rotat_change
   
   Start3D()
      RotateSprite3D(#sprite_3D, rotat, #PB_Absolute)      
      DisplaySprite3D(#sprite_3D, x_pos, y_pos)  
   Stop3D()
   
   ;gelbe Basislinie zeichnen:
   StartDrawing(ScreenOutput())
      Line(10, y_pos + 2*rad, 620, 1, #Yellow)
   StopDrawing()
   
   FlipBuffers()
  
   ExamineKeyboard()
    
Until KeyboardPushed(#PB_Key_Escape)
  
End   
PB + B4X = greatest tools on earth
Win 10 | PB 5.72
Antworten