Pixel*Tile Kollision

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Progger93

Betreff: Pixel*Tile Kollision

BeitragSa, Dez 20, 2008 21:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi Leute,
Ich muss jetzt leider nocheinmal fragen, weil ich bis jetzt nie eine richtige Antwort auf diese Frage bekommen habe: Wie mache ich eine Pixel*Tile Kollision, wie es sie z.b.B in CS2d gibt?
Ich hatte schon etliche anlaufversuche, aber alle sind irgendwie gescheitert...
Hat da keiner ein gutes Beispiel mit Pixel*Tile+ Scrolling?

Hier mein aktueller Versuch:
Code: [AUSKLAPPEN]
SuperStrict

Const width:Int = 1024
Const height:Int = 768


Graphics width , height
SetBlend(ALPHABLEND)

Global mapwidth:Int=1
Global mapheight:Int=1
Global map:Int[mapheight , mapwidth]

loadmap()

Type spieler
   Field x:Float
   Field y:Float
   Field ammo:Int
   Field weapon:Int
   Field bot:Byte
   Field camera:Byte
   Field speed:Float
   
   Field col_oben:Int
   Field col_unten:Int
   Field col_links:Int
   Field col_rechts:Int
End Type
Global spielerlist:TList = CreateList()

Local sp:spieler = New spieler
sp.x = 5
sp.y = 5
sp.ammo = 200
sp.weapon = 1
sp.camera = 1
sp.speed=2
ListAddLast(spielerlist,sp)


Global I:Int , J:Int

Global scroll_x:Int=500,scroll_y:Int=372


Local frame_timer:TTimer=CreateTimer(60)
Repeat
   WaitTimer(frame_timer)
   Cls
   
   
   drawmap()
   
   spielerupdate()

   
   Flip 0
Until KeyHit(KEY_ESCAPE)
End

Function loadmap()
   Local datei:TStream = ReadFile("map1.txt")
   mapwidth = ReadShort(datei:TStream)
   mapheight = ReadShort(datei:TStream)
   map=New Int[mapwidth+1,mapheight+1]
   For I = 0 To mapwidth
      For J = 0 To mapheight
         map[I , J] = ReadByte(datei:TStream) 
      Next
   Next
   CloseFile(datei:TStream)
End Function
   
Function drawmap()
   For I = 0 To mapwidth
      For J = 0 To mapheight
         Select map[I , J]
            Case 0
               SetColor 255,255,255
            Case 1
               SetColor 0,0,0
         End Select
         DrawRect I * 32-scroll_x , J * 32-scroll_y , 32 , 32
      Next
   Next
End Function

