Pong Kollision Eintritt- Austrittwinkel

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Diablo

Betreff: Pong Kollision Eintritt- Austrittwinkel

BeitragSo, Feb 26, 2012 18:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ja ich habe gesucht, ich habe auch schon zig Seiten hier gelesen und zig Code durchwühlt (Einige haben echt schlechte Variablennamen um dort durchzusteigen...). Ich sitze jetzt aber schon paar Std. an meinem und wühle da immer noch drin rum...

Es dreht sich um folgendes; Ich mache aus Spielerei ein kleines Pong spiel und habe es auch soweit geschafft, dass sich der Ball bewegt, abprallt und auch an manchen Stellen in Form von Eintrittswinkel = Austrittswinkel, abprallt.

Allerdings funktioniert das ganze noch nicht so wirklich.

Folgende Fehler sind mir aufgefallen:

- Ball eiert erst mal im Startpunkt rum bis er dann los fliegt (dann fliegt er zu einer Wand und prallt dort korrekt ab)
- Ball prallt an Wand ab und verschwindet beim nächsten Kollidieren Shocked

Mein Code sieht wie folgt aus (Einige Dinge sind auskommentiert!!):

Code: [AUSKLAPPEN]

'// Class TBall
Type TBall

    Field ballX:Int, ballY:Int                        '// Ball Koordinaten X / Y
   Field ballSpeed:Int = 5                           '// Ballgeschwindigkeit
   Field ballRadius:Int = 25                        '// Ballgröße
   Field playerX:Int, playerY:Int                     '// Spielschläger Koordinaten X / Y
   Field playerHeight:Int = 10                        '//   Spielschlägerdicke
   Field playerWidth:Int = 80                        '// Spielschlägerlänge
   Field angle:Int = 360                           '// Ballwinkel
   Field deviation:Int                              '// Abweichung
   
      
   '// Draw the ball
   Method Draw(pX:Int, pY:Int)      
      Self.ballX = pX
      Self.ballY = pY
      
      DrawOval ballX, ballY, ballRadius, ballRadius      '// X, Y, Groeße X, Groeße Y
      DrawText "X: " + ballX, 5, 5                  '// X-Koordinaten
      DrawText "Y: " + ballY, 5, 20                  '// Y-Koordinaten
   End Method

      
'   '// Ballmovement
   Method Move()
      'ballX = ballX - ballSpeed
      'ballY = ballY + ballSpeed
      
      ballX = ballX + Cos(angle) * ballSpeed
      ballY = ballY - Sin(angle) * ballSpeed
   End Method

   
   '// Collision with Wall   
   Method Wall()
      
      If ballX > 772 Then
         angle = 180 - angle
      '   ballSpeed = -ballSpeed
      ElseIf ballX < 1
         angle = 180 - angle
      '   ballSpeed = -ballSpeed
      End If
      
      If ballY > 575 Then
         angle = 180 - angle
      '   ballSpeed = -ballSpeed
      ElseIf ballY < 1
         angle = 180 - angle
      '   ballSpeed = -ballSpeed
      End If
      
      '// Angle      
      If angle > 360 Then angle = angle - 360
      If angle < 0 Then angle = angle + 360
      
   End Method
   
   
   '// Collision with Stick
   Method Stick(pPlayerX:Int, pPlayerY:Int)

      Self.playerX = pPlayerX
      Self.playerY = pPlayerY
      
      If ballX > (playerX - ballRadius) And ballX < (playerX + playerWidth + ballRadius) Then
         angle = 360 - angle
          deviation = 2 * (playerY - ballX)
          angle = angle + deviation
         
            If ballY > (playerY - ballRadius) And ballY < (playerY + playerHeight + ballRadius) Then
               angle = 360 - angle
                deviation = 2 * (playerX - ballX)
                angle = angle + deviation
            EndIf
      EndIf
            
   End Method

End Type

www.pb-software.de.vu

Meine Entwicklungsseite

Diablo

BeitragSo, Feb 26, 2012 21:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Leider geht das Editieren nicht (?) Confused

Also das Austreten des Balles konnte ich folgendermaßen lösen:

