ball an tilemap abprallen[Edited: NEUE FRAGE!]

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

mas93

Betreff: ball an tilemap abprallen[Edited: NEUE FRAGE!]

BeitragSo, Nov 11, 2007 18:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi, ich habe noch ein frage

Und zwar: Ich habe ein Programm geschrieben, bei dem ein Ball an einer tilemap abprallen soll.
Das funktioniert manchmal auch, aberr machmal wackelt er sich einfach nur durch die wände durch und macht dann weiter.

Könnt ihr mir sagen warum??

Code: [AUSKLAPPEN]

Graphics 525,525,32,2
SetBuffer BackBuffer()

;Das Map feld erstellen
Dim map(20,20)

Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,2,2,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1
Data 1,0,0,0,0,2,2,0,0,0,0,0,0,0,2,2,2,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,1
Data 1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

For ay = 0 To 20
   For ax = 0 To 20
      Read map(ax,ay)
   Next
Next



Global ink=LoadImage("ink.png")
MaskImage ink,255,0,255

Global tileset=LoadAnimImage("tileset.png",25,25,0,3)

Global ball=LoadImage("ink.png")
MaskImage ball,255,0,255


Type line
   Field x,y
   Field nummer
End Type

Global number


Global winkel#=15
Global x#=100,y#=250

timer=CreateTimer(60)

Repeat
   WaitTimer(timer)
   Cls
   
   Drawmap()
   updateball()
   
   
   
   
   
   
   ;------------FPS-------------
   FPScount = FPScount + 1
   If MilliSecs() > lastcheck+1000
      fps = fpscount
      fpscount = 0
      lastcheck = MilliSecs()
   End If
   If vorlast<fpscount Then vorlast=fpscount
   Text 20, 20,"FPS: "+ vorlast
   Text 20,40, winkel
   
   Flip 0
Until KeyHit(1)


Function Drawmap()
   
   For ay = 0 To 20
      For ax = 0 To 20
         DrawImage tileset,ax*25,ay*25,map(ax,ay)
      Next
   Next
   
End Function


Function updateball()
   
   x#=x#+Sin(winkel)*3
   y#=y#-Cos(winkel)*3
   
   For ax=0 To 20
      For ay=0 To 20
            If map(ax,ay)=1 Then If ImageRectCollide(ball,x,y,0,ax*25,ay*25,25,25)Then
            winkel=(540-winkel) Mod 360
         EndIf
         
         If map(ax,ay)=2 Then If ImageRectCollide(ball,x,y,0,ax*25,ay*25,25,25)Then
            winkel=(540-winkel) Mod 360
         EndIf
      Next
   Next
   
   
   DrawImage ball,x,y
End Function


wäre nett wenn ihr mein fehler erkennen könntet.


mfg
mas93
www.lpbase.de
Meine Linkin Park Fanseite[Noch im Aufbau]
  • Zuletzt bearbeitet von mas93 am Mo, Nov 12, 2007 16:13, insgesamt einmal bearbeitet

The_Nici

BeitragSo, Nov 11, 2007 19:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Vermutung: Der Ball fliegt durch das Tile.

mas93

BeitragSo, Nov 11, 2007 19:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Nein wer hätts gedacht...

ICh will ja wissen wo mein fehler ist.


mfg
mas93
www.lpbase.de
Meine Linkin Park Fanseite[Noch im Aufbau]

DerHase

BeitragSo, Nov 11, 2007 19:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube es liegt daran, dass Du den Ball zurücksetzen musst. Wenn eine Kollision stattgefunden hat und sich der Ball dreht, kollidiert er ja im nächsten Schleifendurchlauf wieder und liefert so kein vernünftiges Ergebnis.
Play Satyr!

The_Nici

BeitragSo, Nov 11, 2007 20:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit durch das Tile fliegen meinte ich, dass er hinter dem Tile platziert wird.

mas93

BeitragSo, Nov 11, 2007 21:13
Antworten mit Zitat
Benutzer-Profile anzeigen
@ The nici: Wie meinst du das? Warum sollte er dahinter platziert werden?


Hmm, gibt es kein tutorial wo sowas behandelt wird, oder hat sowas schonmal einer gemacht??


mfg
mas93
www.lpbase.de
Meine Linkin Park Fanseite[Noch im Aufbau]

Spikespine

BeitragSo, Nov 11, 2007 21:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde sagen, DerHase hat die richtige Antwort für dich. Dieses Wackeln ist ein typisches Zeichen davon, dass der Ball nicht sauber zurückgesetzt wird bei einer Kollision, was in deinem Code auch nicht stattfindet. In deinem Code dürfte sich das ganze ungefähr so verhalten:
Der Ball Kollidiert, also wird der Winkel verändert.
Im nächsten Durchlauf bewegt er sich ein Stück in die andere Richtung, allerdings kann es sein, dass er sich dann immer noch leicht innerhalb der Mauer befindet, somit findet wieder eine Kollision statt, was eigentlich nicht sein darf!

Lösung: Wenn der Ball kollidiert, nicht nur den Winkel verändern, sondern ihn auch noch auf eine Nicht-Kollisions-Position bringen (idealerweise genau an die Wand).
Athlon 64 3700+ | 1024 MB RAM | GeForce 7900 GT | Blitz2D, Blitz3D, BlitzPlus, BlitzMax

mas93

BeitragSo, Nov 11, 2007 21:26
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm , ok. Aber wenn ich es so mache:

