i did these code for create RayCasting:

Option Explicit

Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)

Private Const PI As Double = 3.14159265358979

Dim LevelMap(12) As Variant
Dim CamWidth As Long
Dim CamHeight As Long
Dim CamHalfHeight As Long
Dim RayCastingPrecision As Long
Dim PlayerX As Double
Dim PlayerY As Double
Dim PlayerAngle As Long
Dim PlayerFOV As Long
Dim PlayerMovement As Double
Dim PlayerRotation As Double

Dim blnGameLoop As Boolean
Dim colors(3) As ColorConstants

Public Function Floor(ByVal x As Double) As Long
    Floor = (-Int(x) * (-1))
End Function

Private Function DegreeToRadians(degree As Long) As Double
    DegreeToRadians = degree * PI / 180
End Function

Private Sub DrawLine(X0 As Long, Y0 As Long, X1 As Long, Y1 As Long, Color As ColorConstants)
    Me.Line (X0, Y0)-(X1, Y1), Color
End Sub

Private Sub rayCasting()
    ' O RayAngle é o angulo atual do "raio".
    ' se ele começa olhando para angulo 90º e tem fov 60, então o rayAngle vai de 60 até 120, sendo incrementado por fov/width
    Dim rayAngle As Long
    rayAngle = PlayerAngle - PlayerFOV / 2
    ' Para Cada coluna da tela
    Dim raycount As Long
    For raycount = 0 To CamWidth
        ' Player dados
        Dim RayX As Double
        Dim RayY As Double
        RayX = PlayerX
        RayY = PlayerY


        ' Com cosseno e seno do angulo conseguimos a direção do raio sobre o grid a partir do ponto de visão.
        ' Aqui teremos a direção do raio sobre a matriz e também o modulo (passo)
        Dim rayCos As Double
        Dim raySin As Double
        rayCos = Cos(DegreeToRadians(rayAngle)) / RayCastingPrecision
        raySin = Sin(DegreeToRadians(rayAngle)) / RayCastingPrecision

        ' Colisão do raio com as paredes
        Dim Wall As Long
        Wall = 0
        While (Wall = 0) ' Aqui o "raio" seria tipo uma progetil que sai do personagem até colidir com uma parede

            RayX = RayX + rayCos ' novo x do raio
            RayY = RayY + raySin ' novo y do raio
            Wall = LevelMap(Floor(RayY))(Floor(RayX)) ' verifica colisão com a parede (não nulo na matriz)
        Wend

        ' Distancia até a parede (teorema de pitagoras), uma vez que temos o (X,Y) do personagem e da parede
        Dim distance As Double
        distance = Sqr((PlayerX - RayX) ^ 2 + (PlayerY - RayY) ^ 2)

        ' Correção olho de peixe (sem colisão com a parede), melhora a vista em corredores ou proximo de paredes
        distance = distance * Cos(DegreeToRadians(rayAngle - PlayerAngle))

        'Altura da parede em consequência a distancia
        'quando mais longe a parede está menor ela é e vice versa, são inversamente proporcionais
        Dim WallHeight As Long
        WallHeight = Floor(CamHalfHeight / distance)
        If (WallHeight > CamHalfHeight) Then WallHeight = CamHalfHeight


         'Desenhando as paredes usando os tamanhos calculados acima
        DrawLine raycount, 0, raycount, CamHalfHeight - WallHeight, ColorConstants.vbCyan 'céu
        If (Wall > 0) Then
            DrawLine raycount, CamHalfHeight - WallHeight, raycount, CamHalfHeight + WallHeight, colors(Wall) ' Parede
        End If
        DrawLine raycount, CamHalfHeight + WallHeight, raycount, CamHeight, vbMagenta ' chão
        Wall = 0
        ' Incremento da ray
        rayAngle = rayAngle + PlayerFOV / CamWidth
    Next raycount
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim playerCos As Double
    Dim playerSin As Double
    Dim newX As Double
    Dim newY As Double
    If (KeyCode = vbKeyEscape) Then
        blnGameLoop = False
        End
    ElseIf (KeyCode = vbKeyUp) Then

        playerCos = Cos(DegreeToRadians(PlayerAngle)) * PlayerMovement
        playerSin = Sin(DegreeToRadians(PlayerAngle)) * PlayerMovement
        newX = PlayerX + playerCos
        newY = PlayerY + playerSin

        ' Verficia colisão do player
        If (LevelMap(Floor(newY))(Floor(newX)) = 0) Then
            PlayerX = newX
            PlayerY = newY
        End If
    ElseIf (KeyCode = vbKeyDown) Then


        playerCos = Cos(DegreeToRadians(PlayerAngle)) * PlayerMovement
        playerSin = Sin(DegreeToRadians(PlayerAngle)) * PlayerMovement
        newX = PlayerX - playerCos
        newY = PlayerY - playerSin

        ' Verficia colisão do player
        If (LevelMap(Floor(newY))(Floor(newX)) = 0) Then
            PlayerX = newX
            PlayerY = newY
        End If
    ElseIf (KeyCode = vbKeyLeft) Then
        PlayerAngle = PlayerAngle - PlayerRotation
    ElseIf (KeyCode = vbKeyRight) Then
        PlayerAngle = PlayerAngle + PlayerRotation
    End If
