BreakOut: Kollisionsabfrage und Abprall-Winkel

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Gizeh

Betreff: BreakOut: Kollisionsabfrage und Abprall-Winkel

BeitragDi, Nov 28, 2006 1:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Leute Smile

Ich habe eine generelle Frage zu Tile-Games:
Ein kleiner BreakOut-Verschnitt an dem ich gerade bastle lädt die zuvor mittels eines Editors erstellten Levels. Dabei werden die Angaben zu jedem einzelnen Brick in ein entsprechendes Type geladen (Enthält: Feld\Typ, Feld\col, Feld\row).

Die einzelnen Types werden in ein DIM-Array ( Spielfeld(col,row) ) geladen.

Code: [AUSKLAPPEN]

   ; GESETZTE TILES IN ARRAY LADEN
   While Not EOF(File%)
      typ         = ReadInt    (File%)
      col         = ReadInt    (File%)
      row         = ReadInt   (File%)
      
      Spielfeld(col,row)   = NEW TFeld
      Spielfeld(col,row)\typ   = typ
      Spielfeld(col,row)\col   = col
      Spielfeld(col,row)\row   = row
      
      Select Spielfeld(col,row)\typ
         Case 1
         Spielfeld(col,row)\image = Img_Brick1
         Case 2
         Spielfeld(col,row)\image = Img_Brick2
         Case 3
         Spielfeld(col,row)\image = Img_Brick3
      End Select
      
   Wend


Wie gestaltet man nun hier aber eine elegante Kollisions-Abfrage (Ball-->Bricks) ?
Immerhin existiert ja nun nicht für jedes Spielfeld(col,row) ein Image - sondern nur für bereits "gefüllte" Positionen - was die Meldung "Object does not exist" provozieren würde, wenn man bei einer Kollisionsabfrage durch alle vollständig loopen würde. Hab´ ich nu wieder n Hänger. Smile
Was tun?

Smile
  • Zuletzt bearbeitet von Gizeh am Di, Dez 05, 2006 12:25, insgesamt einmal bearbeitet

D2006

Administrator

BeitragDi, Nov 28, 2006 1:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
If Spielfeld(col,row) <> Null Then
; das hier wird nur gemacht, wenn ein Brick an der Stelle exisitiert
EndIf
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
 

Mr Hopp

BeitragDi, Nov 28, 2006 14:59
Antworten mit Zitat
Benutzer-Profile anzeigen
bewegt sich der Spieler tile-weiße, oder pixel-weiße??? Pixelweiße geht nämlich noch etwas anders
Zitat:
Wie poste ich falsch?

Nachdem ich Google, die FAQ's und die Boardsuche erfolgreich ignoriert habe, erstelle ich zwei bis fünf neue Themen, in den falschen Unterforen, mit kreativen Titeln und undeutlichem Text, unter dem sich jeder etwas anderes vorstellen kann.

Gizeh

BeitragMo, Dez 04, 2006 13:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry, ich komme erst jetzt wieder dazu an diesem Spiel zu schreiben und in das Forum zu sehen, deshalb die lange Pause - Danke ersteinmal für den Tipp! Smile

Jetzt stellt sich aber mir gegenwärtig noch das Problem bei der Kollisionsabfrage - dass einfach nichts kollidiert Smile

Ich gehe wie gesagt so vor:

Wie oben beschrieben werden die Leveldaten aus einem externen File in Types gesteckt, die wiederum in ein DIM gesteckt werden.

Die einzelnen Bricks werden gezeichnet:

Code: [AUSKLAPPEN]

; ------------------------------------------------
; DRAW TILES
; ------------------------------------------------
Function DrawTiles()

   Local Feld.TFeld
   Local x%,y%
   
   For Feld.TFeld = EACH TFeld
      x = (Feld\col * TILEWIDTH) - OFFSETX
      y = Feld\row * TILEHEIGHT
      DrawImage Feld\image,x,y
   Next

End Function


Die Kollisionsabfrage in der Hauptschleife:

Code: [AUSKLAPPEN]

   ; COLLSISION BALL --> BRICKS
   If Spielfeld(gCol,gRow) <> NULL Then
      If ImagesOverlap(Spielfeld(gCol,gRow)\image,x,y, Img_Ball, Ballx, Bally) Then
         If ImagesCollide(Spielfeld(gCol,gRow)\image,x,y,0, Img_Ball, Ballx, Bally,0) Then
            PlaySound Snd_Hit1
         EndIf

      EndIf
   EndIf


Kann mir vielleicht jemand sagen, warum das nicht funktioniert? Wenn ich das Programm starte fliegt der Ball einfach munter durch alle Bricks durch und beachtet sie einfach nicht weiter Rolling Eyes

Question



Zitat:
bewegt sich der Spieler tile-weiße, oder pixel-weiße??? Pixelweiße geht nämlich noch etwas anders


Der Spieler selbst bewegt sich Pixelweise Smile

DerHase

BeitragMo, Dez 04, 2006 14:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab den Code nur kurz überflogen, aber ich denke, der Ball fliegt deshalb einfach weiter, weil Du ihm nicht sagst was er Denn machen soll ausser nen Sound abspielen. Stopp ihn doch oder änder seine Richtung :]
Play Satyr!

Gizeh

