A lot of issues with a raycaster

Viewed 9

I have been working on a raycaster for school based off Lodev's texture free example (search up Lodev raycaster on most search engines and it should come up) and I am struggling with a couple major issues.

  1. I can't change the resolution variables, it makes no difference to how it gets drawn out
  2. While I haven't finished writing out the controls what I have already done should be capable of moving the player back and forth a bit
  3. the fps counter I can't get working
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        'It seems that in order for the windows form to even load
        'I have to I need to have everything run on a second thread, this is very annoying
        'I have had less trouble with ininite loops on C than I have on VB.net 
        'Initial setup of variables
        'Labeltest()
        ScreenWidth = 640
        ScreenHeight = 480

        MapWidth = 24
        MapWidth = 24

        Do
            'Label1.Text = "Wow the code actually ran this far!"
            For X = 0 To ScreenWidth 'fix this later
                'I assume the "w" on lodev's website is simply
                'a stand in for "Width" As in screen width
                'Label1.Text = "Wow the code actually ran this far!"
                Dim CameraX As Double = 2 * X / Convert.ToDouble(ScreenWidth) - 1
                Dim RayDirX As Double = DirX + PlaneX * CameraX
                Dim RayDirY As Double = DirY + PlaneY * CameraX
                'What box of the map the player is in
                Dim MapX As Int16 = Convert.ToInt16(PosX)
                'I'm trying out possible optimisations
                'I'm considering making all integers 16 bit
                Dim MapY As Int16 = Convert.ToInt16(PosY)
                Dim SideDistX As Double
                Dim SideDistY As Double
                Dim PerpWallDist As Double
                Dim StepX As Int16 'what direction to step in?
                Dim StepY As Int16 'Either + or -1
                Dim Hit As Int16 = 0 'Wall hit?
                Dim Side As Int16 'Was a North-South or East-West wall hit?
                Dim DeltaDistX As Double = Math.Sqrt(1 + (RayDirY * RayDirY) / (RayDirX * RayDirX))
                Dim DeltaDistY As Double = Math.Sqrt(1 + (RayDirX * RayDirX) / (RayDirY * RayDirY))
                'RayDir is the length of the vector (RayDirX, RayDirY)
                If RayDirX < 0 Then
                    StepX = -1
                    SideDistX = (PosX - MapX) * DeltaDistX
                ElseIf RayDirX > 0 Or RayDirX = 0 Then
                    StepX = 1
                    SideDistX = (MapX + 1.0 - PosX) * DeltaDistX
                End If

                If RayDirY < 0 Then
                    StepY = -1
                    SideDistY = (PosY - MapY) * DeltaDistY
                ElseIf RayDirY > 0 Or RayDirY = 0 Then
                    StepY = 1
                    SideDistY = (MapY + 1.0 - PosY) * DeltaDistY
                End If
                'It is now time to perform DDA (I believe stands for Digital Differential Analyzer)
                While Hit = 0
                    'Label1.Text = "Wow the code actually ran this far!"
                    'DDA is a way of reducing the amount of calculations needed
                    'for a raycaster down by a lot
                    'Without DDA it could theoretically take infinite calculations
                    'as is my understanding, DDA works by if a block in the map is "0" it doesn't
                    'keep checking smaller parts of the block it skips to the next one
                    If SideDistX < SideDistY Then
                        SideDistX += DeltaDistX
                        MapX += StepX
                        Side = 0
                    ElseIf SideDistX > SideDistY Or SideDistX = SideDistY Then
                        SideDistY += DeltaDistY
                        MapY += StepY
                        Side = 1
                    End If
                    If WorldMap(MapX, MapY) > 0 Then
                        Hit = 1
                    End If
                End While
                'Once thats done we know which wall our ray has hit
                'Label1.Text = "Wow the code actually ran this far!"
                If Side = 0 Then
                    PerpWallDist = SideDistX - DeltaDistX
                ElseIf Side = 1 Then
                    PerpWallDist = SideDistY - DeltaDistY
                End If
                '480 is the test screen height
                Dim LineHeight As Int16 = Int(ScreenHeight / PerpWallDist) 'ScreenHeight /
                Dim DrawStart = (-LineHeight / 2) + ScreenHeight / 2
                If DrawStart < 0 Then
                    DrawStart = 0
                End If
                Dim DrawEnd As Int16 = LineHeight / 2 + ScreenHeight / 2
                If DrawEnd > ScreenHeight Or DrawEnd = ScreenHeight Then
                    DrawEnd = DrawEnd - 1
                End If
                'choosing wall colour I guess
                Dim ColourRGB As Color
                Select Case WorldMap(MapX, MapY)
                    'was considering alpha values but decided against it
                    Case 1
                        ColourRGB = Color.Gray
                    Case 2
                        ColourRGB = Color.Red
                    Case 3
                        ColourRGB = Color.Blue
                    Case 4
                        ColourRGB = Color.DarkMagenta
                    Case Else
                        ColourRGB = Color.Yellow
                End Select
                If Side = 1 Then
                    ColourRGB = Color.FromArgb(ColourRGB.R / 2, ColourRGB.G / 2, ColourRGB.B / 2)
                    'had quite a bit of trouble figuring this out
                End If
                ThePen = New Pen(ColourRGB, 1)
                RayGraphics.DrawLine(ThePen, X, CInt(DrawStart), X, DrawEnd)
                ThePen.Dispose() 'This seems to reduce memory usage by quite a bit. So thats good
                MoveSpeed = 20.0
                RotSpeed = 60.0
                OldTime = Time
                Time = inbetweentime
                Dim FrameTime As Double = (Time - OldTime) / 1000.0
                FPS = (1.0 / Time)
                'While testing methods of erasing the screen I found a great way
                'to demonstrate how raycasting works
                'If you wish to demonstrate this uncomment the code below
                'ThePen = New Pen(Color.Black, 999)
                'RayGraphics.DrawLine(ThePen, 0, 0, ScreenWidth, ScreenHeight)
                'Threading.Thread.Sleep(300)
            Next
        Loop
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Label1.Text = "Frame:" & FPS
        inbetweentime += 1
    End Sub

    Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode = Keys.Up Then 'move forward if no wall is in front of you
            If Not WorldMap(Int(PosX + DirX * MoveSpeed), Int(PosY)) Then
                PosX += DirX * MoveSpeed
            End If
            'Label2.Text = "ok cool this works!"
            If Not WorldMap(Int(PosX), Int(PosY + DirY * MoveSpeed)) Then
                PosY += DirY * MoveSpeed
            End If
        End If

        If e.KeyCode = Keys.Up Then 'move forward if no wall behind you

            If WorldMap(Int(PosX - DirX * MoveSpeed), Int(PosY)) = False Then
                PosX -= DirX * MoveSpeed
            End If

        End If










        If e.KeyCode = Keys.Escape Then
            Application.Exit()
        End If
    End Sub
End Class

Apologies for the poor formatting of the code, also I could not get all of the code into this post but this is the stuff that is the most relevant anyways. Also ignore the comments many of them are relevant to bits of code that no longer exist or were moved elsewhere, I do plan to fix this before I submit it to my teacher.

0 Answers
Related