Interface für "ImageScreens", also Screen ohne DX

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
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

Interface für "ImageScreens", also Screen ohne DX

Beitrag von NicTheQuick »

Ein kleines Beispiel ist dabei. Der Rest müsste selbsterklärend sein. Achja: Beenden mit Alt+F4.

Code: Alles auswählen

Interface ImageScreen
  Open(x.l, y.l, Width.l, Height.l, Titel.s)
  OpenGadget(x.l, y.l, Width.l, Height.l)
  Resize(x.l, y.l, Width.l, Height.l)
  Clear(red.l, green.l, blue.l)
  StartDraw()
  StopDraw()
  ShowChanges()
  Kill()
EndInterface
Structure ImageScreen_Struc
  VTable.l
  
  Functions.l[8]
  
  Pos.RECT
  WinID.l
  hWnd.l
  GadID.l
  ImgID.l
  hImg.l
EndStructure

Procedure IS_Open(*IS.ImageScreen_Struc, x.l, y.l, Width.l, Height.l, Titel.s)
  *IS\Pos\left   = x
  *IS\Pos\top    = y
  *IS\Pos\right  = Width
  *IS\Pos\bottom = Height
  
  *IS\ImgID = CreateImage(#PB_Any, Width, Height)
  If *IS\ImgID = 0 : ProcedureReturn #False : EndIf
  *IS\hImg = UseImage(*IS\ImgID)
  
  *IS\WinID = OpenWindow(#PB_Any, x, y, Width, Height, #PB_Window_BorderLess, Titel)
  If *IS\WinID = 0 : FreeImage(*IS\ImgID) : ProcedureReturn #False : EndIf
  *IS\hWnd = WindowID(*IS\WinID)
  
  If CreateGadgetList(*IS\hWnd)
    *IS\GadID = ImageGadget(#PB_Any, 0, 0, Width, Height, *IS\hImg)
    If *IS\GadID : ProcedureReturn #True : EndIf
  EndIf
  
  CloseWindow(*IS\WinID)
  FreeImage(*IS\ImgID)
  ProcedureReturn #False
EndProcedure
Procedure IS_OpenGadget(*IS.ImageScreen_Struc, x.l, y.l, Width.l, Height.l)
  *IS\Pos\left   = x
  *IS\Pos\top    = y
  *IS\Pos\right  = Width
  *IS\Pos\bottom = Height
  
  *IS\ImgID = CreateImage(#PB_Any, Width, Height)
  If *IS\ImgID = 0 : ProcedureReturn #False : EndIf
  *IS\hImg = UseImage(*IS\ImgID)
  
  *IS\GadID = ImageGadget(#PB_Any, 0, 0, Width, Height, *IS\hImg)
  If *IS\GadID : ProcedureReturn #True : EndIf
  
  FreeImage(*IS\ImgID)
  ProcedureReturn #False
EndProcedure
Procedure IS_Resize(*IS.ImageScreen_Struc, x.l, y.l, Width.l, Height.l)
  If *IS\GadID
    ResizeGadget(*IS\GadID, 0, 0, Width, Height)
  EndIf
  
  If x = -1 : x = *IS\Pos\left : EndIf
  If y = -1 : y = *IS\Pos\top  : EndIf
  If Width = -1 : Width = *IS\Pos\right : EndIf
  If Height = -1 : Height = *IS\Pos\bottom : EndIf
  If *IS\WinID
    MoveWindow_(*IS\hWnd, x, y, Width, Height, 0)
  EndIf
  If *IS\ImgID
    ResizeImage(*IS\ImgID, Width, Height, #PB_Image_Raw)
    *IS\hImg = UseImage(*IS\ImgID)
  EndIf
  
  *IS\Pos\left   = x
  *IS\Pos\top    = y
  *IS\Pos\right  = Width
  *IS\Pos\bottom = Height
EndProcedure

Procedure IS_Clear(*IS.ImageScreen_Struc, red.l, green.l, blue.l)
  UseImage(*IS\ImgID)
  StartDrawing(ImageOutput())
    Box(0, 0, *IS\Pos\right, *IS\Pos\bottom, RGB(red, green, blue))
  StopDrawing()
EndProcedure
Procedure IS_StartDraw(*IS.ImageScreen_Struc)
  UseImage(*IS\ImgID)
  StartDrawing(ImageOutput())
EndProcedure
Procedure IS_StopDraw(*IS.ImageScreen_Struc)
  StopDrawing()
EndProcedure
Procedure IS_ShowChanges(*IS.ImageScreen_Struc)
  SetGadgetState(*IS\GadID, UseImage(*IS\ImgID))
EndProcedure

Procedure IS_Kill(*IS.ImageScreen_Struc)
  If *IS\WinID : CloseWindow(*IS\WinID) : EndIf
  If *IS\ImgID : FreeImage(*IS\ImgID) : EndIf
  FreeMemory(*IS)
  
  ProcedureReturn #True
EndProcedure
Procedure IS_Create()
  Protected *IS.ImageScreen_Struc
  *IS = AllocateMemory(SizeOf(ImageScreen_Struc))
  If *IS = 0 : ProcedureReturn #False : EndIf
  
  *IS\VTable = *IS + 4
  
  *IS\Functions[0] = @IS_Open()
  *IS\Functions[1] = @IS_OpenGadget()
  *IS\Functions[2] = @IS_Resize()
  *IS\Functions[3] = @IS_Clear()
  *IS\Functions[4] = @IS_StartDraw()
  *IS\Functions[5] = @IS_StopDraw()
  *IS\Functions[6] = @IS_ShowChanges()
  *IS\Functions[7] = @IS_Kill()
  
  ProcedureReturn *IS
EndProcedure

*Scr.ImageScreen = IS_Create() ; Interface "laden"
If *Scr = 0 : End : EndIf

xPos.l   = 100
yPos.l   = 100
Width.l  = 400
Height.l = 300

*Scr\Open(xPos, yPos, Width, Height, "TestScreen") ; "Screen" öffnen

x.f = Width / 2
y.f = Height / 2
x_a.f = (Random(2000) - 1000) / 1000
y_a.f = (Random(2000) - 1000) / 1000
r.f = 10
Repeat
  *Scr\Clear(0, 0, 0) ; "Screen" löschen
  *Scr\StartDraw() ; Mit dem Malen beginnen
    Circle(x, y, r, $FF0000)
  *Scr\StopDraw() ; Das Malen beenden
  *Scr\ShowChanges() ; Alles gemalte anzeigen
  
  x + 3 * x_a
  y + 3 * y_a
  If x < r
    x - x_a + 10
    x_a = Random(1000) / 1000
    y_a.f = (Random(2000) - 1000) / 1000
    xPos - 10
    Width + 10
    *Scr\Resize(xPos, -1, Width, -1) ; Ändere Größe und verschiebe "Screen"
  EndIf
  If y < r
    y - y_a + 10
    y_a = Random(1000) / 1000
    x_a.f = (Random(2000) - 1000) / 1000
    yPos - 10
    Height + 10
    *Scr\Resize(-1, yPos, -1, Height)
  EndIf
  If x + r > Width  
    x - x_a
    x_a = -Random(1000) / 1000
    y_a.f = (Random(2000) - 1000) / 1000
    Width + 10
    *Scr\Resize(-1, -1, Width, -1)
  EndIf
  If y + r > Height
    y - y_a
    y_a = -Random(1000) / 1000
    x_a.f = (Random(2000) - 1000) / 1000
    Height + 10
    *Scr\Resize(-1, -1, -1, Height)
  EndIf
Until WindowEvent() = #PB_EventCloseWindow

*Scr\Kill() ; Alles schließen und Speicher freigeben
Zuletzt geändert von NicTheQuick am 14.01.2006 22:43, insgesamt 2-mal geändert.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

:allright:
Witzig wenn der Screen grösser wird.
Solltest vielleicht noch erwähnen, das man mit Alt-F4 beenden kann.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Green Snake
Beiträge: 1394
Registriert: 22.02.2005 19:08

Beitrag von Green Snake »

LOL :mrgreen:
Es ist wirklich lustig, wenn der screen grösser wird :lol:

:allright:
-.-"
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 »

Hier noch eine Version für mehr Bälle. Interfac nicht vergessen.

Code: Alles auswählen

*Scr.ImageScreen = IS_Create() ; Interface "laden"
If *Scr = 0 : End : EndIf

xPos.l   = 540
yPos.l   = 412
Width.l  = 200
Height.l = 200
Balls.l  = 10

Structure Ball
  x.f
  y.f
  x_a.f
  y_a.f
  r.l
EndStructure
Dim Ball.Ball(Balls - 1)

*Scr\Open(xPos, yPos, Width, Height, "TestScreen") ; "Screen" öffnen

For a.l = 0 To Balls - 1
  Ball(a)\r = Random(10) + 2
  Ball(a)\x = Random(Width - 2 * Ball(a)\r) + Ball(a)\r
  Ball(a)\y = Random(Height - 2 * Ball(a)\r) + Ball(a)\r
  Ball(a)\x_a = (Random(2000) - 1000) / 1000
  Ball(a)\y_a = (Random(2000) - 1000) / 1000
Next
p.f = 0
Repeat
  *Scr\Clear(0, 0, 0) ; "Screen" löschen
  *Scr\StartDraw() ; Mit dem Malen beginnen
    For a = 0 To Balls - 1
      Circle(Ball(a)\x, Ball(a)\y, Ball(a)\r, $FF0000)
    Next
  *Scr\StopDraw() ; Das Malen beenden
  *Scr\ShowChanges() ; Alles gemalte anzeigen
  
  For a = 0 To Balls - 1
    Ball(a)\x + 3 * Ball(a)\x_a
    Ball(a)\y + 3 * Ball(a)\y_a
    
    If Ball(a)\x < Ball(a)\r
      If xPos < Ball(a)\r : p = xPos : Else : p = Ball(a)\r : EndIf
      Ball(a)\x - Ball(a)\x_a
      Ball(a)\x_a = Random(1000) / 1000
      Ball(a)\y_a = (Random(2000) - 1000) / 1000
      
      xPos - p
      For b = 0 To Balls - 1 : Ball(b)\x + p : Next
      Width + p
      
      *Scr\Resize(xPos, -1, Width, -1) ; Ändere Größe und verschiebe "Screen"
    EndIf
    
    If Ball(a)\y < Ball(a)\r
      If yPos < Ball(a)\r : p = yPos : Else : p = Ball(a)\r : EndIf
      Ball(a)\y - Ball(a)\y_a
      Ball(a)\y_a = Random(1000) / 1000
      Ball(a)\x_a = (Random(2000) - 1000) / 1000
      
      yPos - p
      For b = 0 To Balls - 1 : Ball(b)\y + p : Next
      Height + p
      
      *Scr\Resize(-1, yPos, -1, Height)
    EndIf
    If Ball(a)\x + Ball(a)\r > Width  
      Ball(a)\x - Ball(a)\x_a
      Ball(a)\x_a = -Random(1000) / 1000
      Ball(a)\y_a = (Random(2000) - 1000) / 1000
      Width + Ball(a)\r
      *Scr\Resize(-1, -1, Width, -1)
    EndIf
    If Ball(a)\y + Ball(a)\r > Height
      Ball(a)\y - Ball(a)\y_a
      Ball(a)\y_a = -Random(1000) / 1000
      Ball(a)\x_a = (Random(2000) - 1000) / 1000
      Height + Ball(a)\r
      *Scr\Resize(-1, -1, -1, Height)
    EndIf
  Next
Until WindowEvent() = #PB_EventCloseWindow

*Scr\Kill() ; Alles schließen und Speicher freigeben
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 »

Hier ein Update. Jetzt mit Mauskoordinatenabfrage und kleinem Beispiel.

Erst das Interface:

Code: Alles auswählen

;Info: ImageScreen Interface

;Use PB-Memory, 2D-Drawing, Window, Gadget.

Interface ImageScreen
  Open(x.l, y.l, Width.l, Height.l, Titel.s) ; Erstellt neues Screen-Fenster
  OpenGadget(x.l, y.l, Width.l, Height.l) ; Erstellt neues Screen-Gadget
  Resize(x.l, y.l, Width.l, Height.l) ; Ändert Position und Größe
  Clear(red.l, green.l, blue.l) ; Löscht Screen mit festgelegter Farbe
  MouseX() ; Gibt die X-Mauskoordinate auf dem Screen wieder
  MouseY() ; Gibt die X-Mauskoordinate auf dem Screen wieder
  IsMouseOverScreen() ; Ergibt #True, wenn die Maus auf dem Screen ist, sonst #False
  StartDraw() ; Beginnt Malen auf den Screen
  StopDraw() ; Beendet Malen auf den Screen
  ShowChanges() ; Zeigt gemaltes an
  Kill() ; Schließt das Interface
  ;IS_Create() ; Erstellt Interface
EndInterface
Structure ImageScreen_Struc
  VTable.l
  
  Functions.l[11]
  
  Pos.RECT
  WinID.l
  hWnd.l
  GadID.l
  ImgID.l
  hImg.l
EndStructure

Procedure IS_Open(*IS.ImageScreen_Struc, x.l, y.l, Width.l, Height.l, Titel.s)
  *IS\Pos\left   = x
  *IS\Pos\top    = y
  *IS\Pos\right  = Width
  *IS\Pos\bottom = Height
  
  *IS\ImgID = CreateImage(#PB_Any, Width, Height)
  If *IS\ImgID = 0 : ProcedureReturn #False : EndIf
  *IS\hImg = UseImage(*IS\ImgID)
  
  *IS\WinID = OpenWindow(#PB_Any, x, y, Width, Height, #PB_Window_BorderLess, Titel)
  If *IS\WinID = 0 : FreeImage(*IS\ImgID) : ProcedureReturn #False : EndIf
  *IS\hWnd = WindowID(*IS\WinID)
  
  If CreateGadgetList(*IS\hWnd)
    *IS\GadID = ImageGadget(#PB_Any, 0, 0, Width, Height, *IS\hImg)
    If *IS\GadID : ProcedureReturn #True : EndIf
  EndIf
  
  CloseWindow(*IS\WinID)
  FreeImage(*IS\ImgID)
  ProcedureReturn #False
EndProcedure
Procedure IS_OpenGadget(*IS.ImageScreen_Struc, x.l, y.l, Width.l, Height.l)
  *IS\Pos\left   = x
  *IS\Pos\top    = y
  *IS\Pos\right  = Width
  *IS\Pos\bottom = Height
  
  *IS\ImgID = CreateImage(#PB_Any, Width, Height)
  If *IS\ImgID = 0 : ProcedureReturn #False : EndIf
  *IS\hImg = UseImage(*IS\ImgID)
  
  *IS\GadID = ImageGadget(#PB_Any, 0, 0, Width, Height, *IS\hImg)
  If *IS\GadID : ProcedureReturn #True : EndIf
  
  FreeImage(*IS\ImgID)
  ProcedureReturn #False
EndProcedure
Procedure IS_Resize(*IS.ImageScreen_Struc, x.l, y.l, Width.l, Height.l)
  If *IS\GadID
    ResizeGadget(*IS\GadID, 0, 0, Width, Height)
  EndIf
  
  If x = -1 : x = *IS\Pos\left : EndIf
  If y = -1 : y = *IS\Pos\top  : EndIf
  If Width = -1 : Width = *IS\Pos\right : EndIf
  If Height = -1 : Height = *IS\Pos\bottom : EndIf
  If *IS\WinID
    MoveWindow_(*IS\hWnd, x, y, Width, Height, 0)
  EndIf
  If *IS\ImgID
    ResizeImage(*IS\ImgID, Width, Height, #PB_Image_Raw)
    *IS\hImg = UseImage(*IS\ImgID)
  EndIf
  
  *IS\Pos\left   = x
  *IS\Pos\top    = y
  *IS\Pos\right  = Width
  *IS\Pos\bottom = Height
EndProcedure

Procedure.l IS_MouseX(*IS.ImageScreen_Struc)
  Protected Mouse.Point, hGad.l, Gad.RECT
  
  If IsGadget(*IS\GadID)
    hGad = GadgetID(*IS\GadID)
    GetCursorPos_(@Mouse)
    GetWindowRect_(hGad, @Gad)
    
    ProcedureReturn Mouse\x - Gad\left
  EndIf
EndProcedure
Procedure.l IS_MouseY(*IS.ImageScreen_Struc)
  Protected Mouse.Point, hGad.l, Gad.RECT
  
  If IsGadget(*IS\GadID)
    hGad = GadgetID(*IS\GadID)
    GetCursorPos_(@Mouse)
    GetWindowRect_(hGad, @Gad)
    
    ProcedureReturn Mouse\y - Gad\top
  EndIf
EndProcedure
Procedure IS_IsMouseOverScreen(*IS.ImageScreen_Struc)
  Protected Mouse.Point, hGad.l, Gad.RECT
  
  If IsGadget(*IS\GadID)
    hGad = GadgetID(*IS\GadID)
    GetCursorPos_(@Mouse)
    GetWindowRect_(hGad, @Gad)
    
    If Mouse\x >= Gad\left And Mouse\y >= Gad\top And Mouse\x < Gad\left + *IS\Pos\right And Mouse\y < Gad\top + *IS\Pos\bottom
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
EndProcedure

Procedure IS_Clear(*IS.ImageScreen_Struc, red.l, green.l, blue.l)
  UseImage(*IS\ImgID)
  StartDrawing(ImageOutput())
    Box(0, 0, *IS\Pos\right, *IS\Pos\bottom, RGB(red, green, blue))
  StopDrawing()
EndProcedure
Procedure IS_StartDraw(*IS.ImageScreen_Struc)
  UseImage(*IS\ImgID)
  StartDrawing(ImageOutput())
EndProcedure
Procedure IS_StopDraw(*IS.ImageScreen_Struc)
  StopDrawing()
EndProcedure
Procedure IS_ShowChanges(*IS.ImageScreen_Struc)
  SetGadgetState(*IS\GadID, UseImage(*IS\ImgID))
EndProcedure

Procedure IS_Kill(*IS.ImageScreen_Struc)
  If *IS\WinID : CloseWindow(*IS\WinID) : EndIf
  If *IS\ImgID : FreeImage(*IS\ImgID) : EndIf
  FreeMemory(*IS)
  
  ProcedureReturn #True
EndProcedure
Procedure IS_Create()
  Protected *IS.ImageScreen_Struc
  *IS = AllocateMemory(SizeOf(ImageScreen_Struc))
  If *IS = 0 : ProcedureReturn #False : EndIf
  
  *IS\VTable = *IS + 4
  
  *IS\Functions[0] = @IS_Open()
  *IS\Functions[1] = @IS_OpenGadget()
  *IS\Functions[2] = @IS_Resize()
  *IS\Functions[3] = @IS_Clear()
  *IS\Functions[4] = @IS_MouseX()
  *IS\Functions[5] = @IS_MouseY()
  *IS\Functions[6] = @IS_IsMouseOverScreen()
  *IS\Functions[7] = @IS_StartDraw()
  *IS\Functions[8] = @IS_StopDraw()
  *IS\Functions[9] = @IS_ShowChanges()
  *IS\Functions[10] = @IS_Kill()
  
  ProcedureReturn *IS
EndProcedure
Dann das Beispiel:

Code: Alles auswählen

*Scr.ImageScreen = IS_Create()
*Scr\Open(100, 100, 200, 200, "Titel")
Repeat
  *Scr\Clear(255, 255, 255)
  *Scr\StartDraw()
    Locate(0, 0)
    DrawText(Str(*Scr\MouseX()) + ", " + Str(*Scr\MouseY()))
    Locate(0, 16)
    DrawText(Str(*Scr\IsMouseOverScreen()))
  *Scr\StopDraw()
  *Scr\ShowChanges()
  Delay(10)
Until WindowEvent() = #PB_EventCloseWindow
Viel Spaß damit.
Antworten