saubere Kollisionsabfrage gefunden
Übersicht

![]() |
dayle_85Betreff: saubere Kollisionsabfrage gefunden |
![]() Antworten mit Zitat ![]() |
---|---|---|
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!!! |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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!!! |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group