how use RayCasting?

Started by
5 comments, last by JoeJ 1 month ago
i create a RayCasting function:
Private Sub DrawRays()

        Dim StepX As Double
        Dim StepY As Double
        Dim VertX As Double
        Dim VertY As Double
        Dim HorizX As Double
        Dim HorizY As Double
        Dim MapX As Long
        Dim MapY As Long
        Dim HorizDist As Double
        Dim VertDist As Double
        Dim WallDistance As Double
        Dim RayHeight As Double
        Dim RayRadians As Double
        Dim RadiansSteps As Double
        Dim RayCount As Long
        Dim RayCounts As Long = 0
        Dim OffSetGrid As Long
        Dim PreviousRayX As Double = 0
        Dim PreviousRayY As Double = 0
        Dim RayX As Double = 0
        Dim RayY As Double = 0

        'Get viewe Width:
        RayCount = 300

        MapX = Player.MapX
        MapY = player.MapY

        'Divide the FOV in a Radians steps:
        RadiansSteps = Radian60 / RayCount

        'Get the FOV start radians:
        RayRadians = (player.Radians - Radian30)

        RayCounts = 0
        Do While RayCounts < RayCount
			If (RayRadians > Radian360) Then RayRadians = 0.001 'correct some Radians
            'Check for horizontal intersections:
            'and get the 1st horizontal line intersection:
            If RayRadians >= 0 And RayRadians <= Math.PI Then 'Facing down
                HorizY = (Fix(player.PosY / ObjectSize) * ObjectSize) + ObjectSize ' Calculate grid position
                HorizX = player.PosX + (HorizY - player.PosY) / Math.Tan(RayRadians)
                StepY = ObjectSize
            ElseIf RayRadians = 0 Or RayRadians = Math.PI Then
                HorizY = player.PosY
                HorizX = player.PosX
            Else 'Facing Up
                HorizY = (Fix(player.PosY / ObjectSize) * ObjectSize) - 1
                HorizX = player.PosX + (HorizY - player.PosY) / Math.Tan(RayRadians)
                StepY = -ObjectSize
            End If
            StepX = StepY / Math.Tan(RayRadians)
            MapX = GetPositionMap(HorizX)
            MapY = GetPositionMap(HorizY)


            'Get all Vertical intersection lines until hit a wall:
            Do
                If MapX < 0 Or MapX > 9 Or MapY < 0 Or MapY > 9 Then Exit Do
                If levelmap0(MapY, MapX) = Color.Black Then Exit Do
                HorizX = HorizX + StepX
                HorizY = HorizY + StepY

                MapX = HorizX \ ObjectSize
                MapY = HorizY \ ObjectSize

            Loop
            'Get the Ray Distance:
            HorizDist = Math.Abs((player.PosX - HorizX) / Math.Cos(RayRadians))

            'Check for vertical intersections:
            'and get the 1st vertical line intersection:
            If RayRadians < Radian90 Or RayRadians > Radian270 Then 'Facing right
                VertX = (Fix(Player.PosX / ObjectSize) * ObjectSize) + ObjectSize ' Calculate grid position
                VertY = player.PosY + (player.PosX - VertX) * -Math.Tan(RayRadians)
                StepX = ObjectSize
            ElseIf RayRadians = Radian90 Or RayRadians = Radian270 Then
                VertY = Player.PosY
                VertX = Player.PosX
            Else 'Facing left
                VertX = (Fix(Player.PosX / ObjectSize) * ObjectSize) - 1
                VertY = player.PosY + (player.PosX - VertX) * -Math.Tan(RayRadians)
                StepX = -ObjectSize
            End If

            StepY = StepX * Math.Tan(RayRadians)
            MapX = GetPositionMap(VertX)
            MapY = GetPositionMap(VertY)

            'Get all Vertical intersection lines until hit a wall:
            Do
                If MapX < 0 Or MapX > 9 Or MapY < 0 Or MapY > 9 Then Exit Do
                If levelmap0(MapY, MapX) = Color.Black Then Exit Do
                VertX = VertX + StepX
                VertY = VertY + StepY

                MapX = VertX \ ObjectSize
                MapY = VertY \ ObjectSize
            Loop
            'Get the Ray Distance:
            VertDist = Math.Abs((player.PosX - VertX) / Math.Cos(RayRadians))

            'Get the nearst Ray:
            Dim clr As Pen
            If VertDist < HorizDist Then
                WallDistance = VertDist
                OffSetGrid = VertY Mod ObjectSize
                clr = Pens.Blue
            Else
                OffSetGrid = HorizX Mod ObjectSize
                WallDistance = HorizDist
                clr = Pens.DarkBlue
            End If
            'Draw the nearst Ray(4 is the circle\player center):
            'imgverticallineGraphics.DrawLine(Pens.Blue, New Point(player.PosX + 4, player.PosY + 4), New Point(RayX, RayY))

            'Avoiding the Fish Effect:
            WallDistance = WallDistance * Math.Cos(RayRadians - player.Radians)

            'Calculate the vertical line Height:
            RayHeight = (ObjectSize / WallDistance) * 200

            'Get the texture vertical line:
            'If (OffSetGrid < 0 Or OffSetGrid >= picWall1.Width) Then OffSetGrid = 0
            'picWall1.DrawTextureVerticalLine(A.MemoryHDC, OffSetGrid, Fix(RayHeight * 4), RayCounts, 5)

            'draw a vertical line:
            imgverticallineGraphics.DrawLine(clr, New Point(RayCounts, 300 / 2 - RayHeight / 2), New Point(RayCounts, 300 / 2 + RayHeight / 2))
            RayCounts = RayCounts + 1
            RayRadians = RayRadians + RadiansSteps
        Loop

    End Sub

how can i avoid the vertical bar render?(blue and not blue dark)

Advertisement

@cambalinho , programming is not Game Design. The Game Design forum is for game design discussions only. What is game design? Your post has been moved to a more appropriate forum.

-- Tom Sloper -- sloperama.com

thank you so much for all…
lets see if i can get help 😉

cambalinho said:
lets see if i can get help

Probably not.
I have not used Basic since C64, but trying to understand your code anyway, i fail because idk how you define the level. I would expect something like BSP tree or DDA in a uniform grid, but seems neither?

honestly, i only showed the RayCasting function and you see that i can create the level normaly… only we notice that vertical bar with a different color 😉

I guess the bug is something like missing or skipping an intersection with the level, thus the question about the level data.

Assuming you use a regular grid, where some cells are solid and others are empty, DDA is usually used to find intersections of a ray with grid edges in front to back order.

Here is a tutorial: https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-acceleration-structure/grid.html

Unfortunately it only cares about intersections but not which cell is behind the edge along the ray, so some extra logic is needed.

It looks like you do just that, but maybe comparing code helps to find the bug.

EDIT: I just see they show a second code example giving the cell indices as well, so it should help.

This topic is closed to new replies.

Advertisement