saubere Kollisionsabfrage gefunden

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

dayle_85

Betreff: saubere Kollisionsabfrage gefunden

BeitragSo, Jul 22, 2007 23:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi Leute,

Ich weiß, es gibt schon tausend Tutorials, die erklären, wie man ein Jump and Run macht und auch eine Menge Threads, die sich um Kollision kümmern. Da ich ein blutjunger Noob bin, kann ich den meisten von euch wahrscheinlich auch nichts vor machen, denn ich hab im Prinzip vor 2 Tagen erst mit Blitzbasic angefangen (und richtig ernsthaft programmiert hab ich vorher auch noch nicht - immer nur probiert und irgendwann aufgegeben), aber ich hab gestern mal mein erstes Prog geschrieben und dabei ne Möglichkeit gefunden, mit relativ geringem Aufwand, ne sehr saubere Kollisionsabfrage zu machen. aber seht selbst:
Code: [AUSKLAPPEN]

;Autor: Gerd Relitz
;geschrieben am 22.7.07
;fertiggestellt am 23.07.07

;----------------HEAD--------------------
Graphics 384,407,32,2
SetBuffer BackBuffer()
frametimer= CreateTimer(30)

;              Variablen

;Ballvariablen
Global Ball = LoadImage("ball.bmp") ;32*32 großes Bild von nem Ball mit Lilaner Transparenz
   MaskImage ball,255,0,255
Global ball_x = 32
Global ball_y = 32
Global x_speed=0
Global y_speed=0
;Maxspeed nicht kleiner als 1 machen!!
Global maxspeed=15
;die Geschwindigkeit ist beliebig veränderbar *stolz*
Global ball_speed =1

;Umgebungsvariablen
Const WEG=0,MAUER=4

Global Wand = LoadImage("Mauer.bmp") ;32x32 großes Bild von ner Mauer
Dim Map(12,12)
Restore mapdata
For y=0 To 11
   For x=0 To 11
      Read map(x,y)
   Next
Next


;Tastaturkonstanten
Const RAUF = 200, RUNTER = 208, RECHTS = 205, LINKS = 203, SPACE = 57



;------------HAUPTSCHLEIFE---------------

Repeat
WaitTimer (frametimer)
   ClsColor 80,40,40
   Cls

   Drawmap()
   DrawBall()

   Text 1,385,ball_x Mod 32 ;um herauszufinden, an welcher Stelle mein gegenstand noch nicht richtig collidiert
   Text 1,395,ball_y Mod 32 ;hab ich mir des hier anzeigen lassen
   Text 50,385, x_speed
   Text 50,395, y_speed

   Flip
Until KeyHit(1)
End

;-----------------MAP--------------------

Function Drawmap()
For x = 0 To 11
   For y = 0 To 11
      If Map(x,y) = MAUER Then
         DrawImage Wand,x*32,y*32
      EndIf
   Next
Next
End Function
;0=Boden - begehbar
;4=Stein - unbegehbar


.mapdata
Data 4,4,4,4,4,4,4,4,4,4,4,4
Data 4,0,0,0,0,0,0,0,0,0,0,4
Data 4,0,0,0,0,0,0,0,0,0,0,4
Data 4,0,0,0,0,0,0,0,0,0,0,4
Data 4,0,0,0,0,0,0,0,4,4,4,4
Data 4,0,0,0,0,0,0,0,0,0,0,4
Data 4,0,0,0,0,0,0,0,0,0,0,4
Data 4,0,0,0,4,4,4,0,0,0,0,4
Data 4,0,0,0,0,0,0,0,0,0,0,4
Data 4,0,0,0,0,0,0,0,4,4,4,4
Data 4,0,0,0,0,0,0,0,0,0,0,4
Data 4,4,4,4,4,4,4,4,4,4,4,4


;-----------------BALL-------------------
Function DrawBall()


If KeyDown(RAUF) Then
   If y_speed > 0 Then y_speed=0
   y_speed = y_speed - ball_speed
   If y_speed*-1 > maxspeed Then y_speed = maxspeed*-1
ElseIf y_speed<maxspeed Then
   y_speed = y_speed + 1
EndIf

If KeyDown(RUNTER) Then
   y_speed =y_speed + ball_speed
   If y_speed > maxspeed Then y_speed = maxspeed
ElseIf y_speed>maxspeed Then
   y_speed = y_speed - 1
