Sprite Spiegel Effekt

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
dige
Beiträge: 1241
Registriert: 08.09.2004 08:53

Sprite Spiegel Effekt

Beitrag von dige »

Inspiriert von Rings's sprite effects, habe ich mal versucht einen Spiegeleffekt zu basteln. Probierts mal aus und viel Spaß!

Bild

Code: Alles auswählen

; --------------------------------------------------------------
;
; Sprite Mirror Effect
;
; Based on Codes from Rings & va!n
; http://www.purebasic.fr/english/viewtopic.php?t=29680
; http://www.purebasic.fr/english/viewtopic.php?t=30677
;
; --------------------------------------------------------------

; Mirror Sprite Effect by DiGe
; Based on Code from Rings & Va!n

lTextureSize.l  = 256
lScreenWidth.l  = 640
lScreenHeight.l = 480

Procedure SpriteMirrorHorizontal(SpriteID)
  ; Mirrors a sprite horizontal by Rings
  ; http://www.purebasic.fr/english/viewtopic.php?t=29680
  StartDrawing(SpriteOutput(SpriteID))
  IW = SpriteWidth(SpriteID)
  IH = SpriteHeight(SpriteID)
  Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
  Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 
  *pxData1.LONG = Buffer
  *pxData2.LONG = *pxData1 + (IH-1)*Pitch
 
  mem=AllocateMemory(Pitch)
  For lines=0 To IH/2-1
    CopyMemory(*pxData1,mem,pitch)
    CopyMemory(*pxData2,*pxData1,pitch)
    CopyMemory(mem,*pxData2,pitch)
    *pxData1 + pitch
    *pxData2 - pitch
  Next
  StopDrawing()
  If mem: FreeMemory(mem):EndIf
 
EndProcedure
Procedure SpriteFadeOut(SpriteID, Offset.b, Intensity.b)
  ; Fade Sprite Colors
  StartDrawing(SpriteOutput(SpriteID))
  IW = SpriteWidth(SpriteID)
  IH = SpriteHeight(SpriteID)
 
  Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
  Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
  PixelFormat = DrawingBufferPixelFormat()
 
  *pxData1.LONG = Buffer
  *pxData2.LONG = *pxData1 + (IH-1) * Pitch
 
 
  Select PixelFormat
    Case #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
      ByteOffset=1
    Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
      ByteOffset=2
    Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
      ByteOffset=2
    Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
      ByteOffset=3
    Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
      ByteOffset=3
    Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
      ByteOffset=4
    Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
      ByteOffset=4
    Default
      ByteOffset=4
  EndSelect
 
  f = Offset
 
  For Lines=0 To IH-1
    *pxData1 = Buffer + (Lines*pitch)
    f + Intensity
   
    For t=0 To IW-1
      m = *pxData1\l
     
      Select Pixelformat
        Case #PB_PixelFormat_16Bits
          Debug "Geht noch nicht"
         
        Case #PB_PixelFormat_24Bits_BGR,#PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
         
          p=m >> 24 & $FF ;the additive alpha
          r= m >> 16 & $FF
          g= m >> 8 & $FF
          b= m  & $FF
         
          If r > f : r - f : Else : r = 0 : EndIf
          If g > f : g - f : Else : g = 0 : EndIf
          If b > f : b - f : Else : b = 0 : EndIf
         
          ;gray=((r*29)+(g*58)+(b*11))/100
          m=   b | g << 8 | r << 16 | p << 24
         
        Case #PB_PixelFormat_24Bits_RGB,#PB_PixelFormat_32Bits_RGB
          p=m >> 24 & $FF ;the additive alpha
          b= m >> 16 & $FF
          g= m >> 8 & $FF
          r= m  & $FF
         
          If r > f : r - f : Else : r = 0 : EndIf
          If g > f : g - f : Else : g = 0 : EndIf
          If b > f : b - f : Else : b = 0 : EndIf

         
          ;gray=((r*29)+(g*58)+(b*11))/100
          m=   r | g << 8 | b << 16 | p << 24
         
      EndSelect
     
      *pxData1\l=m
      *pxData1 + ByteOffset
    Next
  Next
  StopDrawing()
 