End Sub

Private Sub Form_Load()
    CamWidth = 1028
    CamHeight = 720
    CamHalfHeight = CInt(CamHeight / 2)
    RayCastingPrecision = 100
    PlayerX = 2
    PlayerY = 3
    PlayerAngle = 0
    PlayerFOV = 60
    PlayerMovement = 0.1
    PlayerRotation = 0.8
    Me.Show
    LevelMap(0) = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    LevelMap(1) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(2) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(3) = Array(1, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 1)
    LevelMap(4) = Array(1, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 1)
    LevelMap(5) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(6) = Array(1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1)
    LevelMap(7) = Array(1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1)
    LevelMap(8) = Array(1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1)
    LevelMap(9) = Array(1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1)
    LevelMap(10) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(11) = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    blnGameLoop = True

    colors(0) = vbBlue
    colors(1) = vbGreen
    colors(2) = vbRed

    While (blnGameLoop = True)
        Me.Cls
        rayCasting
        blnGameLoop = True
        DoEvents
    Wend
End Sub

Private Sub Form_Unload(Cancel As Integer)
    blnGameLoop = False
End Sub

my problem is on these code:

 'Desenhando as paredes usando os tamanhos calculados acima
        DrawLine raycount, 0, raycount, CamHalfHeight - WallHeight, ColorConstants.vbCyan 'Sky
        If (Wall > 0) Then
            DrawLine raycount, CamHalfHeight - WallHeight, raycount, CamHalfHeight + WallHeight, colors(Wall) ' Wall
        End If
        DrawLine raycount, CamHalfHeight + WallHeight, raycount, CamHeight, vbMagenta ' floor
        Wall = 0

all vertical wall lines drawed have the same color even some are different color... i don't understand why :(

rproffitt commented: Neat but no one I know has VB6 installed. May want to move to a current compiler. +17

Recommended Answers

All 24 Replies

It's difficult to determine the cause without seeing the rest of your project. Could it possibly be the DrawMode of the surface on which the line is being drawn?

SCBWV i shared all code.
https://imgur.com/I57p4P6
you see the green 'rectangle'... if the block(64 pixels of dimension) change color, it will change all rectangle and not only the block

I see what you're saying. I got a black block (line) after so long of pressing a key. The resulting color is dependent on the DrawMode, but the size is based on your calculations in the rayCasting Sub. I would suggest moving all you can in the rayCasting Sub to outside the For/Next loop. There's no need in Dim'ing variables repeatedly.

DrawMode is 13 - copy pen
and yes i create the variables, now, outside the for...next

In your code, the incorrect coloring is because the colors array is defined with a size of 3 (Dim colors(3) As ColorConstants), but you have four different wall colors defined in your array. This causes an "index out of bounds" error, and the walls end up being drawn with the default color (vbCyan) instead of their intended colors.

Change the size of your colors to 'Dim colors(4) As ColorConstants'.
Change your colors e.g. -

colors(0) = vbBlue
colors(1) = vbGreen
colors(2) = vbRed
colors(3) = ' Add the fourth color here (e.g., vbYellow)

You probably heard this before, you need to move away from vb6 as it has been long dead and buried, there is no more support for it etc. a Good example was now with your question, almost nobody has access to vb6 to test your code, it was by chance that I saw your array error.

even fix that error.. my mistake... the problem remains.
i can't see 2 different colors on walls :(
these function:

Public Function Floor(ByVal x As Double) As Long
    Floor = (-Int(x) * (-1))
End Function