Code: [AUSKLAPPEN]
   '// Collision with Wall   
   Method Wall()
      
      If ballX > 772 Then
         angle = 180 - angle
      ElseIf ballX < 1
         angle = 180 - angle
      End If
      
      If ballY > 575 Then
         angle = 180 + angle
      ElseIf ballY < 1
         angle = 180 + angle
      End If
      
      '// Angle      
      If angle > 360 Then angle = angle - 360
      If angle < 0 Then angle = angle + 360
      
   End Method


Aber so ganz funktioniert der Code mit dem Schläger noch nicht. Der Ball zappelt da noch ziemlich weit weg vom Schläger in der Luft (und prallt da auch ab) Rolling Eyes
www.pb-software.de.vu

Meine Entwicklungsseite
 

Lion

BeitragSo, Feb 26, 2012 21:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Gib dem Type zwei Field's dazu:
xDegree, yDegree
xDegree gibst du gleich am anfang den Wert von Cos(winkel), yDegree kriegt Sin(winkel).
Die Bewegung läuft nun wie folgt ab:
x=x+xDegree*speed
y=y+yDegree*speed

Wenn nun eine Kollision stattfindet, machst du folgendes:
xDegree:*-1
bzw.
yDegree:*-1
Das kehrt den Wert um und damit auch die ganze Bewegung.
Du musst immer nur eines von den beiden machen, das kommt drauf an, aus welchem Winkel die Kollision stattfindet (siehe dazu die Sachen in der Wall()-Methode).
Intel Core 2 Quad 4x2.66 ghz - 4gb ddr2 - nvidia GeForce GTX660 2gb
Intel Atom 1x1.83 ghz - 2gb ddr2 - intel GMA 3150 256mb
AMD A10-5750M 4x2.5 ghz - 8 gb ddr4 - AMD R9 M290x

Diablo

BeitragSo, Feb 26, 2012 22:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Habe noch einwenig rum probiert, aber an einigen Stellen funktioniert mein Code, aber an anderen Stellen prallt der Ball im Eintrittswinkel wieder ab...

@Lion: So ganz verstehe ich deins nicht Embarassed
www.pb-software.de.vu

Meine Entwicklungsseite

DaysShadow

BeitragMo, Feb 27, 2012 0:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Vereinfacht gesagt:

Wenn dein Ball, sagen wir vom linken Paddle, startet in Richtung rechts oben, dann wäre xDegree positiv und yDegree negativ, da die Position in x-Richtung steigt und in y-Richtung abnimmt( 0,0 ist oben links, width,height ist unten rechts ).

Kommt er dann bei y = 0 an, musst du die Richtung für y ändern, also dein yDegree und zwar nur das. Da es eben negativ war muss es jetzt positiv sein, das erreichst du halt indem du *(-1) nimmst.

So, jetzt bewegt er sich nach rechts(unverändert) und nach unten, xDegree ist unverändert positiv und yDegree haben wir gerade umgedreht auf positiv.

Knallt er jetzt an das rechte Paddle musst du nur xDegree ändern, also xDegree *(-1).

Jetzt bewegt sich der Ball nach links und unten(unverändert).

Kommt er jetzt bei height - ballheight an, eben an der unteren Grenze, dann musst du nur wieder yDegree umdrehen.

Jetzt bewegt sich der Ball nach links(unverändert) und nach oben.

Als nächstes bist du wieder am Anfang und dasselbe geht von vorne los.

Mal es dir auf Papier auf zur Not, spiels durch, überlege dir die Werte usw., war auch mein erstes "Spiel".
Ich will es mal nicht so schimpfen, denn es war grottig Wink
Blessed is the mind too small for doubt

BladeRunner

Moderator

BeitragMo, Feb 27, 2012 10:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Was klappte denn beim editieren nicht, diablo? Kurze PM mit Fehlerbeschreibung wäre nett, danke.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Diablo

BeitragMo, Feb 27, 2012 12:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab dir eine geschrieben. Bin gespannt.

EDIT: Ok, war "nur" auf das Editieren des Beitrages gerichtet.

Wer sich meinen Code mal anschauen möchte, kann dies hier tun: http://pb-software.pf-control....ng_src.zip

Komme da noch nicht so recht weiter.

Fehler sind:

- Ball prallt nicht immer vom Schläger ab, sondern geht manchmal durch bzw. "verhakt" sich dort und prallt dann erst ab
- Ball geht manchmal durch die "Wand"
- Ball springt immer von der oberen Wand zur linken Wand ab und verhakt sich dann in der linken oberen Ecke.