Function spielerupdate()
   For Local sp:spieler = EachIn spielerlist
      If sp.bot = 0 Then
               DrawText  "Oben: "+sp.col_oben+" Unten: "+sp.col_unten+" Links: "+sp.col_links+" Rechts: "+sp.col_rechts,0,20
         If KeyDown(KEY_W) And sp.col_oben=0 Then
            sp.y=sp.y-sp.speed
         EndIf
         If KeyDown(KEY_S) And sp.col_unten=0 Then
            sp.y=sp.y+sp.speed
         EndIf
         If KeyDown(KEY_A) And sp.col_links=0 Then
            sp.x=sp.x-sp.speed
         EndIf
         If KeyDown(KEY_D) Then
            If sp.col_rechts=0
               sp.x = sp.x + sp.speed
            EndIf
         EndIf
         'Kollision
         For I = 0 To mapwidth
            For J = 0 To mapheight
               If map[I,J]=1 Then
                  If rectsoverlap(sp.x-scroll_x , sp.y-scroll_y , 24 , 24 , I * 32 -scroll_x , J * 32-scroll_y , 32 , 1) Then
                     sp.col_oben = 1
                  Else
                     sp.col_oben = 0
                  EndIf
                  If rectsoverlap(sp.x -scroll_x , sp.y-scroll_y , 24 , 24 , I * 32-scroll_x  , J * 32-scroll_y , 1 , 32) Then
                     sp.col_rechts = 1
                  Else
                     sp.col_rechts =0
                  EndIf
                  If rectsoverlap(sp.x -scroll_x , sp.y-scroll_y , 24 , 24 , I * 32 -scroll_x , J * 32 + 32 -scroll_y, 32 , 1) Then
                     sp.col_unten = 1
                  Else
                     sp.col_unten = 0
                  EndIf
                  If rectsoverlap(sp.x - scroll_x , sp.y - scroll_y , 24 , 24 , I * 32 + 32 - scroll_x , J * 32 - scroll_y , 1 , 32) Then
                     sp.col_links = 1
                  Else
                     sp.col_links = 0
                  EndIf
                  
                  SetColor 255,0,0
                  DrawRect I * 32-scroll_x  , J * 32 -scroll_y, 32 , 1
                  SetColor 255,255,0
                  DrawRect I * 32-scroll_x  , J * 32-scroll_y , 1 , 32
                  SetColor 0 , 255 , 0
                  DrawRect I * 32 -scroll_x , J * 32 + 32-scroll_y , 32 , 1
                  SetColor 0 , 0 , 255
                  DrawRect I * 32 + 32 - scroll_x , J * 32 - scroll_y , 1 , 32

               EndIf
            Next
         Next
         
         
      EndIf
      If sp.camera = 1 Then
         scroll_x = sp.x-500
         scroll_y = sp.y-372
      EndIf

      SetColor 0,0,255
      DrawRect sp.x - scroll_x , sp.y - scroll_y , 24 , 24
      SetColor 255,0,0
      DrawText "X: " + Int(sp.x) + "  Y: " + Int(sp.y) , 0 , 0
      SetColor 255 , 0 , 255
      Rect sp.x-scroll_x  , sp.y-scroll_y , 24 , 24
   Next
End Function



Function rectsoverlap:Int(x1:Int , y1:Int , width1:Int , height1:Int , x2:Int , y2:Int , width2:Int , height2:Int)
   If x1 + width1 > x2 And y1 + height1 > y2 And x1 < x2 + width2 And y1 < y2 + height2 Then
      Return 1
   Else
      Return 0
   EndIf
End Function

Function rect(x:Int, y:Int, width:Int, height:Int)
   DrawRect x, y, 1, height
   DrawRect x, y, width, 1
   DrawRect x, y + height, width + 1, 1
   DrawRect x + width, y, 1, height + 1
End Function


Ich würde mich echt total über eure Hilfe freuen, da ich an diesem Problem echt schon ewig sitze.
Gebt euch nen Ruck, es ist Weihnachtszeit Wink

mfg
Progger93
MfG Pascal
Win 7|T7250@2.0Ghz|3GB RAM|M8600GT

Goodjee

BeitragSa, Dez 20, 2008 21:35
Antworten mit Zitat
Benutzer-Profile anzeigen
nunja, eg kann man das quasi in 2 schritten machen:
1. verschiedene eckpunkte des sprites prüfen, ob es in irgendeinem massiven tile steckt
2. wenn ja, wieder auf die position von vor einem schleifenlauf setzen


wenn man es etwas komplizierter machen will:
ein massives tile hat 4 umrisslinien
wenn eine umrisslinie von einer linie von spriteposition bis spriteposition vom letzen frame geschnitten wird, dann den schnittpunkt rechnen und mit hilfe des schnittpunktes das sprite an die richtige stelle setzen, sodass es immer genau am hindernis anliegt
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

Progger93

BeitragSa, Dez 20, 2008 21:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habs jetzt so gemacht:

Code: [AUSKLAPPEN]

sp.altx = sp.x
sp.alty = sp.y

'BEWEGEN

If rectsoverlap(sp.x - scroll_x , sp.y - scroll_y , 24 , 24 , I * 32 - scroll_x , J * 32 - scroll_y , 32 , 32) Then
     sp.x = sp.altx
     sp.y = sp.alty
EndIf      


Allerdings bleibt der Spieler immer an der Wand hängen.
Wie könnte man dies unterbinden?