is correct?
maybe i have another calculation error... but tell me if these function is correct?
VB6 don't have floor(), ceil() and some useful math functions

i continue with same problem...
i will do another test: draw the map with Rays... and then i can see what is really done ;)

commented: Is there a specific reason that you must use VB6? You are going to run into constant issues with development and deployment. +15

AndreRet: how can i use, more faster, VS2022?
it's slow for enter a project and run it :(

commented: What do you use for your dev machine? Here it's one of the usual i7, 16GB RAM all SSD setups. +17

CPU: I3-5005U 2.0 GHz
RAM: 8GB's
HDD: 500GB's
maybe i found the problem: the graphicard predefined is Intel HD Graphics 5500.. but i have a NVIDIA Geforce... i must enable some 'startup' programs

commented: That HDD is going to dog you. Switch to SSD ASAP. +0
commented: The hardware should be more than ample to run VS2022 just fine. +15

HDD is 1 problem.. i'm trying month less month resolve it ;)

commented: It's the one thing I find causing folk to write "it's slow." +0

thanks for all to all

If you are planning to switch to VS 2022, great and congrats! It might seem very intimidating at first until you get the hang of it.
Here are some pointers which I hope will help you getting started -

  1. Download the free community edition from Microsoft
  2. Hardware requirements as per your post above -

ARM64 or x64 processor; Quad-core or better recommended. ARM 32 processors are not supported.
Minimum of 4 GB of RAM. Many factors impact resources used; we recommend 16 GB RAM for typical professional solutions.
Windows 365: Minimum 2 vCPU and 8 GB RAM. 4 vCPU and 16 GB of RAM recommended.
Hard disk space: Minimum of 850 MB up to 210 GB of available space, depending on features installed; typical installations require 20-50 GB of free space. We recommend installing Windows and Visual Studio on a solid-state drive (SSD) to increase performance.
Video card that supports a minimum display resolution of WXGA (1366 by 768); Visual Studio will work best at a resolution of 1920 by 1080 or higher.
Minimum resolution assumes zoom, DPI settings, and text scaling are set at 100%. If not set to 100%, minimum resolution should be scaled accordingly. For example, if you set the Windows display ‘Scale and layout’ setting on your Surface Book, which has a 3000x2000 physical display, to 200%, then Visual Studio would see a logical screen resolution of 1500x1000, meeting the minimum 1366x768 requirement.

  1. How to optimize Visual Studio performance
  2. Google for migration tools that can migrate/convert MOST, but not all your VB 6 code. THIS Tool is still used, not sure if it is geared for VS 2022.
  3. Play with VS and check/download it's tons of extensions available (Most are Free) that might help you in your project, no use re-creating the wheel.
  4. With all being said and done, I doubt it if your current system will be able to run/test Raytracing/casting successfully, you will probably need to upgrade your development pc/laptop as well.
  5. GitHub has plenty of samples to test in newest .net

Happy coding

now i'm doing another test:

Private Sub rayCasting()

    Dim rayAngle As Double
    Dim IncreRayAngle  As Long
    Dim RayX As Double
    Dim RayY As Double
    Dim rayCos As Double
    Dim raySin As Double

    IncreRayAngle = DegreeToRadians(PlayerFOV) / CamWidth
    RayX = PlayerX * MapResolution
    RayY = PlayerY * MapResolution
    For rayAngle = PlayerAngle To CamWidth
        DrawLine Floor(RayX), Floor(RayY), Floor(RayX + Cos(rayAngle) * 50), Floor(RayY + Sin(rayAngle) * 50), vbRed

        rayAngle = rayAngle + IncreRayAngle

    Next rayAngle
End Sub

why these lines are drawed 360º instead just 1028 lines doing like a vision cone:
https://imgur.com/8iSJ9VJ

Without being able to test the code (vb6), I can see the loop is iterating from 'PlayerAngle' to 'CamWidth', which covers the entire 360º range. Instead, you should limit the loop to the vision cone angle. I think the below code should do what you require (very rusted at vb6 and imagery were not my strong points). Assuming 'PlayerAngle' represents the center angle of the vision cone and 'CamWidth' represents the total angle span of the cone -