EndIf

If KeyDown(LINKS) Then
   x_speed = x_speed - ball_speed
   If x_speed*-1 > maxspeed Then x_speed = maxspeed*-1
ElseIf x_speed<0 Then
   x_speed = x_speed + 1
EndIf

If KeyDown(RECHTS) Then
   x_speed =x_speed + ball_speed
   If x_speed > maxspeed Then x_speed = maxspeed
ElseIf x_speed>0 Then
   x_speed = x_speed - 1
EndIf

;Kollisionsabfrage:
;drückt man bsw den Up-Button wird y_speed bis -maxspeed gesenkt (also wird der Ball nach oben beschleunigt), dann geprüft, ob y_speed pixel üb er der Ballposition auf der Map eine Mauer
;eingezeichnet is. Da das nicht reicht, weil der Ball ja eine Fläche von 32 Pixeln und somit auch in
;einen Stein rollen würde, wenn nur der erste Pixel außerhalb des Balls liegt, wird getestet,
;ob beim Teilen der X-Position durch 32 ein Rest bleibt

;-----------------------------------------------------------------------UP------------------------------------------------------------------------------------------------------------------

If y_speed<0 Then
      If map(ball_x/32,(ball_y+y_speed)/32)<2 Then
         If Not ball_x Mod 32 > 0 And map(ball_x/32+1,(ball_y+y_speed)/32)=MAUER ;bleibt ein Rest, wird abgefragt ob eine Wand weiter drüben auch eine Mauer is
            ball_y=ball_y+y_speed   ; wenn nicht, wird der Ball beschleunigt
;         ist man näher als y_speed an einer Wand, wird man direkt an die Wand gesetzt
         ElseIf ball_y Mod 32 >= 0 Then
            ball_y=ball_y - ball_y Mod 32
            y_speed=y_speed * -1            
         EndIf
      ElseIf ball_y Mod 32 >= 0 Then
         ball_y=ball_y - ball_y Mod 32
         y_speed=y_speed * -1
      EndIf
      
EndIf
   
   ;bei den anderen Tasten läuft es genauso ab
;----------------------------------------------------------------------DOWN-----------------------------------------------------------------------------------------------------------------
If y_speed>0 Then
      If map(ball_x/32,(ball_y+31+y_speed)/32)<2 Then
         If Not ball_x Mod 32 > 0 And map(ball_x/32+1,(ball_y+31+y_speed)/32)=MAUER ; hier musste ich noch 31 pixel auf die Position des Balls draufrechnen, da ich nur
            ball_y=ball_y+y_speed               ; mit den Ecken des Balls rechne... sind beide Ecken eingeplant, is die Kollision vollkommen sauber, jedoch nicht pixelgenau
         ElseIf ball_y Mod 32 > 0 Then
            ball_y=ball_y +32 - ball_y Mod 32
            If y_speed > 1 Then
               y_speed=y_speed*-1+1
            Else y_speed = 0
            EndIf
         
         ;da y_speed durchweg auf maxspeed gezogen wird, müssen hier extra Vorsichtsmaßnahmen getroffen werden, dass der Ball nicht aus Versehen in den Boden rutscht   
         ElseIf ball_y Mod 32 = 0 Then
         If y_speed > 1 Then
            y_speed=y_speed*-1+1 ;+1 sorgt dafür, dass der Ball nicht wieder mit der gleichen Geschwindigkeint nach oben springt, sondern nach und nach langsamer wird               
         Else y_speed = 0
         EndIf
         EndIf
      ElseIf ball_y Mod 32 > 0 Then
         ball_y=ball_y+32- ball_y Mod 32
         If y_speed > 1 Then
         y_speed=y_speed*-1+1
         Else y_speed = 0
         EndIf
         ElseIf ball_y Mod 32 = 0 Then
         If y_speed > 1 Then
         y_speed=y_speed*-1+1
         Else y_speed = 0
         EndIf
      EndIf

EndIf

;----------------------------------------------------------------------LEFT-----------------------------------------------------------------------------------------------------------------
If x_speed < 0 Then
      If map((ball_x+x_speed)/32, ball_y/32)<2 Then
         If Not ball_y Mod 32 > 0 And map((ball_x+x_speed)/32,ball_y/32+1)=MAUER
            ball_x=ball_x+x_speed
         ElseIf ball_x Mod 32 >= 0 Then
            ball_x=ball_x- ball_x Mod 32
            x_speed=x_speed * -1
         EndIf
      ElseIf ball_x Mod 32 >= 0 Then
         ball_x=ball_x- ball_x Mod 32
         x_speed=x_speed * -1
      EndIf