Habe das ganze jetzt auch bisschen mit xDegree & yDegree ausprobiert, aber so ganz komme ich damit immer noch nicht klar, wobei ich das Prinzip verstanden und aufgemalt habe. Wink

Wie gesagt, schaut euch den Sourcecode an, ist nur etwas durcheinander, wegen dem rumprobieren Rolling Eyes
www.pb-software.de.vu

Meine Entwicklungsseite
 

Lion

BeitragMo, Feb 27, 2012 15:17
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzMax: [AUSKLAPPEN]

'// Class TBall
Type TBall

Field ballX:Float, ballY:Float '// Ball Koordinaten X / Y
Field ballSpeed:Int = 5 '// Ballgeschwindigkeit
Field ballRadius:Int = 25 '// Ballgröße
Field playerX:Int, playerY:Int '// Spielschläger Koordinaten X / Y
Field playerHeight:Int = 10 '// Spielschlägerdicke
Field playerWidth:Int = 80 '// Spielschlägerlänge
Field angle:Int '// Ballwinkel
Field deviation:Int '// Abweichung
Field xDegree:Float
Field yDegree:Float


'// Draw the ball
Method Draw(pX:Int, pY:Int)
Self.ballX = pX
Self.ballY = pY

DrawOval ballX, ballY, ballRadius, ballRadius '// X, Y, Groeße X, Groeße Y
DrawText "X: " + ballX, 5, 5 '// X-Koordinaten
DrawText "Y: " + ballY, 5, 20 '// Y-Koordinaten
End Method


'// Ballreset
Method ResetBall()

If KeyHit(KEY_SPACE) Then
ballX = 800 / 2
ballY = 600 / 2
If Rand(0, 1) = 1 Then
angle = Rnd(105, 45)
Else
angle = Rnd(315, 225)
End If
xDegree = Cos(angle)
yDegree = Sin(angle)
ballSpeed = 5
End If
End Method


'// Ballmovement
Method Move()
ballX = ballX + xDegree * ballSpeed
ballY = ballY - yDegree * ballSpeed
End Method


'// Collision with Wall
Method Wall()

If ballX > 772 Then
xDegree:*- 1
ElseIf ballX <= 1
xDegree:*- 1
End If

If ballY >= 575 Then
yDegree:*- 1
ElseIf ballY <= 1
yDegree:*- 1
End If

'// Angle
If angle > 360 Then angle = angle - 360
If angle < 0 Then angle = angle + 360

End Method


'// Collision with Stick
Method Stick(pPlayerX:Int, pPlayerY:Int)

Self.playerX = pPlayerX
Self.playerY = pPlayerY

If ballX > (playerX - ballRadius) And ballX < (playerX + playerWidth + ballRadius) Then
'' angle = 360 - angle
'' deviation = 2 * (playerX - ballX)
'' angle = angle + deviation
'
If ballY > (playerY - ballRadius) And ballY < (playerY + playerHeight + ballRadius) Then
angle = 360 - angle
deviation = 2 * (playerX - ballX)
angle = angle - deviation
EndIf
EndIf


End Method

End Type



Meine fresse, dein code ist unstrukturiert. Warum hast du für ein so kleines Projekt gleich 3 dateien? Da muss man sich ja alles erstmal zusammensuchen...
Also, da ist der gefixte code.
Abgesehen von der Tatsache, dass du den Kram, den wir dir erklärt haben, nicht eingebaut hast, war dein Hauptproblem, dass du weder die Koordinaten noch X/YDegree als Float gesetzt hast. Da die Zahlen sehr gering sind (Sin und Cos werte sind immer von -1,0 - 1,0) wird in einem Integer daher eher gar nichts gespeichert und die Bewegung kommt nicht zu stande, da für die Integer immer abgerundet wird.
So geht es jetzt, aber bitte strukturier das ganze doch mal Smile
Intel Core 2 Quad 4x2.66 ghz - 4gb ddr2 - nvidia GeForce GTX660 2gb
Intel Atom 1x1.83 ghz - 2gb ddr2 - intel GMA 3150 256mb
AMD A10-5750M 4x2.5 ghz - 8 gb ddr4 - AMD R9 M290x