Private Sub rayCasting()
    Dim rayAngle As Double
    Dim IncreRayAngle As Double
    Dim RayX As Double
    Dim RayY As Double
    Dim rayCos As Double
    Dim raySin As Double

    IncreRayAngle = DegreeToRadians(CamWidth) / CamWidth
    RayX = PlayerX * MapResolution
    RayY = PlayerY * MapResolution

    For rayAngle = PlayerAngle - CamWidth/2 To PlayerAngle + CamWidth/2 Step IncreRayAngle
        DrawLine Floor(RayX), Floor(RayY), Floor(RayX + Cos(rayAngle) * 50), Floor(RayY + Sin(rayAngle) * 50), vbRed
    Next rayAngle
End Sub

heres entire code:

Option Explicit

Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)

Private Const PI As Double = 3.14159265358979

Dim LevelMap(12) As Variant
Dim MapResolution As Long
Dim CamWidth As Long
Dim CamHeight As Long
Dim CamHalfHeight As Long
Dim RayCastingPrecision As Long
Dim PlayerX As Double
Dim PlayerY As Double
Dim PlayerAngle As Long
Dim PlayerFOV As Long
Dim PlayerMovement As Double
Dim PlayerRotation As Double

Dim blnGameLoop As Boolean
Dim colors(4) As ColorConstants

Function Floor(ByVal n As Double) As Long
  Floor = (n \ 1)
End Function

Private Function DegreeToRadians(degree As Long) As Double
    DegreeToRadians = degree * PI / 180
End Function

Private Sub DrawLine(X0 As Long, Y0 As Long, X1 As Long, Y1 As Long, Color As ColorConstants)
    Me.Line (X0, Y0)-(X1, Y1), Color
End Sub
Private Sub DrawMap()
    Dim X0 As Long
    Dim Y0 As Long
    Dim x As Long
    Dim y As Long
    Dim clr As Long
    X0 = 0
    Y0 = 0
    For y = 0 To 11
        For x = 0 To 14
            clr = LevelMap(y)(x)
            Me.Line (X0, Y0)-Step(MapResolution, MapResolution), colors(clr), BF
            X0 = X0 + MapResolution + 5
        Next x
        Y0 = Y0 + MapResolution + 5
        X0 = 0
    Next y
    Dim PlayerDotX As Long
    Dim PlayerDotY As Long
    PlayerDotX = PlayerX * MapResolution
    PlayerDotY = PlayerY * MapResolution

    Me.Circle (PlayerDotX, PlayerDotY), 5
    Me.Line (PlayerDotX, PlayerDotY)-Step((30) * Cos(DegreeToRadians(PlayerAngle)), (30) * Sin(DegreeToRadians(PlayerAngle))), vbGreen

End Sub

Private Sub rayCasting()
    Dim rayAngle As Double
    Dim IncreRayAngle As Double
    Dim RayX As Double
    Dim RayY As Double
    Dim rayCos As Double
    Dim raySin As Double

    IncreRayAngle = DegreeToRadians(CamWidth) / CamWidth
    RayX = PlayerX * MapResolution
    RayY = PlayerY * MapResolution

    For rayAngle = PlayerAngle - CamWidth / 2 To PlayerAngle + CamWidth / 2 Step IncreRayAngle
        DrawLine Floor(RayX), Floor(RayY), Floor(RayX + Cos(rayAngle) * 50), Floor(RayY + Sin(rayAngle) * 50), vbRed
    Next rayAngle
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim playerCos As Double
    Dim playerSin As Double
    Dim newX As Double
    Dim newY As Double
    If (KeyCode = vbKeyEscape) Then
        blnGameLoop = False
        End
    ElseIf (KeyCode = vbKeyUp) Then

        playerCos = Cos(DegreeToRadians(PlayerAngle)) * PlayerMovement
        playerSin = Sin(DegreeToRadians(PlayerAngle)) * PlayerMovement
        newX = PlayerX + playerCos
        newY = PlayerY + playerSin

        ' Verficia colisão do player
        'If (LevelMap(Floor(newY))(Floor(newX)) = 0) Then
            PlayerX = newX
            PlayerY = newY
        'End If
    ElseIf (KeyCode = vbKeyDown) Then


        playerCos = Cos(DegreeToRadians(PlayerAngle)) * PlayerMovement
        playerSin = Sin(DegreeToRadians(PlayerAngle)) * PlayerMovement
        newX = PlayerX - playerCos
        newY = PlayerY - playerSin

        ' Verficia colisão do player
 '        If (LevelMap(Floor(newY))(Floor(newX)) <> 0) Then
            PlayerX = newX
            PlayerY = newY
       ' End If
    ElseIf (KeyCode = vbKeyLeft) Then
        PlayerAngle = PlayerAngle - PlayerRotation
    ElseIf (KeyCode = vbKeyRight) Then
        PlayerAngle = PlayerAngle + PlayerRotation
    End If
