Wasser Tropfen

Übersicht BlitzBasic Allgemein

Dieses Thema ist gesperrt, du kannst keine Beiträge editieren oder beantworten.

 

Ronon_Dex

Betreff: Wasser Tropfen

BeitragSa, März 31, 2012 15:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

Ich würde gerne ein Spiel erstellen in dem man Wasser leiten muss, indem man objekte zb vor den Strahl stellt und das Wasser somit zum Ziel gelenkt wird.

d.h. Ich bräuchte so eine Wasser Physik wie in dem Android Spiel "Where's my Water".

Das Problem ist nur, ich habe keine Ahnung wie ich soetwas hinbekommen soll ...
Hoffentlich könnt ihr mir helfen.


mfg

ZEVS

BeitragSa, März 31, 2012 15:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich mache es so, dass ich jeden Wassertropfen als Kreis darstelle. Der Rest ist recht einfach im Vergleich zu Physik von Objekten mit Kanten. Ich wende das Prinzip Verlet an, was besagt, dass man sich immer die letzte Position merkt, wo der Tropfen war, und dann den Unterschied zur aktuellen nimmt und den nochmal draufpackt.
BlitzBasic: [AUSKLAPPEN]
Type TCircle
Field x#, y#, radius#, lastX#, lastY#
End Type
Function DrawCircles()
For Local circle.TCircle = Each TCircle
Oval circle\x-circle\radius, circle\y-circle\radius, circle\radius*2, circle\radius*2
Next
End Function
Function UpdateCircles()
For Local circle.TCircle = Each TCircle
Local x# = circle\x, y# = circle\y
circle.x = circle.x + (circle.x-circle.lastX)
circle.y = circle.y + (circle.y-circle.lastY)
circle.lastX = x
circle.lastY = y
Next
End Function

(ungetestet)
Dadurch erhält man eine flüssige Bewegung. Um diese müssen wir uns jetzt nicht mehr kümmern, wir können einfach die X/Y-Koordinaten anpassen und fertig.
Zunächst sollten wir die Y-Koordinate stets um einen konstanten Wert erhöhen, dadurch haben wir Schwerkraft.
Schließlich fehlt noch die Kollision. Die Kollision mit dem Spielfeldrand gesteltet sich einfach, wir müssen ja nur darauf achten, dass die Tropfen/Kreise im Rahmen bleiben, den Rest erledigt Verlet. Die Kollision mit den Kreisen selbst ist erfreulicherweise einfach, wir müssen nur schauen, dass der Abstand stets die Summe der Radien beträgt. Hier führt leider nichts vernünftiges an Vektorrechnung vorbei
Code: [AUSKLAPPEN]
VektorX = circle1.x-circle2.x
VektorY = circle1.y-circle2.y
AktuelleDistanz = Sqr(VektorX*VektorX + VektorY*VektorY)
MindestDistanz = circle1.radius+circle2.radius
wenn AktuelleDistanz < MindestDistanz
Faktor = MindestDistanz/AktuelleDistanz
VektorX = VektorX*Faktor
VektorY = VektorY*Faktor
circle1.x = circle1.x-VektorX/2
circle1.y = circle1.y-VektorY/2
circle2.x = circle2.x+VektorX/2
circle2.y = circle2.y+VektorY/2

So sollte es klappen. Die weitere Kollision gestaltet sich teilweise ein bisschen komplexer, aber ich wäre froh, wenn du mir bis hierher folgen konntest. Ein einfacherer Ansatz fällt mir nicht ein.

ZEVS
 

Ronon_Dex

BeitragSa, März 31, 2012 16:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weis was du meinst und folgen konnte ich dir auch Smile
Doch dein Code funktioniert in B3D nicht.
Aber das kann ich auch noch selber probieren, ich habe ja deinen Ansatz.

Jedoch wird es schwerer wenn sich das Wasser so verhalten soll wie hier in dem Video oder ?:
http://www.youtube.com/watch?v...re=related

aber genau so etwas bräuchte ich eigentlich Sad

ZEVS

BeitragSa, März 31, 2012 16:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Wasser verhält sich ähnlich. Ich habe das ganze mal in BlitzMax implementiert, aber ich glaube nicht, dass dir das hier viel helfen würde.
Zitat:
Doch dein Code funktioniert in B3D nicht.
Es sind ein Type und zwei Funktionen, dir ist schon klar, dass Copy+Paste+[F5] nicht reicht?
Zitat:
Aber das kann ich auch noch selber probieren, ich habe ja deinen Ansatz.

Das war mein Ziel. Ich stehe dir natürlich weiter für Fragen zur Verfügung.

ZEVS
 

Ronon_Dex

BeitragSa, März 31, 2012 20:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich hab das mal bis jetz soweit hin bekommen und der Rand wird auch kein Problem werden...
jedoch weis ich nicht ganz wie ich das mit den Vektoren machen soll.
Denn in einer For-Schleife zu rechnen macht ja keinen Sinn,
weil ja sonst circle1 = circle2 ist, da, selber Tropfen

BlitzBasic: [AUSKLAPPEN]
AppTitle "Water Test"
Global gfx_max=800, gfx_min=600
Graphics gfx_max,gfx_min,32,0
SetBuffer BackBuffer()

Type tropfen
Field char, x#, y#, radius#, lastX#, lastY#
End Type

