2D Metaball

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.
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

2D Metaball

Beitrag von Robert Wünsche »

Hallo Leute,
ich habe den bekannten Metaball-Algorithmus auf einer ebene (2d) angewandt. Das Programm zeichnet Kreise, die ineinander übergehen.

Es werden 10 Metaballs auf zufälligen Positionen erzeugt, die mit den anderen interagieren.
Man kann einen MetaBall zur interaktion mit der Maus direkt bewegen.

Eventuell könnt iher es in einem Spiel oder einer Demo oder sonstwas mit einsetzen, aber nehmt mich bitte mit in den Credits mit auf.

Code: Alles auswählen

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Fehler!","Konnte DirectX 7.0 nicht initialisieren!")
  End
EndIf

If OpenScreen(800,600,32,"Metaball 2D") = 0
  MessageRequester("Fehler!","Konnte einen 800x600 32 bit farbtiefe bildschirm nicht öffnen!")
  End
EndIf

;ll für einen metaball
Structure Metaball
  x.l
  y.l
  starke.f
EndStructure
NewList metaball.Metaball()

;Structure für die einstellungen
Structure einstellungen
  pegel.f ;ist der niveau pegel zum anzeigen
  
  x.l ;ist der rederbereich...
  y.l
  
  mausstarke.f ;ist die stärke des Maus-Metaball's...
EndStructure
Global einstellungen.einstellungen

;Procedure für den 2d abstand:
Procedure asd(x1.l,y1.l,x2.l,y2.l)
  x = x1 - x2
  y = y1 - y2
  ProcedureReturn x*x+y*y
EndProcedure

einstellungen\x = 200
einstellungen\y = 200
einstellungen\pegel = 2
einstellungen\mausstarke = 100

;~ tzene kreieren:
For _=0 To 10
  AddElement(metaball())
  metaball()\x = Random(einstellungen\x)
  metaball()\y = Random(einstellungen\y)
  metaball()\starke = 100 + Random(100)
Next

Repeat
  If ExamineMouse() <> 0
    mausx.l = MouseX()
    mausy.l = MouseY()
  EndIf
  
  If StartDrawing(ScreenOutput()) <> 0
    For x = 1 To einstellungen\x
      For y = 1 To einstellungen\y
        pegel.f = 0
        ForEach metaball()
          pegel + 1/asd(x,y,metaball()\x,metaball()\y)*metaball()\starke
        Next
        pegel + 1/asd(x,y,mausx,mausy) *einstellungen\mausstarke
        
        If pegel > einstellungen\pegel
          Plot(x,y,RGB(255,0,0))
        EndIf
      Next
    Next
    Stopdrawing()
  EndIf

  FlipBuffers()
  ClearScreen(0,0,0)
  
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Escape)
    exit = 1
  EndIf
  
Until exit = 1
Zuletzt geändert von Robert Wünsche am 05.09.2005 22:32, insgesamt 3-mal geändert.
Benutzeravatar
Hroudtwolf
Beiträge: 1416
Registriert: 30.10.2004 23:33
Kontaktdaten:

Beitrag von Hroudtwolf »

Wie wärs mit Stopdrawing ? ;-)

Leider finden alle Bewegungen sehr, sehr langsam statt.
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

Hinzugefügt :roll: ...
Naja, ich habe keine ahnung warum das auch so ohne funktioniert hat...egal :wink:.
Edit: Die Verzögerung war nur zu testzwecken -> rausgenommen.
Benutzeravatar
Eric
Beiträge: 303
Registriert: 05.09.2004 09:50
Wohnort: Göttingen

Beitrag von Eric »

Juhuuuuu

ein kleiner Bereich mit einigen roten Kreisen, die wie verrückt flackern und etwa die Hälfte vom Bildschirm ist von kleinen roten Flecken übersäht. :freak:
El_Choni_work: cant't you just spit the binary data to sqlite, as you would spit a hamster into a microwave oven?
* Fangles falls off the chair laughing
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
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 »

Also bei mir funktioniert es.

Und ich habe diese Metabälle auch gleich mal ein bisschen in Schwung versetzt:

Code: Alles auswählen

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 
  MessageRequester("Fehler!","Konnte DirectX 7.0 nicht initialisieren!") 
  End 
EndIf 

If OpenScreen(800,600,32,"Metaball 2D") = 0 
  MessageRequester("Fehler!","Konnte einen 800x600 32 bit farbtiefe bildschirm nicht öffnen!") 
  End 
EndIf 

;ll für einen metaball 
Structure Metaball 
  x.f
  y.f 
  xr.f
  yr.f
  starke.f 
EndStructure 
NewList metaball.Metaball() 

;Structure für die einstellungen 
Structure einstellungen 
  pegel.f ;ist der niveau pegel zum anzeigen 
  
  x.l ;ist der rederbereich... 
  y.l 
  
  mausstarke.f ;ist die stärke des Maus-Metaball's... 
EndStructure 
Global einstellungen.einstellungen 

;Procedure für den 2d abstand: 
Procedure asd(x1.l,y1.l,x2.l,y2.l) 
  x = x1 - x2 
  y = y1 - y2 
  ProcedureReturn x*x+y*y 
EndProcedure 

einstellungen\x = 200 
einstellungen\y = 200 
einstellungen\pegel = 2
einstellungen\mausstarke = 100 

;~ tzene kreieren: 
For _=0 To 20 
  AddElement(metaball()) 
  metaball()\x = Random(einstellungen\x) 
  metaball()\y = Random(einstellungen\y) 
  metaball()\xr = Random(20) / 10 - 1
  metaball()\yr = Random(20) / 10 - 1
  metaball()\starke = 100 + Random(100) 
Next 

Repeat 
  If ExamineMouse() <> 0 
    mausx.l = MouseX() 
    mausy.l = MouseY() 
  EndIf 
  
  If StartDrawing(ScreenOutput()) <> 0 
    For x = 1 To einstellungen\x 
      For y = 1 To einstellungen\y 
        pegel.f = 0 
        ForEach metaball() 
          pegel + 1/asd(x,y,metaball()\x,metaball()\y)*metaball()\starke 
        Next 
        pegel + 1/asd(x,y,mausx,mausy) *einstellungen\mausstarke 
        
        If pegel > einstellungen\pegel 
          Plot(x,y,RGB(255,0,0)) 
        EndIf 
      Next 
    Next 
    StopDrawing() 
  EndIf 
  
  ForEach metaball()
    metaball()\x + metaball()\xr
    metaball()\y + metaball()\yr
    If metaball()\x < 0 Or metaball()\x > einstellungen\x : metaball()\xr = -metaball()\xr : EndIf
    If metaball()\y < 0 Or metaball()\y > einstellungen\y : metaball()\yr = -metaball()\yr : EndIf
  Next

  FlipBuffers() 
  ClearScreen(0,0,0) 
  
  ExamineKeyboard() 
  If KeyboardPushed(#PB_Key_Escape) 
    exit = 1 
  EndIf 
  
Until exit = 1 
Benutzeravatar
Vallan
Beiträge: 223
Registriert: 20.01.2006 19:34
Kontaktdaten:

Beitrag von Vallan »

Hey cool :allright: ...
... Bloß sehr langsam. Außerdem sind die Punkte bei mir nur in nem kleinen bereich oben rechts.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

was is eigentlich mit RoWü... lebt der noch...?
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Der war bischen zu überheblich, bekam von den anderen usern was auf
die Nase und seit dem hören ma nichts mehr von ihm... übliche :|
Bild
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

Beitrag von Xaby »

Das erinnert mich an Liquid Wars, kennt ihr das.

Das ist ganz lustig. Gibts für Linux und Windows.

Da hat man sowas wie ne Flüssigkeit und muss den ,,Feind,, umsprudeln oder so ähnlich :roll:

Oder kennt jemand dieses QuecksilberSpiel für die PSP, das ist auch cool. Aber ist halt eher was für den 3D-Metaball.

Naja, wie auch immer. Der Gedanke zählt. :shock:
Kinder an die Macht http://scratch.mit.edu/
Antworten