End Sub

Private Sub Form_Load()
    CamWidth = 1028
    CamHeight = 720
    CamHalfHeight = CInt(CamHeight / 2)
    MapResolution = 64
    RayCastingPrecision = 10
    PlayerX = 2
    PlayerY = 2
    PlayerAngle = 0
    PlayerFOV = 60
    PlayerMovement = 0.1
    PlayerRotation = 1#
    Me.Show
    LevelMap(0) = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    LevelMap(1) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(2) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(3) = Array(1, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 1)
    LevelMap(4) = Array(1, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 1)
    LevelMap(5) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(6) = Array(1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1)
    LevelMap(7) = Array(1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1)
    LevelMap(8) = Array(1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1)
    LevelMap(9) = Array(1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1)
    LevelMap(10) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(11) = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    blnGameLoop = True

    colors(0) = vbBlue
    colors(1) = vbGreen
    colors(2) = vbRed
    colors(3) = vbYellow

    While (blnGameLoop = True)
        Me.Cls
        DrawMap
        rayCasting
        blnGameLoop = True
        DoEvents
    Wend
End Sub

Private Sub Form_Unload(Cancel As Integer)
    blnGameLoop = False
End Sub
commented: Ok, so did you test my code? Did you receive any other errors? I am not about to re-write all of your code. +15

now i have something:

Private Sub rayCasting()
    Dim RayCount As Long
    Dim RayAngle As Double
    Dim RayX As Double
    Dim RayY As Double

    RayX = PlayerX * MapResolution
    RayY = PlayerY * MapResolution
    RayAngle = PlayerAngle - (80 / 2 * PlayerRotation / 10)
    For RayCount = 0 To 80
        DrawLine Floor(RayX), Floor(RayY), Floor(RayX + Cos(RayAngle) * 100), Floor(RayY + Sin(RayAngle) * 100), vbRed
        RayAngle = RayAngle + PlayerRotation / 10
    Next RayCount
    RayAngle = 0#
End Sub

the camviewe is 80 pixels.... but how can i use 1000 pixels(for example), if the viewe cone will be more big than 360º?
(almost done for learn on doing my own RayCasting)

Again, I am unable to test but I would say that you need to change 'For RayCount = 0 To 80' to 'For RayCount = 0 To 1000'. I can however promise you that it is huge and your pc will probably not be able to run it with your current setup.

i get your point of speed. but change the '80' to '1000' i can get more than 360º... and that is make me think

finally i did something that works:

Option Explicit

Private Const PI As Double = 3.14159265358979

Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)


Dim LevelMap(12) As Variant
Dim MapResolution As Long
Dim CamWidth As Long
Dim CamHeight As Long
Dim CamHalfHeight As Long
Dim RayCastingPrecision As Long
Dim PlayerX As Double
Dim PlayerY As Double
Dim PlayerAngle As Double
Dim PlayerFOV As Long
Dim PlayerMovement As Double
Dim PlayerRotation As Double

Dim blnGameLoop As Boolean
Dim colors(4) As ColorConstants

Function Ceil(value As Double) As Long
    Ceil = IIf(Fix(value) = value, value, Fix(value) + 1)
End Function

Function DecimalPart(value As Double) As Long
    DecimalPart = value - Int(value)
End Function

Public Function Floor(ByVal Number) As Long
    Floor = Fix(Number)
End Function

Private Function DegreeToRadians(degree As Long) As Double
    DegreeToRadians = degree * PI / 180
End Function

Private Sub DrawLine(X0 As Long, Y0 As Long, X1 As Long, Y1 As Long, Color As ColorConstants)
    Me.Line (X0, Y0)-(X1, Y1), Color
End Sub

