(Continued from above post) Also just to let ya know, if the collision isn't a sprite and its a tile in a tile engine, I do something differently but with the same algorithm. Most people would make the fatal mistake of looping through the whole map one tile at a time to check if a collision took place with the sprite. But if your map is gigantic in size, this would be sluggish. The faster way would be to check all 9 sides of the sprite to see if it collided into the tile surrounding it. Why check all 9 sides and not just the sprite itself? Cause if you are approaching the walls at an angle or move into a corner, you end up going through the walls! So for example, if you use rigid body collision, you do this, assuming you got a tile engine going:
vb Code:
Public Function Collision_Detection() As Boolean Dim Vertex_List(4) As Vector Dim Vertex_List2(4) As Vector Dim Boundry(8) As Vector Dim Position As Vector Dim I As Long Vertex_List(0) = Vector_New(0, 0) Vertex_List(1) = Vector_New(TILE_SIZE, 0) Vertex_List(2) = Vector_New(TILE_SIZE, TILE_SIZE) Vertex_List(3) = Vector_New(0, TILE_SIZE) Vertex_List2(0) = Vector_New(0, 0) Vertex_List2(1) = Vector_New(TILE_SIZE, 0) Vertex_List2(2) = Vector_New(TILE_SIZE, TILE_SIZE) Vertex_List2(3) = Vector_New(0, TILE_SIZE) With Player Boundry(0).X = .Coordinates.X - 1: Boundry(0).Y = .Coordinates.Y Boundry(1).X = .Coordinates.X: Boundry(1).Y = .Coordinates.Y - 1 Boundry(2).X = .Coordinates.X + 1: Boundry(2).Y = .Coordinates.Y Boundry(3).X = .Coordinates.X: Boundry(3).Y = .Coordinates.Y + 1 Boundry(4).X = .Coordinates.X: Boundry(4).Y = .Coordinates.Y Boundry(5).X = .Coordinates.X - 1: Boundry(5).Y = .Coordinates.Y - 1 Boundry(6).X = .Coordinates.X + 1: Boundry(6).Y = .Coordinates.Y - 1 Boundry(7).X = .Coordinates.X - 1: Boundry(7).Y = .Coordinates.Y + 1 Boundry(8).X = .Coordinates.X + 1: Boundry(8).Y = .Coordinates.Y + 1 For I = 0 To 8 If Boundry(I).X <= 0 Then Boundry(I).X = 0 If Boundry(I).Y <= 0 Then Boundry(I).Y = 0 If Boundry(I).X >= Map.Width - 1 Then Boundry(I).X = Map.Width - 1 If Boundry(I).Y >= Map.Height - 1 Then Boundry(I).Y = Map.Height - 1 Position.X = Map.Collision_Map.Vertex_List(Boundry(I).X, Boundry(I).Y).X Position.Y = Map.Collision_Map.Vertex_List(Boundry(I).X, Boundry(I).Y).Y .Collided = Collide(Vertex_List2(), Vertex_List(), 4, 4, Vector_Subtract(.Position, Position), .NColl, .DColl) If .Collided = True Then If Map.Collision_Map.Response(Boundry(I).X, Boundry(I).Y) = COLLISION_WALL Then Collision_Detection = True .Position = Vector_Subtract(.Position, Vector_Multiply2(.NColl, (.DColl * 1.01))) End If End If Next I End With end function
with sprite coordinates being the tile position of where the sprite is at on the map. To convert a position into tile coordinates you do this:
vb Code:
Public Sub Convert_Position_To_Coordinates(Sprite As Sprite_Type) Sprite.Coordinates.X = Int(Sprite.Position.X / TILE_SIZE) Sprite.Coordinates.Y = Int(Sprite.Position.Y / TILE_SIZE) End Sub
For Box to Box however, its similar but a little different for collision response:
vb Code:
Public Function Collision_Detection2(ByVal Overlap As Long) Const NO_COLLISION As Long = 0 Const COL_LEFT As Long = 1 Const COL_RIGHT As Long = 2 Const COL_UP As Long = 3 Const COL_DOWN As Long = 4 Dim Boundry(8) As Vector Dim Side As Long Dim I As Long With Player Boundry(0).X = .Coordinates.X - 1: Boundry(0).Y = .Coordinates.Y Boundry(1).X = .Coordinates.X: Boundry(1).Y = .Coordinates.Y - 1 Boundry(2).X = .Coordinates.X + 1: Boundry(2).Y = .Coordinates.Y Boundry(3).X = .Coordinates.X: Boundry(3).Y = .Coordinates.Y + 1 Boundry(4).X = .Coordinates.X: Boundry(4).Y = .Coordinates.Y Boundry(5).X = .Coordinates.X - 1: Boundry(5).Y = .Coordinates.Y - 1 Boundry(6).X = .Coordinates.X + 1: Boundry(6).Y = .Coordinates.Y - 1 Boundry(7).X = .Coordinates.X - 1: Boundry(7).Y = .Coordinates.Y + 1 Boundry(8).X = .Coordinates.X + 1: Boundry(8).Y = .Coordinates.Y + 1 For I = 0 To 8 If Boundry(I).X <= 0 Then Boundry(I).X = 0 If Boundry(I).Y <= 0 Then Boundry(I).Y = 0 If Boundry(I).X >= Map.Width - 1 Then Boundry(I).X = Map.Width - 1 If Boundry(I).Y >= Map.Height - 1 Then Boundry(I).Y = Map.Height - 1 Side = Collision_Box_To_Box2(Player.Position.X, Player.Position.Y, TILE_SIZE, TILE_SIZE, Boundry(I).X * TILE_SIZE, Boundry(I).Y * TILE_SIZE, TILE_SIZE, TILE_SIZE) If Side <> 0 Then If Map.Collision_Map.Response(Boundry(I).X, Boundry(I).Y) = COLLISION_WALL Then Collision_Detection2 = True .Collided = True Select Case Side Case COL_LEFT: .Position.X = .Position.X + Overlap Case COL_RIGHT:: .Position.X = .Position.X - Overlap Case COL_UP:: .Position.Y = .Position.Y + Overlap Case COL_DOWN:: .Position.Y = .Position.Y - Overlap End Select End If End If Next I End With End Function
Heres a project I uploaded for ya. Although it's an AStar sample I'm working on, it has the tile collision code I was talking about. Have fun
![]()






Mark Thread Resolved
Reply With Quote