EndProcedure

If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "Can't open DirectX 7 Or later", 0)
  End
EndIf
If InitSprite3D() = 0
  MessageRequester("Error", "Direct3D system can't be initialized correctly", 0)
  End
EndIf

OpenWindow(0, 0, 0, lScreenWidth, lScreenHeight, "Sprite Mirrorx FX by DiGe", #WS_OVERLAPPEDWINDOW)
If OpenWindowedScreen(WindowID(0), 0, 0, lScreenWidth, lScreenHeight, 0, 0, 0)

  lp=LoadSprite(0, #PB_Compiler_Home + "Examples\Sources\Data\Geebee2.bmp", #PB_Sprite_Texture)
  If lp=0
    Debug "sprite not loaded"
    End
  EndIf


  ; Create Background. Code by va!n
  ; http://www.purebasic.fr/english/viewtopic.php?t=30677
  xres = lScreenWidth /2
  yres = lScreenHeight / 1
 
  CreateImage (1, lScreenWidth, lScreenHeight)
 
  StartDrawing(ImageOutput(1))
    b.f = 0
    For y = 0 To lScreenHeight -1
        w.f = -yres / y
        v.f = (  lScreenWidth * w )
        u.f = ( -xres * w )
        For x = 0 To lScreenWidth -1
            t =  ((Int(u) ! Int(v) ) & 255 )
            c = Int((t / lScreenHeight) * y)
            Plot( x, y, RGB( c, c, c ))
            u = u + w
        Next
        b = b + lScreenWidth
    Next
  StopDrawing()

 
 
  CopySprite(0, 1,  #PB_Sprite_Texture)
  SpriteMirrorHorizontal(1)
  SpriteFadeOut(1, 10, 2)

  CreateSprite(5, lScreenWidth, lScreenHeight , #PB_Sprite_Texture )
  If StartDrawing(SpriteOutput(5))
    DrawImage(ImageID(1), 0, 0)
    StopDrawing()
  EndIf
 
  Repeat
    ; --- FrameCounter
    Count + 1
    If time < ElapsedMilliseconds()
      SetWindowTitle(0, Str(Count) + " FPS")
      time = ElapsedMilliseconds() + 1000
      Count = 0
    EndIf
   
    DisplaySprite(5, 0, 0)    ; Background Sprite
    DisplaySprite(0, x, 100)  ; Normal Sprite
    DisplayTranslucentSprite(1, x, 240, 100); Mirror Sprite

    x + 2
    If x > lScreenWidth : x = - SpriteWidth(0) : EndIf
   
    FlipBuffers()
   
    If ExamineKeyboard() And KeyboardPushed(#PB_Key_Escape) : Break : EndIf
    If WindowEvent() = #PB_Event_CloseWindow : Break : EndIf
   
  ForEver
Else
  MessageRequester("Error", "Can't open a screen !", 0)
EndIf
End 
Edit by NicTheQuick: Code vervollständigt
"Papa, ich laufe schneller - dann ist es nicht so weit."
PMTheQuick
Beiträge: 630
Registriert: 05.05.2005 19:06

Beitrag von PMTheQuick »

Ähm... Der Repeat / Until Teil hat ja fast nix drinnen?!? Kein einziger Zeichenbefehl... ?!? Vorallem... Die If-Abfrage ist auch etwas buggy... Hast du da was aufsversehen gelöscht oder so?

Gruss
PMTheQuick ;)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

In der 'If'-Zeile fehlen eindeutig Zeilen.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

a²+b²=mc²
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Hab den Code oben mal ausgebessert.

Was mich allerdings wundert:
Unter Linux will er mir den Befehl 'InitSprite3D()' nicht erkennen. Er meldet
'InitSprite3D() is not a function, array, macro or linked list'. Kann mir
vielleicht jemand helfen, wie das unter Linux geht? In der Hilfe steht ja, dass
der Befehl von Linux untrestützt wird.
Antworten