Results 1 to 10 of 10

Thread: [RESOLVED] Detecting a Collision "in advance"

Threaded View

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Posts
    97

    Resolved [RESOLVED] Detecting a Collision "in advance"

    Hey,

    The attached picture shows a game I'm working on. The Player is the white dot in the centre, and the map, including the brown houses, move around the Player according to where you click.

    I have a "HitTest" function that stops the Player when he collides with a wall; it first detects whether the Player is inside or outside the house, and makes calculatations accordingly, allowing for the Player to travel through the grey doors.

    My problem is, as you can see in the screenshot, while the Player does stop when he hits a wall, it's a little later than I'd like, resulting in the Player appearing to be half-in and half-out of the house (the Player's co-ordinates are taken to be the centre of the white dot).

    I tried to get around this by detecting collision with an invisible "border" around the house - the problem then is that the player can't get OUT of the house, as when he exits through the door, the game stops him because he's still inside the border (I have since removed the border).

    Here's the code - if anyone can find a solution to my problem, I'd be very grateful. If you see a way to improve on the code's efficiency also (shouldn't be too hard), please let me know

    Declarations
    Code:
    Public Type PlayerObj
        ZoneX As Long
        ZoneY As Long
        X As Single
        Y As Single
        XPos As Single
        YPos As Single
        House As Integer
        Width As Long
        Height As Long
        Picture As StdPicture
        Speed As Long
        MoveTime As Long
        MoveSpeedX As Single
        MoveSpeedY As Single
    End Type
    
    Public Player As PlayerObj
    
    Public Type HouseObj
        XPos As Single
        YPos As Single
        X As Long
        Y As Long
        Width As Long
        Height As Long
        Colour As String
        'Door (distance from top corner)
            DX As Single
            DY As Single
            DWidth As Long
            DHeight As Long
            DColour As String
    End Type
    
    Public Type ZoneObj
        Houses As Long
        House() As HouseObj
    End Type
    
    Public Zone() As ZoneObj
    HitTest Function
    Code:
    Public Function HitTest() As Integer
    
    Dim i As Integer
    Dim PX As Single, PY As Single, X2 As Single, Y2 As Single, _
        DX1 As Single, DX2 As Single, DY1 As Single, DY2 As Single
    
    With Player
        PX = .X + .MoveSpeedX
        PY = .Y + .MoveSpeedY
    End With
    
    'Returns a value depending on which side of the Player has collided
    '     __1__
    '    |     |
    '   4| [i] |2
    '    |_____|
    '       3
    
    'Check if the Player hits a house
        For i = 1 To Zone(Player.ZoneX, Player.ZoneY).Houses
            With Zone(Player.ZoneX, Player.ZoneY).House(i)
    
                X2 = .X + .Width
                Y2 = .Y + .Height
                DY1 = .Y + .DY
                DY2 = .Y + .DY + .DHeight
                DX1 = .X + .DX
                DX2 = .X + .DX + .DWidth
                
                'Is the player outside?
                If Player.House = 0 Then
                
                    'Is he entering a house...
                    If PX >= .X And PX <= X2 Then
                        If PY >= .Y And PY <= Y2 Then
                
                            '... from the left?
                            If Player.MoveSpeedX > 0 Then
                                If PX >= .X Then
                                    'Is he using the door?
                                    If PY >= DY1 And PY <= DY2 And DX1 = .X Then
                                        Player.House = i 'Set house
                                        Exit Function
                                    Else
                                        HitTest = 2
                                    End If
                                End If
                            End If
                            
                            '... from the right?
                            If Player.MoveSpeedX < 0 Then
                                If PX <= X2 Then
                                    'Is he using the door?
                                    If PY >= DY1 And PY <= DY2 And DX1 = X2 Then
                                        Player.House = i 'Set house
                                        Exit Function
                                    Else
                                        HitTest = 4
                                    End If
                                End If
                            End If
                            
                            '... from the top?
                            If Player.MoveSpeedY > 0 Then
                                If PY >= .Y Then
                                    'Is he using the door?
                                    If (PX >= DX1) And (PX <= DX2) Then
                                        If DY1 = .Y Then
                                            Player.House = i 'Set house
                                            Exit Function
                                        End If
                                    Else
                                        HitTest = 1
                                    End If
                                End If
                            End If
                            
                            '... from the bottom?
                            If Player.MoveSpeedY < 0 Then
                                If PY <= Y2 Then
                                    'Is he using the door?
                                    If PX >= DX1 And PX <= DX2 And DY1 = Y2 Then
                                        Player.House = i 'Set house
                                        Exit Function
                                    Else
                                        HitTest = 3
                                    End If
                                End If
                            End If
                            
                        End If
                    End If
                    
                'Or is he in a house, exiting...
                ElseIf Player.House = i Then
                
                    '... from the left?
                    If Player.MoveSpeedX > 0 Then
                        If PX >= X2 Then
                            'Is he using the door?
                            If PY >= DY1 And PY <= DY2 And DX1 = X2 Then
                                Player.House = 0 'Set outside
                                Exit Function
                            Else
                                HitTest = 2
                                Player.X = X2
                                Halt
                            End If
                        End If
                        
                    '... from the right?
                    Else
                        If PX <= .X Then
                            'Is he using the door?
                            If PY >= DY1 And PY <= DY2 And DX1 = .X Then
                                Player.House = 0 'Set outside
                                Exit Function
                            Else
                                HitTest = 4
                                Player.X = .X
                                Halt
                            End If
                        End If
                    End If
                    
                    '... from the top?
                    If Player.MoveSpeedY > 0 Then
                        If PY >= Y2 Then
                            'Is he using the door?
                            If PX >= DX1 And PX <= DX2 And DY1 = Y2 Then
                                Player.House = 0 'Set outside
                                Exit Function
                            Else
                                HitTest = 3
                                Player.Y = Y2
                                Halt
                            End If
                        End If
                    
                    '... from the bottom?
                    Else
                        If PY <= .Y Then
                            'Is he using the door?
                            If PX >= DX1 And PX <= DX2 And DY1 = .Y Then
                                Player.House = 0 'Set outside
                                Exit Function
                            Else
                                HitTest = 1
                                Player.Y = .Y
                                Halt
                            End If
                        End If
                    End If
                End If
                        
            End With
        Next i
    
    End Function
    Code that moves the Player
    Code:
    Private Sub MapUpdate_Timer()
    
    Dim Hit As Integer
    
    'Updates the map every frame
    Game.Cls
    
        'Draw Houses
        UpdateMap
    
        'Draw Player
        With Player
        
            If (.MoveTime > 0) Then
            
                'Move Player
                Hit = HitTest
                If Hit = 0 Then
                    .X = .X + .MoveSpeedX
                    .Y = .Y + .MoveSpeedY
                    .MoveTime = .MoveTime - 1
                End If
                
                    'Move zones
                    If (.X >= 500) Then
                        .X = 500 - .X
                        .ZoneX = .ZoneX + 1
                    ElseIf (.X <= 0) Then
                        .X = 500 + .X
                        .ZoneX = .ZoneX - 1
                    End If
                    If (.Y >= 500) Then
                        .Y = 500 - .Y
                        .ZoneY = .ZoneY + 1
                    ElseIf (.Y <= 0) Then
                        .Y = 500 + .Y
                        .ZoneY = .ZoneY - 1
                    End If
                    
            Else 'Stop
                .MoveSpeedX = 0
                .MoveSpeedY = 0
            End If
            
            'Draw Player
            Call DrawPlayer(Player, .XPos, .YPos, .Width, .Height)
            
        End With
    
    Game.Refresh
    
    End Sub
    Attached Images Attached Images  

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width