MFG Progger93
MfG Pascal
Win 7|T7250@2.0Ghz|3GB RAM|M8600GT

Goodjee

BeitragSa, Dez 20, 2008 22:59
Antworten mit Zitat
Benutzer-Profile anzeigen
bewegst du immer noch so wie vorher?

edit:
eine weitere möglichkeit ist xbewegung und ybewegung zu trennen:
1. map an x+speed,y prüfen
2. wenn keine kollision bewegen
3. map an x,y+speed prüfen
4. wenn keine kollision bewegen

natürlich sollte man das entweder für alle ecken des players oder nur für die relevanten machen
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

Progger93

BeitragSo, Dez 21, 2008 15:33
Antworten mit Zitat
Benutzer-Profile anzeigen
JUHU endlich Fortschritte Very Happy

Ich habs jetzt so gemacht:
Code: [AUSKLAPPEN]
If KeyDown(KEY_W) Then
   If map[Int(sp.x / 32) , Int( (sp.y - sp.speed) / 32)] = 0 Then
      sp.y = sp.y - sp.speed
   EndIf
EndIf
If KeyDown(KEY_S) Then
   If map[Int(sp.x / 32) , Int( (sp.y + sp.speed+23) / 32)] = 0 Then
      sp.y = sp.y + sp.speed
   EndIf
EndIf
If KeyDown(KEY_A) Then
   If map[Int((sp.x - sp.speed) / 32) , Int(sp.y/32)] = 0 Then
      sp.x = sp.x - sp.speed
   EndIf
EndIf
If KeyDown(KEY_D) Then
   If map[Int((sp.x + sp.speed+23) / 32) , Int(sp.y/32)] = 0 Then
      sp.x = sp.x + sp.speed
   EndIf
EndIf


Allerdings fahr ich bei ein paar Ecken noch rein:


user posted image


Ich weiß allerdings nicht Warum des jetzt so ist Sad

Hoffe ihr könnt mir helfen

Progger93
MfG Pascal
Win 7|T7250@2.0Ghz|3GB RAM|M8600GT
  • Zuletzt bearbeitet von Progger93 am So, Dez 21, 2008 16:05, insgesamt 3-mal bearbeitet

Goodjee

BeitragSo, Dez 21, 2008 15:45
Antworten mit Zitat
Benutzer-Profile anzeigen
ich verstehe nicht wofür du die +24 und die +23 brauchst?
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

Progger93

BeitragSo, Dez 21, 2008 15:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab ich dazugemacht weil die rechts, bzw. unten Kollision um genau die Anzahl Pixel verschoben waren. Sollte eigentlich beides 23 sein Smile.
MfG Pascal
Win 7|T7250@2.0Ghz|3GB RAM|M8600GT

Goodjee

BeitragSo, Dez 21, 2008 23:03
Antworten mit Zitat
Benutzer-Profile anzeigen
hier das im chat versprochene beispiel
Code: [AUSKLAPPEN]
Method move:Int(sx:Int,sy:Int)
         x=x+sx
         If(sx<>0)
            If(map.getCollision((x-16)/64,(y-16)/64)) x=Int((x-16)/64)*64+80
            If(map.getCollision((x-16)/64,(y+16)/64)) x=Int((x-16)/64)*64+80
            If(map.getCollision((x+16)/64,(y-16)/64)) x=Int((x+16)/64)*64-17
            If(map.getCollision((x+16)/64,(y+16)/64)) x=Int((x+16)/64)*64-17
         EndIf
         y=y+sy
         If(sy<>0)
            If(map.getCollision((x-16)/64,(y-16)/64)) y=Int((y-16)/64)*64+80
            If(map.getCollision((x+16)/64,(y-16)/64)) y=Int((y-16)/64)*64+80
            If(map.getCollision((x-16)/64,(y+16)/64)) y=Int((y+16)/64)*64-17
            If(map.getCollision((x+16)/64,(y+16)/64)) y=Int((y+16)/64)*64-17
         EndIf
    End Method
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group