Private Sub DrawMap()
    Dim X0 As Long
    Dim Y0 As Long
    Dim x As Long
    Dim y As Long

    Dim clr As Long
    X0 = 0
    Y0 = 0
    Me.DrawStyle = 5
    For y = 0 To 11
        For x = 0 To 14

            clr = LevelMap(y)(x)
            Me.Line (X0, Y0)-Step(MapResolution, MapResolution), colors(clr), BF
            X0 = X0 + MapResolution
        Next x
        Y0 = Y0 + MapResolution
        X0 = 0
    Next y

    Dim PlayerDotX As Long
    Dim PlayerDotY As Long
    PlayerDotX = PlayerX
    PlayerDotY = PlayerY
    Me.DrawStyle = 0
    Me.Circle (PlayerDotX, PlayerDotY), 5
    Me.Line (PlayerDotX, PlayerDotY)-Step((30) * Cos(PlayerAngle), (30) * Sin(PlayerAngle)), vbGreen

End Sub

Private Sub RayCasting()
    Dim startAngle As Double
    Dim endAngle As Double
    Dim incrementAngle As Double
    Dim distance As Double
    Dim RayX As Double
    Dim RayY As Double
    Dim RayAngle As Double
    Dim RayActualX As Double
    Dim RayActualY As Double
    Dim Wall As Integer

    'Obter a posição inicial dos Raios com a posição do jogador:
    RayX = PlayerX
    RayY = PlayerY

    'o ângulo do meio tem de ser o ângulo do jogador
    startAngle = PlayerAngle - DegreeToRadians(90 / 2)
    endAngle = PlayerAngle + DegreeToRadians(90 / 2)
    incrementAngle = 0.01

    For RayAngle = startAngle To endAngle Step incrementAngle
        Wall = 0
        RayActualX = RayX
        RayActualY = RayY
        Wall = LevelMap(Floor(RayActualX / MapResolution))(Floor(RayActualY / MapResolution))
        While (Wall = 0)
            RayActualX = RayActualX + Cos(RayAngle)
            RayActualY = RayActualY + Sin(RayAngle)
            Wall = LevelMap(Floor(RayActualX / MapResolution))(Floor(RayActualY / MapResolution))
        Wend
        ' Cast a ray from the player's position at this angle
        ' Check for collision with any walls
        ' Calculate the distance to the collision point
        ' Draw the wall section on the screen using the distance for perspective
        'DrawLine CLng(RayX), CLng(RayY), CLng(RayActualX), CLng(RayActualY), vbCyan
        Me.Line (CLng(RayX), CLng(RayY))-(CLng(RayActualX), CLng(RayActualY)), vbCyan
    Next RayAngle
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim playerCos As Double
    Dim playerSin As Double
    Dim newX As Double
    Dim newY As Double
    If (KeyCode = vbKeyEscape) Then
        blnGameLoop = False
        End
    ElseIf (KeyCode = vbKeyUp) Then

        playerCos = Cos(PlayerAngle) * PlayerMovement
        playerSin = Sin(PlayerAngle) * PlayerMovement
        newX = PlayerX + playerCos
        newY = PlayerY + playerSin

        ' Verficia colisão do player
        If (LevelMap(Floor(newY / MapResolution))(Floor(newX / MapResolution)) = 0) Then
            PlayerX = newX
            PlayerY = newY

        End If
         Me.Caption = "PlayerX: " + CStr(Floor(PlayerX / MapResolution)) + "   PlayerY: " + CStr(Floor(PlayerY / MapResolution))
    ElseIf (KeyCode = vbKeyDown) Then


        playerCos = Cos(PlayerAngle) * PlayerMovement
        playerSin = Sin(PlayerAngle) * PlayerMovement
        newX = PlayerX - playerCos
        newY = PlayerY - playerSin

        ' Verficia colisão do player
         'If (LevelMap(Floor(newY / MapResolution))(Floor(newX / MapResolution)) <> 0) Then
            PlayerX = newX
            PlayerY = newY
        'End If
       Me.Caption = "PlayerX: " + CStr(Floor(PlayerX / MapResolution)) + "   PlayerY: " + CStr(Floor(PlayerY / MapResolution))
    ElseIf (KeyCode = vbKeyLeft) Then
        PlayerAngle = PlayerAngle - PlayerRotation
    ElseIf (KeyCode = vbKeyRight) Then
        PlayerAngle = PlayerAngle + PlayerRotation
    End If
End Sub

