Ball versinkt im Stein [gelöst]
Übersicht

![]() |
BigSnakeBetreff: Ball versinkt im Stein [gelöst] |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das scheint nur mit Winkeln von einem Vielfachen von 45° zu passieren. Allerdings hab ich noch keine Lösung gefunden, um das zu verhindern. Mit den unten stehenden Werten sieht man das Problem sofort. Vieleicht hat ja jemand einen Ansatz für eine Lösung
Code: [AUSKLAPPEN] ; --- Bibliotheken ------------------------------------------------------ ;Include "XX.bb" ; --- Konstanten -------------------------------------------------------- Const MaxBlocks = 200 ; --- Typen ------------------------------------------------------------- Type T_Ball ; Repräsentiert einen Ball ; Die Kollisionsabfrage erfolgt in jedem Frame über jeweils 0.1 ; Pixel Schritte Field X# Field Y# Field W# Field H# Field Angle# Field Speed# End Type Type T_Block ; Repräsentiert einen Spielstein ; Kann beliebig positioniert werden und beliebige Ausmaße haben Field X Field Y Field W Field H Field A ; Attribut bestimmt das Verhalten bei Berührung Field P ; Stabilitätspunkte > 0 wird dargestellt End Type ; --- Variablen --------------------------------------------------------- Global SecX,SecY,SecW,SecH ; Ausmaße des Spielfeldes Global Timer ; 86 FPS, alle Bewegungen sind darauf getimet Global Ball.T_Ball = New T_Ball Global Lv Dim Block.T_Block(MaxBlocks) For lv = 1 To MaxBlocks Step 1 Block.T_Block(Lv) = New T_Block Next ; --- Hauptprogramm ----------------------------------------------------- ;XGraphics 800,600,32,2 ;XXInitEngine Graphics 800,600,32,2 SetBuffer BackBuffer() SeedRnd MilliSecs() AppTitle "Blitz Ball - (C) 2003 by Lars Roth" Timer = CreateTimer(86) SecX = 10 SecY = 10 SecW = 780 SecH = 580 Ball\X = 100 Ball\Y = 100 Ball\W = 20 Ball\H = 20 Ball\Angle = 45 Ball\Speed = 3 Block(1)\P = 1 Block(1)\X = 200 Block(1)\Y = 200 Block(1)\W = 100 Block(1)\H = 100 Repeat ; Hintergrund Cls ; Rand Color 255,255,255 Rect SecX,SecY,SecW,SecH,0 ; Blöcke zeichnen For lv = 1 To MaxBlocks Step 1 If Block(lv)\P > 0 Then Color 0,155,0 Rect Block(lv)\X,Block(lv)\Y,Block(lv)\W,Block(lv)\H EndIf Next ; Ball Color 255,0,0 Oval Ball\X,Ball\Y,Ball\W,Ball\H ; Bewegung des Balls MoveBall(Ball) ; Bild anzeigen WaitTimer Timer ;XUpdateScreen3d ;XUpdateScreen2d Flip Until KeyHit(1) End ; --- Funktionen -------------------------------------------------------- Function MoveBall(B.T_Ball) Local St# Local LeftPx#,RightPx#,TopPx#,BottomPx# For St = 0 To B\Speed Step 0.1 ; Bewegt den Ball in 0.1 Pixel Schritten B\X = B\X + 0.1 * Cos(B\Angle) B\Y = B\Y + 0.1 * Sin(B\Angle) ; Kollision mit den Wänden If (B\Y < SecY) Then ; Kollision mit der oberen Wand B\Angle = NewAngle(B\Angle) ElseIf ((B\Y + B\H) > (SecY + SecH)) Then ; Kollision mit der unteren Wand : Verloren ! B\Angle = NewAngle(B\Angle) ElseIf (B\X < SecX) Then ; Kollision mit der linken Wand B\Angle = NewAngle(B\Angle) ElseIf ((B\X + B\W) > (SecX + SecW)) Then ; Kollision mit der rechten Wand B\Angle = NewAngle(B\Angle) EndIf ; Kollision mit einem Block For lv=1 To MaxBlocks Step 1 If (Block(lv)\P > 0) Then If (B\X >= Block(lv)\x) And (B\X <= (Block(lv)\X + Block(lv)\W)) Then If (B\Y >= Block(lv)\Y) And (B\Y <= (Block(lv)\Y + Block(lv)\H)) Then ; Kollision mit dem Block B\Angle = NewAngle(B\Angle) ; Setzt den Ball außerhalb des Blocks ; Dafür muß zuerst einmal festgestellt werden zu welcher Seite ; der Abstand am geringsten ist LeftPx = B\X - Block(lv)\X RightPx = (B\X + B\W) - (Block(lv)\X + Block(lv)\W) TopPx = B\Y - Block(lv)\Y BottomPx = (B\X + B\H) - (Block(lv)\X + Block(lv)\H) ;If (LeftPx = TopPx) Then ; ; Linke obere Ecke ; B\X = Block(lv)\X - B\W - 0.1 ; B\Y = Block(lv)\Y - B\H - 0.1 ;EndIf If (LeftPx < RightPx) And (LeftPx < TopPx) And (LeftPx < BottomPx) Then ; Links neben den Stein setzen B\X = Block(lv)\X - B\W - 0.1 EndIf If (RightPx < LeftPx) And (RightPx < TopPx) And (RightPx < BottomPx) Then ; Rechts neben den Stein setzen B\X = Block(lv)\X + Block(lv)\W + 0.1 EndIf If (TopPx < RightPx) And (TopPx < LeftPx) And (TopPx < BottomPx) Then ; Über den Stein setzen B\Y = Block(lv)\Y - B\H - 0.1 EndIf If (BottomPx < LeftPx) And (BottomPx < RightPx) And (BottomPx < TopPx) Then ; Unter den Stein setzen B\Y = Block(lv)\Y + Block(lv)\H + 0.1 EndIf EndIf EndIf EndIf Next Next End Function Function NewAngle#(OldAngle#) If ((OldAngle >= 315) Or (OldAngle < 45)) Then ; Berührt Hindernis von links If (OldAngle >= 315) Then ; Kommt von schräg unten Return (180 + 360 - OldAngle) Else ; Kommt von schräg oben Return (180 - OldAngle) EndIf ElseIf ( ( OldAngle >= 135) And ( OldAngle < 225 ) ) Then ; Berührt Hindernis von rechts If (OldAngle >= 180) Then ; Kommt von schräg unten Return (360 - (OldAngle - 180)) Else ; Kommt von schräg oben Return (180 - OldAngle) EndIf ElseIf ( ( OldAngle >= 225) And ( OldAngle <= 315 ) ) Then ; Berührt Hindernis von oben If (OldAngle > 270) Then ; Kommt von schräg links Return (90 - (OldAngle - 270)) Else ; Kommt von schräg rechts Return (90 + (270 - OldAngle)) EndIf ElseIf ( ( OldAngle >= 45 ) And ( OldAngle <= 135 ) ) Then ; Berührt Hindernis von unten If (OldAngle >= 90) Then ; Kommt von schräg rechts Return (270 - (OldAngle - 90)) Else ; Kommt von schräg links Return (270 + (90 - OldAngle)) EndIf EndIf End Function |
||
- Zuletzt bearbeitet von BigSnake am Mo, Apr 12, 2004 10:33, insgesamt einmal bearbeitet
![]() |
Garfield |
![]() Antworten mit Zitat ![]() |
---|---|---|
Auf den ersten Blick erscheint es, das Du natürlich immer den Mittelpunkt des Kreises berechnest und darum der Ball immer versinkt.
Man muss sich erstmal in Deine Physik eindenken...... vieleicht komm ich später drauf ![]() |
||
![]() |
BigSnake |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mhh jo das Problem ist nun gelöst. Ändere ich nun aber den Winkel geht gar nichts mehr ![]() Code: [AUSKLAPPEN] ; --- Bibliotheken ------------------------------------------------------ ;Include "XX.bb" ; --- Konstanten -------------------------------------------------------- Const MaxBlocks = 200 Const MaxBalls = 10 ; --- Typen ------------------------------------------------------------- Type T_Ball ; Repräsentiert einen Ball ; Die Kollisionsabfrage erfolgt in jedem Frame über jeweils 0.1 ; Pixel Schritte Field X# Field Y# Field W# Field H# Field Angle# Field Speed# Field Active End Type Type T_Block ; Repräsentiert einen Spielstein ; Kann beliebig positioniert werden und beliebige Ausmaße haben Field X Field Y Field W Field H Field A ; Attribut bestimmt das Verhalten bei Berührung Field P ; Stabilitätspunkte > 0 wird dargestellt End Type ; --- Variablen --------------------------------------------------------- Global SecX,SecY,SecW,SecH ; Ausmaße des Spielfeldes Global Timer ; 86 FPS, alle Bewegungen sind darauf getimet Dim Ball.T_Ball(MaxBalls) Global Lv Dim Block.T_Block(MaxBlocks) For lv = 1 To MaxBlocks Step 1 Block.T_Block(Lv) = New T_Block Next For lv = 1 To MaxBalls Step 1 Ball.T_Ball(lv) = New T_Ball Next ; --- Hauptprogramm ----------------------------------------------------- ;XGraphics 800,600,32,2 ;XXInitEngine Graphics 800,600,32,2 SetBuffer BackBuffer() SeedRnd MilliSecs() AppTitle "Blitz Ball - (C) 2003 by Lars Roth" Timer = CreateTimer(86) SecX = 10 SecY = 10 SecW = 780 SecH = 580 Ball(1)\X = 100 Ball(1)\Y = 100 Ball(1)\W = 20 Ball(1)\H = 20 Ball(1)\Angle = 50 Ball(1)\Speed = 3 Ball(1)\Active = True Block(1)\P = 1 Block(1)\X = 200 Block(1)\Y = 200 Block(1)\W = 100 Block(1)\H = 100 ;Block(2)\P = 1 Block(2)\X = 450 Block(2)\Y = 250 Block(2)\W = 50 Block(2)\H = 50 ;Block(3)\P = 1 Block(3)\X = 300 Block(3)\Y = 300 Block(3)\W = 30 Block(3)\H = 30 ;Block(4)\P = 1 Block(4)\X = 600 Block(4)\Y = 100 Block(4)\W = 50 Block(4)\H = 50 ;Block(5)\P = 1 Block(5)\X = 600 Block(5)\Y = 400 Block(5)\W = 100 Block(5)\H = 20 ;Block(6)\P = 1 Block(6)\X = 30 Block(6)\Y = 500 Block(6)\W = 60 Block(6)\H = 56 Repeat ; Hintergrund Cls ; Rand Color 255,255,255 Rect SecX,SecY,SecW,SecH,0 ; Blöcke zeichnen For lv = 1 To MaxBlocks Step 1 If Block(lv)\P > 0 Then Color 0,155,0 Rect Block(lv)\X,Block(lv)\Y,Block(lv)\W,Block(lv)\H EndIf Next ; Ball ; Bewegung des Balls For BallNr = 1 To MaxBalls Step 1 If Ball(BallNr)\Active Then Color 255,0,0 Oval Ball(BallNr)\X,Ball(BallNr)\Y,Ball(BallNr)\W,Ball(BallNr)\H MoveBall(Ball(BallNr)) EndIf Next ; Bild anzeigen WaitTimer Timer ;XUpdateScreen3d ;XUpdateScreen2d Flip Until KeyHit(1) End ; --- Funktionen -------------------------------------------------------- Function MoveBall(B.T_Ball) Local St# Local LeftPx#,RightPx#,TopPx#,BottomPx# For St = 0 To B\Speed Step 0.1 ; Bewegt den Ball in 0.1 Pixel Schritten B\X = B\X + 0.1 * Cos(B\Angle) B\Y = B\Y + 0.1 * Sin(B\Angle) ; Kollision mit den Wänden If (B\Y < SecY) Then ; Kollision mit der oberen Wand B\Angle = NewAngle(B\Angle) ElseIf ((B\Y + B\H) > (SecY + SecH)) Then ; Kollision mit der unteren Wand : Verloren ! B\Angle = NewAngle(B\Angle) ElseIf (B\X < SecX) Then ; Kollision mit der linken Wand B\Angle = NewAngle(B\Angle) ElseIf ((B\X + B\W) > (SecX + SecW)) Then ; Kollision mit der rechten Wand B\Angle = NewAngle(B\Angle) EndIf ; Kollision mit einem Block For lv=1 To MaxBlocks Step 1 If (Block(lv)\P > 0) Then If ((B\X + B\W) >= Block(lv)\x) And (B\X <= (Block(lv)\X + Block(lv)\W)) Then If ((B\Y + B\H) >= Block(lv)\Y) And (B\Y <= (Block(lv)\Y + Block(lv)\H)) Then ; Kollision mit dem Block B\Angle = NewAngle(B\Angle) EndIf EndIf EndIf Next Next End Function Function NewAngle#(OldAngle#) If ((OldAngle >= 315) Or (OldAngle < 45)) Then ; Berührt Hindernis von links If (OldAngle >= 315) Then ; Kommt von schräg unten Return (180 + 360 - OldAngle) Else ; Kommt von schräg oben Return (180 - OldAngle) EndIf ElseIf ( ( OldAngle >= 135) And ( OldAngle < 225 ) ) Then ; Berührt Hindernis von rechts If (OldAngle >= 180) Then ; Kommt von schräg unten Return (360 - (OldAngle - 180)) Else ; Kommt von schräg oben Return (180 - OldAngle) EndIf ElseIf ( ( OldAngle >= 225) And ( OldAngle <= 315 ) ) Then ; Berührt Hindernis von oben If (OldAngle > 270) Then ; Kommt von schräg links Return (90 - (OldAngle - 270)) Else ; Kommt von schräg rechts Return (90 + (270 - OldAngle)) EndIf ElseIf ( ( OldAngle >= 45 ) And ( OldAngle <= 135 ) ) Then ; Berührt Hindernis von unten If (OldAngle >= 90) Then ; Kommt von schräg rechts Return (270 - (OldAngle - 90)) Else ; Kommt von schräg links Return (270 + (90 - OldAngle)) EndIf EndIf End Function |
||
![]() |
BigSnake |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das ist mein bisheriger Ansatz. Kollision von links und oben funktioniert nun, nur von rechts und unten nicht
Code: [AUSKLAPPEN] ; --- Bibliotheken ------------------------------------------------------ ;Include "XX.bb" ; --- Konstanten -------------------------------------------------------- Const MaxBlocks = 200 Const MaxBalls = 10 ; --- Typen ------------------------------------------------------------- Type T_Ball ; Repräsentiert einen Ball ; Die Kollisionsabfrage erfolgt in jedem Frame über jeweils 0.1 ; Pixel Schritte Field X# Field Y# Field W# Field H# Field Angle# Field Speed# Field Active End Type Type T_Block ; Repräsentiert einen Spielstein ; Kann beliebig positioniert werden und beliebige Ausmaße haben Field X Field Y Field W Field H Field A ; Attribut bestimmt das Verhalten bei Berührung Field P ; Stabilitätspunkte > 0 wird dargestellt End Type ; --- Variablen --------------------------------------------------------- Global SecX,SecY,SecW,SecH ; Ausmaße des Spielfeldes Global Timer ; 86 FPS, alle Bewegungen sind darauf getimet Dim Ball.T_Ball(MaxBalls) Global Lv Dim Block.T_Block(MaxBlocks) For lv = 1 To MaxBlocks Step 1 Block.T_Block(Lv) = New T_Block Next For lv = 1 To MaxBalls Step 1 Ball.T_Ball(lv) = New T_Ball Next ; --- Hauptprogramm ----------------------------------------------------- ;XGraphics 800,600,32,2 ;XXInitEngine Graphics 800,600,32,2 SetBuffer BackBuffer() SeedRnd MilliSecs() AppTitle "Blitz Ball - (C) 2003 by Lars Roth" Timer = CreateTimer(86) SecX = 10 SecY = 10 SecW = 780 SecH = 580 Ball(1)\X = 100 Ball(1)\Y = 100 Ball(1)\W = 20 Ball(1)\H = 20 Ball(1)\Angle = 300 Ball(1)\Speed = 3 Ball(1)\Active = True Block(1)\P = 1 Block(1)\X = 200 Block(1)\Y = 200 Block(1)\W = 100 Block(1)\H = 100 ;Block(2)\P = 1 Block(2)\X = 450 Block(2)\Y = 250 Block(2)\W = 50 Block(2)\H = 50 ;Block(3)\P = 1 Block(3)\X = 300 Block(3)\Y = 300 Block(3)\W = 30 Block(3)\H = 30 ;Block(4)\P = 1 Block(4)\X = 600 Block(4)\Y = 100 Block(4)\W = 50 Block(4)\H = 50 ;Block(5)\P = 1 Block(5)\X = 600 Block(5)\Y = 400 Block(5)\W = 100 Block(5)\H = 20 ;Block(6)\P = 1 Block(6)\X = 30 Block(6)\Y = 500 Block(6)\W = 60 Block(6)\H = 56 Repeat ; Hintergrund Cls ; Rand Color 255,255,255 Rect SecX,SecY,SecW,SecH,0 ; Blöcke zeichnen For lv = 1 To MaxBlocks Step 1 If Block(lv)\P > 0 Then Color 0,155,0 Rect Block(lv)\X,Block(lv)\Y,Block(lv)\W,Block(lv)\H EndIf Next ; Ball ; Bewegung des Balls For BallNr = 1 To MaxBalls Step 1 If Ball(BallNr)\Active Then Color 255,0,0 Oval Ball(BallNr)\X,Ball(BallNr)\Y,Ball(BallNr)\W,Ball(BallNr)\H MoveBall(Ball(BallNr)) EndIf Next If KeyDown(34) Ball(1)\Angle = Ball(1)\Angle + 1 EndIf ; Bild anzeigen WaitTimer Timer ;XUpdateScreen3d ;XUpdateScreen2d Flip Until KeyHit(1) End ; --- Funktionen -------------------------------------------------------- Function MoveBall(B.T_Ball) Local St# Local LeftPx#,RightPx#,TopPx#,BottomPx#,AxisY#,AxisX# For St = 0 To B\Speed Step 0.1 ; Bewegt den Ball in 0.1 Pixel Schritten B\X = B\X + 0.1 * Cos(B\Angle) B\Y = B\Y + 0.1 * Sin(B\Angle) ; Kollision mit den Wänden If (B\Y < SecY) Then ; Kollision mit der oberen Wand B\Angle = NewAngleTop(B\Angle) ElseIf ((B\Y + B\H) > (SecY + SecH)) Then ; Kollision mit der unteren Wand : Verloren ! B\Angle = NewAngleBottom(B\Angle) ElseIf (B\X < SecX) Then ; Kollision mit der linken Wand B\Angle = NewAngleLeft(B\Angle) ElseIf ((B\X + B\W) > (SecX + SecW)) Then ; Kollision mit der rechten Wand B\Angle = NewAngleRight(B\Angle) EndIf ; Kollision mit einem Block For lv=1 To MaxBlocks Step 1 If (Block(lv)\P > 0) Then If ((B\X + B\W) >= Block(lv)\x) And (B\X <= (Block(lv)\X + Block(lv)\W)) Then If ((B\Y + B\H) >= Block(lv)\Y) And (B\Y <= (Block(lv)\Y + Block(lv)\H)) Then ; Kollision mit dem Block ; Es muß bestimmt werden an welcher Seite der Ball ist ; Dementsprechend kann dann ein neuer Winkel bestimmt werden LeftPx = Block(lv)\X - (B\X + B\W) RightPx = (Block(lv)\X + Block(lv)\W) - (B\X + B\W) TopPx = Block(lv)\Y - (B\Y + B\H) BottomPx = (Block(lv)\Y + Block(lv)\H) - (B\Y + B\H) ; Vertikal oder Horizontal If (TopPx > BottomPx) Then AxisY = TopPx Else AxisY = BottomPx EndIf If (LeftPx > RightPx) Then AxisX = LeftPx Else AxisX = RightPx EndIf If (AxisX > AxisY) Then ; Horizontale Kollision If (LeftPx > RightPx) Then ; Schlägt von rechts auf B\Angle = NewAngleLeft(B\Angle) Else ; Schlägt von links auf B\Angle = NewAngleRight(B\Angle) EndIf Else ; Vertikale Kollision If (BottomPx > TopPx) Then ; Schlägt auf der oberen Seite auf B\Angle = NewAngleBottom(B\Angle) Else ; Schlägt auf der unteren Seite auf B\Angle = NewAngleTop(B\Angle) EndIf EndIf ;B\Angle = NewAngle(B\Angle) EndIf EndIf EndIf Next Next End Function Function NewAngleTop#(OldAngle#) ; Berührt Hindernis von unten If (OldAngle >= 180) Then ; Kommt von schräg rechts Return (270 - (OldAngle - 90)) Else ; Kommt von schräg links Return (270 + (90 - OldAngle)) EndIf End Function Function NewAngleBottom#(OldAngle#) ; Berührt Hindernis von oben If (OldAngle >= 180) Then ; Kommt von schräg links Return (90 - (OldAngle - 270)) Else ; Kommt von schräg rechts Return (90 + (270 - OldAngle)) EndIf End Function Function NewAngleLeft#(OldAngle#) ; Berührt Hindernis von rechts If (OldAngle >= 90) Then ; Kommt von schräg unten Return (360 - (OldAngle - 180)) Else ; Kommt von schräg oben Return (180 - OldAngle) EndIf End Function Function NewAngleRight#(OldAngle#) ; Berührt Hindernis von links If (OldAngle > 270) Then ; Kommt von schräg unten Return (180 + 360 - OldAngle) Else ; Kommt von schräg oben Return (180 - OldAngle) EndIf End Function |
||
![]() |
BigSnake |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mit den meisten Winkeln und in den meisten Situationen funktioniert es nun abe manchmal verhält der Ball sich einfach komisch und ich hab keine Ahnung warum *haarerauf* Mit g läßt sich der Winkel verändern, so daß man es selbst ausprobieren kann
Code: [AUSKLAPPEN] ; --- Bibliotheken ------------------------------------------------------ ;Include "XX.bb" ; --- Konstanten -------------------------------------------------------- Const MaxBlocks = 200 Const MaxBalls = 10 ; --- Typen ------------------------------------------------------------- Type T_Ball ; Repräsentiert einen Ball ; Die Kollisionsabfrage erfolgt in jedem Frame über jeweils 0.1 ; Pixel Schritte Field X# Field Y# Field W# Field H# Field Angle# Field Speed# Field Active End Type Type T_Block ; Repräsentiert einen Spielstein ; Kann beliebig positioniert werden und beliebige Ausmaße haben Field X Field Y Field W Field H Field A ; Attribut bestimmt das Verhalten bei Berührung Field P ; Stabilitätspunkte > 0 wird dargestellt End Type ; --- Variablen --------------------------------------------------------- Global SecX,SecY,SecW,SecH ; Ausmaße des Spielfeldes Global Timer ; 86 FPS, alle Bewegungen sind darauf getimet Dim Ball.T_Ball(MaxBalls) Global Lv Dim Block.T_Block(MaxBlocks) For lv = 1 To MaxBlocks Step 1 Block.T_Block(Lv) = New T_Block Next For lv = 1 To MaxBalls Step 1 Ball.T_Ball(lv) = New T_Ball Next ; --- Hauptprogramm ----------------------------------------------------- ;XGraphics 800,600,32,2 ;XXInitEngine Graphics 800,600,32,2 SetBuffer BackBuffer() SeedRnd MilliSecs() AppTitle "Blitz Ball - (C) 2003 by Lars Roth" Timer = CreateTimer(86) SecX = 10 SecY = 10 SecW = 780 SecH = 580 Ball(1)\X = 250 Ball(1)\Y = 350 Ball(1)\W = 20 Ball(1)\H = 20 Ball(1)\Angle = 270 Ball(1)\Speed = 3 Ball(1)\Active = True Block(1)\P = 1 Block(1)\X = 200 Block(1)\Y = 200 Block(1)\W = 100 Block(1)\H = 100 Block(2)\P = 1 Block(2)\X = 450 Block(2)\Y = 250 Block(2)\W = 50 Block(2)\H = 50 Block(3)\P = 1 Block(3)\X = 300 Block(3)\Y = 300 Block(3)\W = 30 Block(3)\H = 30 Block(4)\P = 1 Block(4)\X = 600 Block(4)\Y = 100 Block(4)\W = 50 Block(4)\H = 50 Block(5)\P = 1 Block(5)\X = 600 Block(5)\Y = 400 Block(5)\W = 100 Block(5)\H = 20 Block(6)\P = 1 Block(6)\X = 30 Block(6)\Y = 500 Block(6)\W = 60 Block(6)\H = 56 Repeat ; Hintergrund Cls ; Rand Color 255,255,255 Rect SecX,SecY,SecW,SecH,0 ; Blöcke zeichnen For lv = 1 To MaxBlocks Step 1 If Block(lv)\P > 0 Then Color 0,155,0 Rect Block(lv)\X,Block(lv)\Y,Block(lv)\W,Block(lv)\H EndIf Next ; Ball ; Bewegung des Balls For BallNr = 1 To MaxBalls Step 1 If Ball(BallNr)\Active Then Color 255,0,0 Oval Ball(BallNr)\X,Ball(BallNr)\Y,Ball(BallNr)\W,Ball(BallNr)\H MoveBall(Ball(BallNr)) EndIf Next If KeyDown(34) Ball(1)\Angle = Ball(1)\Angle + 1 EndIf ; Bild anzeigen WaitTimer Timer ;XUpdateScreen3d ;XUpdateScreen2d Flip Until KeyHit(1) End ; --- Funktionen -------------------------------------------------------- Function MoveBall(B.T_Ball) Local St# Local LeftPx#,RightPx#,TopPx#,BottomPx#,AxisY#,AxisX# For St = 0 To B\Speed Step 0.1 ; Bewegt den Ball in 0.1 Pixel Schritten B\X = B\X + 0.1 * Cos(B\Angle) B\Y = B\Y + 0.1 * Sin(B\Angle) ; Kollision mit den Wänden If (B\Y < SecY) Then ; Kollision mit der oberen Wand B\Angle = NewAngleTop(B\Angle) ElseIf ((B\Y + B\H) > (SecY + SecH)) Then ; Kollision mit der unteren Wand : Verloren ! B\Angle = NewAngleBottom(B\Angle) ElseIf (B\X < SecX) Then ; Kollision mit der linken Wand B\Angle = NewAngleLeft(B\Angle) ElseIf ((B\X + B\W) > (SecX + SecW)) Then ; Kollision mit der rechten Wand B\Angle = NewAngleRight(B\Angle) EndIf ; Kollision mit einem Block For lv=1 To MaxBlocks Step 1 If (Block(lv)\P > 0) Then If ((B\X + B\W) >= Block(lv)\x) And (B\X <= (Block(lv)\X + Block(lv)\W)) Then If ((B\Y + B\H) >= Block(lv)\Y) And (B\Y <= (Block(lv)\Y + Block(lv)\H)) Then ; Kollision mit dem Block ; Es muß bestimmt werden an welcher Seite der Ball ist ; Dementsprechend kann dann ein neuer Winkel bestimmt werden LeftPx = Abs((Block(lv)\X - (B\X + B\W))) RightPx = Abs((Block(lv)\X + Block(lv)\W) - (B\X + B\W)) TopPx = Abs((Block(lv)\Y - (B\Y + B\H))) BottomPx = Abs((Block(lv)\Y + Block(lv)\H) - (B\Y + B\H)) ; Vertikal oder Horizontal If (TopPx >= BottomPx) Then AxisY = TopPx Else AxisY = BottomPx EndIf If (LeftPx >= RightPx) Then AxisX = LeftPx Else AxisX = RightPx EndIf ; Wird es vertauscht funktioniert es von der jeweiligen ; anderen Seite nicht If (AxisX >= AxisY) Then ; Horizontale Kollision If (LeftPx > RightPx) Then ; Schlägt von rechts auf B\Angle = NewAngleLeft(B\Angle) Else ; Schlägt von links auf B\Angle = NewAngleRight(B\Angle) EndIf Else ; Vertikale Kollision. If (BottomPx >= TopPx) Then ; Schlägt auf der oberen Seite auf B\Angle = NewAngleBottom(B\Angle) Else ; Schlägt auf der unteren Seite auf B\Angle = NewAngleTop(B\Angle) EndIf EndIf EndIf EndIf EndIf Next Next End Function Function NewAngleTop#(OldAngle#) ; Berührt Hindernis von unten If (OldAngle >= 180) Then ; Kommt von schräg rechts Return (270 - (OldAngle - 90)) Else ; Kommt von schräg links Return (270 + (90 - OldAngle)) EndIf End Function Function NewAngleBottom#(OldAngle#) ; Berührt Hindernis von oben If (OldAngle >= 180) Then ; Kommt von schräg links Return (90 - (OldAngle - 270)) Else ; Kommt von schräg rechts Return (90 + (270 - OldAngle)) EndIf End Function Function NewAngleLeft#(OldAngle#) ; Berührt Hindernis von rechts If (OldAngle >= 90) Then ; Kommt von schräg unten Return (360 - (OldAngle - 180)) Else ; Kommt von schräg oben Return (180 - OldAngle) EndIf End Function Function NewAngleRight#(OldAngle#) ; Berührt Hindernis von links If (OldAngle > 270) Then ; Kommt von schräg unten Return (180 + 360 - OldAngle) Else ; Kommt von schräg oben Return (180 - OldAngle) EndIf End Function |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group