Code: [AUSKLAPPEN]
Function updateball()
   
   x#=x#+Sin(winkel)*3
   y#=y#-Cos(winkel)*3
   
   
   
   For ax=0 To 20
      For ay=0 To 20
            If map(ax,ay)=1 Then If ImageRectCollide(ball,x,y,0,ax*25,ay*25,25,25)Then
            
            x=altx
            y=alty
            
            Text 100,100,"AAAAAAAAAAAAAAAAAAA"
            
            winkel=360-winkel;(540-winkel) Mod 180
            
         EndIf
         
         If map(ax,ay)=2 Then If ImageRectCollide(ball,x,y,0,ax*25,ay*25,25,25)Then
            
            x=altx
            y=alty
            
            Text 100,100,"AAAAAAAAAAAAAAAAAAA"
            
            winkel=360-winkel;(540-winkel) Mod 180
            
         EndIf
      Next
   Next
   
   If KeyHit(2) Then winkel=winkel*1
   If KeyHit(3) Then winkel=winkel*-1
   
   
   If altx<>x Then altx=x
   If alty<>y Then alty=y
   
   DrawImage ball,x,y
End Function



dann bleibt der ball vor einer Wand stehen.
Warum das?

[edit]Er bleibt nur vor der oberen und interen Wand stehen. links und rechts geht.
Ich glaube, dass es an der Abprallwinkelberechnung liegt, weil ich wahrscheinlich irgendwas anderes berechnen muss, wenn der ball oben oder unten anstosst, als wenn er links oder rechts anstoßt.[/edit]
www.lpbase.de
Meine Linkin Park Fanseite[Noch im Aufbau]

mas93

BeitragMo, Nov 12, 2007 22:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Erstmal: Tut mir Leid wegen dem Doppelpost, aber ihr seit meine Lezte Rettung...

Der Ball prallt manchmal ab und manchmal nicht. Ich habe jetzt verzweifelt festgestellt, dass ein Teil des Codes garnicht aufgerufen wird, weil die Bedingung aus irgend einem Grund nicht erfüllt wird...

Ich habe jetzt seit heute Mittag echt schon alles probiert. Es will einfach nicht.
Ich habe auch schon heute Mittag die Nerven einiger Leute im Chat strapaziert, doch ich hänge immer noch.

Ich hab jetzt mal das """Spiel""" hochgeladen.

Hier der Link: https://www.blitzforum.de/upload/file.php?id=2310

Ich wäre zu tiefst gerührt wenn sich einer erbarmen könnte, und sich den Code anschaun könnte, und hoffentlich die Lösung finden.

Wäre nett wenn ihr mir helfen könntet.


mfg
mas93
www.lpbase.de
Meine Linkin Park Fanseite[Noch im Aufbau]

D2006

Administrator

BeitragDi, Nov 13, 2007 20:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Erstmal zur Problemerklärung: Deine Abfrage, von wo der der Ball vermutlich kollidierte, ist viel zu ungenau und führ deshalb häufig zu falschen Reaktionen. Eine bessere Methode beschreibe ich unten.


Ich mag derzeit gerne Auflistungen, also...

a) schlechter Stil

Rand(0.0, 0.3) ist sogar falsch, nicht nur schlechter Stil. Benutze dafür ql:Rnd.
Code: [AUSKLAPPEN]
If bla Then If blubb Then
ist total unübersichtlich. Benutze stattdessen: Code: [AUSKLAPPEN]
If bla And blubb Then


b) du machst 2 Kollisionsprüfungen (is richtig, aber nich in dem fall (siehe c))

Wenn in dem Feld ne 1 ist, prüfst du auf Kollision. Wenn in dem Feld ne 2 ist, prüfst du auf exakt die gleiche art. In dem Fall wäre es also angebracht zu prüfen, ob kollidiert wird und das Feld > 0 ist. Dadurch wird nur einmal kollidiert. (ich weiß, wird in deinem Fall auch, aber das liegt am schlechten Stil (a))

c) Mach dir ne andere Kollision und schau dir dafür simplerweise das Arkanoidbeispiel an, was in den Samples zu finden ist.

Kurz umrandet: Bevor du den Ball bewegst, merkst du dir seine Position. Dann bewegst du ihn in X-Richtung. Dann prüfst du auf Kollision. Wenn er kollidiert, dann muss er links/rechts kollidiert seind, also einfach nur speed_x = - speed_x. Danach bewegst du den Ball in Y-Richtung und prüfst wieder auf Kollision. Wenn er hier kollidiert, dann musse er einen Stein von oben/unten rangekommen sein, deshalb einfach speed_y = - speed_y.
Wichtig: Sobald eine Kollision gefunden wurde, änderst du die entsprechende Geschwindigkeitsvariable und setzt den Ball auf die gespeicherte Position zurück. Das löst dann auch das von DerHase beschriebene Problem.
Intel Core i5 2500 | 16 GB DDR3 RAM dualchannel | ATI Radeon HD6870 (1024 MB RAM) | Windows 7 Home Premium
Intel Core 2 Duo 2.4 GHz | 2 GB DDR3 RAM dualchannel | Nvidia GeForce 9400M (256 MB shared RAM) | Mac OS X Snow Leopard
Intel Pentium Dual-Core 2.4 GHz | 3 GB DDR2 RAM dualchannel | ATI Radeon HD3850 (1024 MB RAM) | Windows 7 Home Premium
Chaos Interactive :: GoBang :: BB-Poker :: ChaosBreaker :: Hexagon :: ChaosRacer 2

mas93

BeitragMi, Nov 14, 2007 18:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke Dee, Funktioniert mit deiner Anleitung perfekt!

Vielen dank.


BTW: Wie findert ihr die tiles? Sehen die gut aus?
Nur aus reinem interesse xD
www.lpbase.de
Meine Linkin Park Fanseite[Noch im Aufbau]

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group