Color 0,0,190

For i=0 To 10
circle.tropfen = New tropfen
circle\radius = 1
circle\x = 50
circle\y = 50
Oval 50, 50-circle\radius, 2, 2
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Main Loop;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Repeat
;Cls
DrawCircles()
UpdateCircles()
Flip
Until KeyHit(1)
End

Function DrawCircles()
For circle.tropfen = Each tropfen
Oval circle\x, circle\y-circle\radius, 2, 2
Next
End Function

Function UpdateCircles()
For circle.tropfen = Each tropfen
Local x# = circle\x, y# = circle\y
circle\y = circle\y + 1
circle\x = circle\x + Rand(-1,1)
circle\lastX = x
circle\lastY = y
Next
End Function

Function Vektor(x1,x2,y1,y2)
For circle.tropfen = Each tropfen

Next
End Function


Sieht meiner Meinung nach auch schon garnicht so schlecht aus Very Happy

Xeres

Moderator

BeitragSa, März 31, 2012 20:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Dann schließt du den Fall einfach aus.
Code: [AUSKLAPPEN]
If circle1 <> circle2 then
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

ZEVS

BeitragSa, März 31, 2012 20:27
Antworten mit Zitat
Benutzer-Profile anzeigen
...oder kürzt ihn ab:
BlitzBasic: [AUSKLAPPEN]
For Local circle1.TCircle = Each TCircle
Local circle2.TCircle = After circle1
While circle2
;...
circle2 = After circle2
Wend
Next

Zu Beachten ist nur, dass dies das Minimum an Überprüfungen ist. So hast du zwar die geringste Laufzeit, aber ggf. musst du es dann mehrmals ausführen, damit es gut aussieht (je öfter die Kollision überprüft wird, desto weniger werden die Tropfen in andere Tropfen hinein "korrigiert")
Zitat:
Sieht meiner Meinung nach auch schon garnicht so schlecht aus

Nein, nur der Verlet-Gedanke ist noch nicht ausreichend umgesetzt. Du musst zunächst x und lastX gleich initialisieren - bisher hast du lastX fast ignoriert (gleiches gilt immer für y/lastY). Außerdem musst du immer den Vektor von der letzten zur momentanen Position hinzuaddieren.
ich (Eigenzitat; schlechter Stil) hat Folgendes geschrieben:
circle.x = circle.x + (circle.x-circle.lastX)
circle.y = circle.y + (circle.y-circle.lastY)


ZEVS
 

Ronon_Dex

BeitragSa, März 31, 2012 21:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe jetz diese Vektor Funktion erstellt:
BlitzBasic: [AUSKLAPPEN]
Function Vektor()
For circle.tropfen = Each tropfen
circle1x=circle\x
circle1y=circle\y
If tropfen <> tropfen Then
circle2x=circle\x
circle2y=circle\y
EndIf

VektorX = circle1x-circle2x
VektorY = circle1y-circle2y
AktuelleDistanz = Sqr(VektorX*VektorX + VektorY*VektorY)
MindestDistanz = circle\radius+circle\radius

If AktuelleDistanz < MindestDistanz Then
Faktor = MindestDistanz/AktuelleDistanz
VektorX = VektorX*Faktor
VektorY = VektorY*Faktor
circle1x = circle1x-VektorX/2
cirkle1y = circle1y-VektorY/2
circle2x = circle2x+VektorX/2
circle2y = circle2y+VektorY/2
EndIf
Next
End Function


Nur wie genau kann ich das jetz mit dem Rest verbinden ?

BlitzBasic: [AUSKLAPPEN]
AppTitle "Water Test"
Global gfx_max=800, gfx_min=600
Graphics gfx_max,gfx_min,32,0
SetBuffer BackBuffer()

Type tropfen
Field char, x#, y#, radius#, lastX#, lastY#
End Type

Color 0,0,190

For i=0 To 10
circle.tropfen = New tropfen
circle\radius = 1
circle\x = 50
circle\y = 50
circle\lastX = 50
circle\lastY = 50
Oval 50, 50-circle\radius, 2, 2
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Main Loop;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Repeat
;Cls
DrawCircles()
UpdateCircles()
Flip
Until KeyHit(1)
End

Function DrawCircles()
For circle.tropfen = Each tropfen
Oval circle\x, circle\y-circle\radius, 2, 2
Next
End Function

Function UpdateCircles()
For circle.tropfen = Each tropfen
Local x# = circle\x, y# = circle\y
circle\y = circle\y + (circle\y-circle\lasty)
circle\x = circle\x + (circle\x-circle\lastX)
circle\lastX = x
circle\lastY = y
Next
End Function
 

Ronon_Dex

Betreff: Push

BeitragDi, Apr 03, 2012 11:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich komme mit dem zusammenfügen nicht klar Sad
 

Ronon_Dex

BeitragFr, Apr 06, 2012 13:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok ... jetz fühl ich mich ignoriert Very Happy

Xeres

Moderator

BeitragFr, Apr 06, 2012 13:19
Antworten mit Zitat
Benutzer-Profile anzeigen
~GESCHLOSSEN~

Trippelpost ist mehr als genug.
Wer dir helfen wollte oder könnte, würde dies auch ohne push tun.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Dieses Thema ist gesperrt, du kannst keine Beiträge editieren oder beantworten.


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group