TileMap Collision Problem
BlitzPlus Forums/BlitzPlus Programming/TileMap Collision Problem
| ||
I have developed a TileEngine using Blitz. Each Tile can have different values. For example if a tile has a value of 1 a collision is possible, if the value is 0, no collision occurs. Now i have a problem: I have a lot of enemy objects. They fly into one direction and if they collide with a tile they should fly in the other direction but mathematical correct (a little bit like a ball). I have done a little exmaple programm to show you my problem. Does anyone know how to solve this problem? Graphics 320,256 SetBuffer BackBuffer() SeedRnd MilliSecs(); ;Generate Random Map Dim Map(10,8) For a=0 To 10 For b=0 To 8 Map(a,b)=Rand(0,10) Next Next Type player Field x Field y Field dx Field dy End Type Global player.player = New player player\x=100 player\y=100 player\dx=2 player\dy=2 Repeat ClsColor 0,0,0 Cls DrawMap() ; ; Calc new player position ; player\x=player\x+player\dx player\y=player\y+player\dy If player\x>320 Or player\x<0 Then player\dx=-player\dx If player\y>256 Or player\y<0 Then player\dy=-player\dy If player\x>320 Then player\x=320 If player\x<0 Then player\x=0 If player\y>256 Then player\y=256 If player\y<0 Then player\y=0 ; ; check for wall ; If isWall(player\x,player\y) ; ; // TODO // ; ; player\dx=-player\dx ; player\dy=-player\dy End If ; ; draw player ; Color 255,0,0 Rect player\x-1,player\y-1,2,2,1 Color 64,64,64 Flip Forever Function isWall(x,y) If Map(x/32,y/32)=8 Then Return True Return False End Function Function DrawMap() For a=0 To 10 For b=0 To 8 If Map(a,b)=8 ;blocktile Rect a*32,b*32,32,32,1 End If Next Next End Function |
| ||
hi! Try moving the enemy down/up, check for a collision. If one occurs, reverse the y direction of the enemy. Then move the enemy left/right, check for a collision, if one occurs then reverse the x direction. Should keep you right.:) Oh and take out the repeat...forever loop and replace it with a While Not KeyHit(1) Wend loop. it means that ppl can exit the game when escpe is pressed :) |
| ||
you just need to seperate the x and y movement and collision and add "if keyhit(1) then end". better than a while loop becuase you can put it wherever you want (like in handleinput()) Graphics 320,256 SetBuffer BackBuffer() SeedRnd MilliSecs(); ;Generate Random Map Dim Map(10,8) For a=0 To 10 For b=0 To 8 Map(a,b)=Rand(0,10) Next Next Type player Field x Field y Field dx Field dy End Type Global player.player = New player player\x=100 player\y=100 player\dx=2 player\dy=2 Repeat ClsColor 0,0,0 Cls DrawMap() ; ; Calc new player position ; player\x=player\x+player\dx If player\x>320 Or player\x<0 Then player\dx=-player\dx If player\x>320 Then player\x=320 If player\x<0 Then player\x=0 ; ; check for wall x ; If isWall(player\x,player\y) player\dx=-player\dx player\x=player\x+player\dx End If player\y=player\y+player\dy If player\y>256 Or player\y<0 Then player\dy=-player\dy If player\y>256 Then player\y=256 If player\y<0 Then player\y=0 ; ; check for wall y ; If isWall(player\x,player\y) player\dy=-player\dy player\y=player\y+player\dy End If ; ; draw player ; Color 255,0,0 Rect player\x-1,player\y-1,2,2,1 Color 64,64,64 Flip If KeyHit(1) Then End Forever Function isWall(x,y) If Map(x/32,y/32)=8 Then Return True Return False End Function Function DrawMap() For a=0 To 10 For b=0 To 8 If Map(a,b)=8 ;blocktile Rect a*32,b*32,32,32,1 End If Next Next End Function |
| ||
You might also want to use Floor() instead of using the built-in Int(). The Int() rounds anything over .5 up to 1 Floor() drops the fraction, which is what you want done. Function isWall(x,y) If Map(Floor(x/32),Floor(y/32))=8 Then Return True Return False End Function |