Diablo

BeitragMo, Feb 27, 2012 17:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke!! Hatte eben auch schon dran gedacht, dass das ja gar kein Integer sein kann, sondern nur eine Fließkommazahl Rolling Eyes

Hatte das halt immer wieder ein- und ausgebaut (und auskommentiert), weils halt nicht so geklappt hat wie ichs dachte. Nun gehts ja, danke dafür!

Und dann habe ich noch mal zur Verständnis eine Frage:

Und zwar habe mal testweise

Code: [AUSKLAPPEN]
xDegree = Cos(angle)
yDegree = Sin(angle)

in die Methode "Move()" eingebaut:

Code: [AUSKLAPPEN]
   '// Ballmovement
   Method Move()
               
                xDegree = Cos(angle)
                yDegree = Sin(angle)
   
      ballX = ballX + xDegree * ballSpeed
      ballY = ballY - yDegree * ballSpeed
   
   End Method


Warum funktioniert das dann wiederum nicht? Nur wenn man es "händisch" mit der Leertaste macht, funktioniert es:

Code: [AUSKLAPPEN]
'// Ballreset
   Method ResetBall()
      
      If KeyDown(KEY_SPACE) Then
         ballX = 800 / 2
         ballY = 600 / 2
         If Rand(0, 1) = 1 Then
            angle = Rnd(105, 45)
         Else
            angle = Rnd(315, 225)
         End If
         xDegree = Cos(angle)
         yDegree = Sin(angle)
      End If
   
   End Method


Achso, moment!! Ich gebe da ja dem Winkel einen Zufallswert mit... Und bei der Methode "Move()" passiert ja nichts mit dem Winkel Idea Question


Zum strukturiertem Code: Wieso ist der unstrukturiert. Ich bin es gewohnt, bei einer Klasse eine neue Datei zu haben.
In dem Fall habe ich eine Klasse "Main", eine Klasse "Player" und eine Klasse "Ball". Natürlich macht es bei so einem kleinen Projekt nicht all zu viel Sinn, aber in Gewisserweise ja schon, so hat man eben nicht alles in einer Datei und zig Code wo man erst mal lange scrollen und suchen muss. Theo. hätte auch Ball von Player erben können...

Meiner Meinung nach ist das doch u.a. der Sinn von OOP?
www.pb-software.de.vu

Meine Entwicklungsseite
 

Lion

BeitragMo, Feb 27, 2012 20:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja richtig, der Winkel bleibt der gleiche, das da nicht passiert liegt einfach daran, dass die ersetzten Werte genau wie die alten sind.

Naja, das mit dem unstrukturiert ist wohl geschmackssache, aber ich würd auf keinen Fall für jede Klasse eine Datei anlegen, ich hab ungern ~30-40 Tabs später offen.
Dazu kommt aber bei dir, dass wahllos Kommentarzeilen überall dazwischen sind, nen Haufen Leerzeichen ohne einen ersichtlichen Grund und die Einrückung auch nicht immer so ist, wie sie sein sollte.
Das gewöhnt man sich einfach irgendwann an, wenn man dann nen Code sieht der von einem "Anfänger" ist, findet man sich nicht sonderlich gut zurecht.
Das mit den Dateien, da bin ich aber auch ehrlich gesagt einer, der lieber alles in einem hat und nur auslagert, woran er nicht ständig arbeitet, da kann man mich genau so anprangern... Mein derzeitiges Projekt hat fast 12.000 Zeilen und ich hab es lediglich in 3 größeren Dateien und nur ein paar kleinere Dateien in denen Konstanten liegen. Das liegt aber bei mir daran, dass ich eben ständig an sämtlichen Teilen des Projekts arbeiten muss und nicht immer zwischen den Tabs herswitchen möchte, und sofern der Code halbwegs gut strukturiert ist, findet man auch alles wieder, selbst wenn die Datei 5000 Zeilen hat.
Intel Core 2 Quad 4x2.66 ghz - 4gb ddr2 - nvidia GeForce GTX660 2gb
Intel Atom 1x1.83 ghz - 2gb ddr2 - intel GMA 3150 256mb
AMD A10-5750M 4x2.5 ghz - 8 gb ddr4 - AMD R9 M290x

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group