BeitragMo, Dez 04, 2006 16:33
Antworten mit Zitat
Benutzer-Profile anzeigen
DerHase hat Folgendes geschrieben:
Ich hab den Code nur kurz überflogen, aber ich denke, der Ball fliegt deshalb einfach weiter, weil Du ihm nicht sagst was er Denn machen soll ausser nen Sound abspielen. Stopp ihn doch oder änder seine Richtung :]


Argh, sorry Very Happy Ich hab mich falsch ausgedrückt - der Sound dient nur als Test, und diesen spielt er natürlich nicht ab. Surprised

Gizeh

BeitragMo, Dez 04, 2006 17:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Mir fiel eben auf, dass ich ja überhaupt vergessen hatte, in der Mainloop einen Schleifendurchlauf für die Kollisionsabfrage der Bricks zu starten Rolling Eyes

Nun sieht es so aus:

Code: [AUSKLAPPEN]

   ; COLLSISION BALL --> BRICKS
   For i = 1 To 29
   For j = 1 To 17
   If Spielfeld(j,i) <> NULL Then
      If ImagesOverlap(Spielfeld(j,i)\image,x,y, Img_Ball, Ballx, Bally) Then
         If ImagesCollide(Spielfeld(j,i)\image,x,y,0, Img_Ball, Ballx, Bally,0) Then
            PlaySound Snd_Hit1
         EndIf
      EndIf
   EndIf
   Next
   Next


Aber das Resultat stimmt noch immer nicht - jetzt geschieht bei Programmstart folgendes: Wenn der Ball den ersten Brick berührt ertönt das Geräusch zigfach übereinander gelagert - und bei allen anderen Bricks tut sich nicht mehr.

Gizeh

BeitragMo, Dez 04, 2006 17:22
Antworten mit Zitat
Benutzer-Profile anzeigen
So. Ich hab das jetzt erst einmal so gelöst - ich habe die Coll-Abfrage in die DrawTiles-Function implementiert:

Code: [AUSKLAPPEN]

; ------------------------------------------------
; DRAW TILES
; ------------------------------------------------
Function DrawTiles()

   Local Feld.TFeld
   Local x%,y%
   
   ; TILES ZEICHNEN
   For Feld.TFeld = EACH TFeld
      x = (Feld\col * TILEWIDTH) - OFFSETX
      y = Feld\row * TILEHEIGHT
      DrawImage Feld\image,x,y
      
      ; KOLLISIONS-ABFRAGE
      If ImagesOverlap(Feld\image,x,y, Img_Ball, Ballx, Bally) Then
         If ImagesCollide(Feld\image,x,y,0, Img_Ball, Ballx, Bally,0) Then
            xspeed = -xspeed
            yspeed = -yspeed
            Delete Feld : PlaySound Snd_Hit1
         EndIf
      EndIf
      
   Next

End Function


Es funktioniert, aber nun wäre meine Frage: Ist das nicht recht ineffizient, wenn das Programm quasi bei jedem Frame durch alle Types loopen muss? Gibt es da vielleicht andere, ökonomischere Wege?

DerHase

BeitragMo, Dez 04, 2006 21:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Kuck Dir mal das >>>HIER<<< an. Und ImagesCollide reicht eigentlich aus, da brauchste kein ImageOverlap davor.
Play Satyr!

Gizeh

BeitragDi, Dez 05, 2006 10:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Und ImagesCollide reicht eigentlich aus, da brauchste kein ImageOverlap davor.


Ich teste zuerst mit ImagesOverlap, da dieser Befehl ja schneller und ressourcenschonender sein soll - und nur im "Erfolgsfall" dann die genauere (und langsamere) Collide-Prüfung ausgeführt wird.

DerHase

BeitragDi, Dez 05, 2006 10:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Jo hast recht, ist ein Ticken schneller, noch schneller ist es, wenn Du bei der ersten Abfrage " RectsOverlap " verwendest :]
Play Satyr!

Gizeh

BeitragDi, Dez 05, 2006 12:25
Antworten mit Zitat
Benutzer-Profile anzeigen
DerHase hat Folgendes geschrieben:
Jo hast recht, ist ein Ticken schneller, noch schneller ist es, wenn Du bei der ersten Abfrage " RectsOverlap " verwendest :]


Ja, danke für den Tip!

Jetzt habe ich ein weiteres Problem: Das Abprall-Verhalten des Balles vom Schläger. Entgegen jedem Realismus soll der Ball ja in verschiedenen Winkeln vom Schläger abprallen, in einem umso spitzeren Winkel je weiter außen er auf den Schläger prallt.

Jetzt habe ich über die Such-Funktion des Boards nach passenden Lösungen gesucht, und wurde in einem Code von Suco-X fündig. Aber ich begreife die entsprechende Stelle nicht so richtig.

Könnte sie mir bitte vielleicht jemand erklären und etwas darzulegen versuchen?

Smile

Code: [AUSKLAPPEN]

If ImagesOverlap(ball_image,ball_x,ball_y,balken_image,balken_x,balken_y)
ball_ywinkel = 0-ball_ywinkel
ball_xwinkel = (-(balken_width/2)+(ball_x-balken_x))/10
EndIf

If ball_ywinkel>0
If ball_ywinkel<=3
ball_ywinkel = 3
EndIf
ElseIf ball_ywinkel>-3
ball_ywinkel = -3
EndIf

If ball_xwinkel>0
If ball_xwinkel<=1
ball_xwinkel = 1
EndIf
ElseIf ball_xwinkel>-1
ball_xwinkel = -1
EndIf

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group