Private Sub Form_Load()
    CamWidth = 500
    CamHeight = 720
    CamHalfHeight = CInt(CamHeight / 2)
    MapResolution = 64
    RayCastingPrecision = 5
    PlayerX = 2 * (MapResolution + 5)
    PlayerY = 2 * (MapResolution + 5)
    PlayerAngle = 0#
    PlayerFOV = 60
    PlayerMovement = MapResolution / 20
    PlayerRotation = 0.1
    Me.Show
    LevelMap(0) = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    LevelMap(1) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(2) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(3) = Array(1, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 1)
    LevelMap(4) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(5) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(6) = Array(1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1)
    LevelMap(7) = Array(1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1)
    LevelMap(8) = Array(1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1)
    LevelMap(9) = Array(1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1)
    LevelMap(10) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(11) = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    blnGameLoop = True

    colors(0) = vbBlue
    colors(1) = vbGreen
    colors(2) = vbRed
    colors(3) = vbYellow
    Me.Caption = "PlayerX: " + CStr(Floor(PlayerX / MapResolution)) + "   PlayerY: " + CStr(Floor(PlayerY / MapResolution))
    While (blnGameLoop = True)
        Me.Cls
        DrawMap
        RayCasting
        blnGameLoop = True
        DoEvents
    Wend
End Sub

Private Sub Form_Unload(Cancel As Integer)
    blnGameLoop = False
End Sub

my problem is here:

For RayAngle = startAngle To endAngle Step incrementAngle
        Wall = 0
        RayActualX = RayX
        RayActualY = RayY
        Wall = LevelMap(Floor(RayActualX / MapResolution))(Floor(RayActualY / MapResolution))
        While (Wall = 0)
            RayActualX = RayActualX + Cos(RayAngle)
            RayActualY = RayActualY + Sin(RayAngle)
            Wall = LevelMap(Floor(RayActualX / MapResolution))(Floor(RayActualY / MapResolution))
        Wend
''''''''...................

because the line can go more big what screen :(
i don't understand why.. can anyone tell me what i'm doing wrong?
yes... i increment 1 pixel on my DDA algoritm

Replace your 'DrawLine' subroutine by adding boundary checks before drawing the lines -

Private Sub DrawLine(X0 As Long, Y0 As Long, X1 As Long, Y1 As Long, Color As ColorConstants)
    Dim minX As Long
    Dim minY As Long
    Dim maxX As Long
    Dim maxY As Long

    ' Calculate the boundary coordinates
    minX = 0
    minY = 0
    maxX = ScaleWidth - 1
    maxY = ScaleHeight - 1

    ' Perform boundary checks for X coordinates
    If X0 < minX And X1 < minX Then Exit Sub
    If X0 > maxX And X1 > maxX Then Exit Sub
    If X0 < minX Then X0 = minX
    If X1 < minX Then X1 = minX
    If X0 > maxX Then X0 = maxX
    If X1 > maxX Then X1 = maxX

    ' Perform boundary checks for Y coordinates
    If Y0 < minY And Y1 < minY Then Exit Sub
    If Y0 > maxY And Y1 > maxY Then Exit Sub
    If Y0 < minY Then Y0 = minY
    If Y1 < minY Then Y1 = minY
    If Y0 > maxY Then Y0 = maxY
    If Y1 > maxY Then Y1 = maxY

    ' Draw the line within the boundaries
    Me.Line (X0, Y0)-(X1, Y1), Color
End Sub

The code checks the coordinates of the line and make sure they fall within the boundaries of the available screen. If any coordinate exceeds the boundary, it is adjusted to stay within the limits.

i found, finally, my error... on array index i swaped the X and Y values :(

Wall = LevelMap(Floor(RayActualY / MapResolution))(Floor(RayActualX / MapResolution))

i need understand more about these array:

LevelMap(0) = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    LevelMap(1) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(2) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(3) = Array(1, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 1)
    LevelMap(4) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(5) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(6) = Array(1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1)
    LevelMap(7) = Array(1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1)
    LevelMap(8) = Array(1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1)
    LevelMap(9) = Array(1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 1)
    LevelMap(10) = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
    LevelMap(11) = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)

so the 'LevelMap' index must be the 'Y' in these case?
anotherthing: the LineTo() API function is more faster than, from VB, Line()?

It depends on various factors such as the complexity of the drawing, the number of lines, and the hardware capabilities of your system.

The Line() method is used for drawing lines in VB6, and it provides a simple way to specify the starting and ending points of a line. The LineTo() method is part of the Windows API and requires more complex parameter handling.

There may be some slight performance differences between Line() and LineTo() but they are unlikely to be significant in most test cases.

If you have anymore questions, this post's original question has been answered, rather open a new post with a new question.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.