EndIf

;----------------------------------------------------------------------RIGHT----------------------------------------------------------------------------------------------------------------
If x_speed>0 Then
      If map((ball_x+31+x_speed)/32, ball_y/32)<2 Then
         If Not ball_y Mod 32 > 0 And map((ball_x+31+x_speed)/32,ball_y/32+1)=MAUER
            ball_x=ball_x+x_speed
         ElseIf ball_x Mod 32 > 0 Then
            ball_x=ball_x+32- ball_x Mod 32
            x_speed=x_speed * -1
         EndIf
         ElseIf ball_x Mod 32 > 0 Then
            ball_x=ball_x+32- ball_x Mod 32
            x_speed=x_speed * -1
      EndIf
EndIf
   
DrawImage Ball,ball_x,ball_y
End Function


Es existiert noch kein Jumptimer, is also eher ne Schwerkraft Simulation, dürfte aber kein Problem sein.
Hab auch noch ne Version davon, die eher an Bomberman erinnert. Kann ich, sollte Interesse bestehen, auch gern mit reinstellen. Bin auch für Verbesserungs- und Vereinfachungsvorschläge offen.
Goto ist böse!!!

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Jul 23, 2007 1:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Für den Anfang echt nicht schlecht. Hier mal ein paar Tipps.


- Im Fenstermodus sollte man die Farbtiefe nicht festlegen. Lasse das Blitz für dich erledigen Graphics 400,300,0,2

- ClsColor 80,40,40 muss nicht in eine Schleife. Es reicht wenn diese einmal irgendwo oben ausgeführt wird.

- Folgende zwei Zeilen machen genau das gleiche
If y_speed*-1 > maxspeed Then y_speed = maxspeed*-1
If y_speed < -maxspeed Then y_speed = -maxspeed

- Du kannst auch alle Bewegungen als Float machen und bei Beschleunigung entsprechend die Geschwindigkeit in jeweiliger Richtung erhöhen. Wenn du dann ein ''Luftwiederstand'' mit einbaust, dann verhält sich deine Figur auch mit einer Maximalgeschwindigkeit, allersings mit einem realistischem Geschwindigkeitsan/abstieg.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

Krümel

BeitragMi, Jul 25, 2007 8:17
Antworten mit Zitat
Benutzer-Profile anzeigen
hi, dayle_85!

Eventuell interessiert dich folgender Code.
Eine sehr einfache aber genaue Möglichkeit Kreise und Rechtecke auf Kollision zu prüfen.

Code: [AUSKLAPPEN]

Graphics 800,600,16,2
SetBuffer BackBuffer()

Function RectCircleCollide(x1,y1,x2,y2, cx,cy,rad)
    If cx < x1 tx=cx-x1 Else If cx > x2 tx = cx-x2
    If cy < y1 ty=cy-y1 Else If cy > y2 ty = cy-y2
    Return (tx*tx+ty*ty) < rad*rad
End Function

kreisR=60

rechteckX1=130
rechteckY1=130
rechteckX2=430
rechteckY2=300
While Not KeyHit(1)
   kreisX=MouseX()
   kreisY=MouseY()
   
   Rect rechteckX1,rechteckY1,rechteckX2-rechteckX1,rechteckY2-rechteckY1
   Oval kreisX-kreisR,kreisY-kreisR,kreisR*2,kreisR*2

   If RectCircleCollide(rechteckX1,rechteckY1,rechteckX2,rechteckY2,kreisX,kreisY,kreisR)
      Text 0,0,"Kollision"
   Else
      Text 0,0,"keine Kollision"   
   EndIf

   Flip 0
   Cls
Wend

dayle_85

BeitragDo, Jul 26, 2007 3:30
Antworten mit Zitat
Benutzer-Profile anzeigen
cool, danke für die Tipps.
Hab in den letzten Tagen festgestellt, dass Blitzbasic wirklich ein sehr mächtiges und auch sehr leicht zu bedienendes Werkzeug ist. Ich glaube, damit werde ich noch viel Zeit verbringen.
Goto ist böse!!!

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group