Ir ao conteúdo
  • Cadastre-se

Visual Basic VB2010: como resolver 1 linha vertical em Raycasting?


Posts recomendados

em Visual Basic 2010, tenho esta função para fazer o RayCasting:

Function GetPositionMap(ByVal valor As Double) As Integer
        If valor < 0 Then
            GetPositionMap = 0
        ElseIf valor > MapWidth Then
            GetPositionMap = 9
        Else
            GetPositionMap = valor \ ObjectSize 'square size
        End If
    End 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
        Dim OffSetGrid As Long

        RayCount = imgverticalline.Width

        MapX = Player.MapX
        MapY = Player.MapY
        RadiansSteps = Radian60 / RayCount

        RayRadians = (Player.Radians - Radian30)
        RayCounts = 0
        img.ForeColor(RGB(255, 0, 0))
        Do While RayCounts < RayCount
            If (RayRadians > Radian360) Then RayRadians = 0.001
            'Check for horizontal intersections:

            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)

            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

            HorizDist = Math.Abs((player.PosX - HorizX) / Math.Cos(RayRadians))

            'Check for vertical intersections:
            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)
            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
            VertDist = Math.Abs((player.PosX - VertX) / Math.Cos(RayRadians))
            Dim VertColor As Color
            If VertDist < HorizDist Then
                WallDistance = VertDist
                OffSetGrid = VertY Mod ObjectSize
                VertColor = Color.Blue

            Else
                OffSetGrid = HorizX Mod ObjectSize
                WallDistance = HorizDist
                VertColor = Color.DarkBlue
            End If
            WallDistance = WallDistance * Math.Cos(RayRadians - player.Radians) 'avoiding the Fish Effect
            RayHeight = (ObjectSize / WallDistance) * 200 ' is the height screen\
            'If (OffSetGrid < 0 Or OffSetGrid >= picWall1.Width) Then OffSetGrid = 0
            'picWall1.DrawTextureVerticalLine(img.MemoryHDC, OffSetGrid, Fix(RayHeight * 4), RayCounts, 5)

            imgverticalline.ForeColor(RGB(VertColor.R, VertColor.G, VertColor.B))
            imgverticalline.DrawLine(RayCounts, imgverticalline.Height / 2 - RayHeight \ 2, RayCounts, imgverticalline.Height / 2 + RayHeight \ 2)
            RayRadians = RayRadians + RadiansSteps
            RayCounts = RayCounts + 1
        Loop

    End Sub

 

eis o resultado:

image.thumb.png.d7c1b1d75388626395526ce9a2a492ef.png

 

sim ainda não estou a usar  textura, porque quero resolver esse bug gráfico: na parede da esquerda(azul escuro) temos 1 linha vertical(azul claro) de 32 em 32(o tamanho de 1 parte da parede).... nem sei onde escontrar e corrigir este bug gráfico... alguém me pode auxiliar?
PS: eu ainda não avaliei o tempo exato, mas gostava de perguntar: cada vez que limpo a imagem, crio 1 brush e seleciono, e sempre que desenho 1 linha\figura, crio e seleciono 1 pen.... se criar os brush's e as pen's e só as selecionar, quando preciso, ganho tempo?(falando em ciclos\loops) se sim, como posso guardar e usar a pen\brush antiga ou a posso ignorar?(sim ainda estou a pensar antes deste grande update)

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

eu estou a tentar resolver da seguinte forma:
- gravo os valores X e Y do final da linha(e também da linha anterior), porque notei que podem ser iguais:
 

Dim PreviousRayX As Double = 0
        Dim PreviousRayY As Double = 0
        Dim RayX As Double = 0
        Dim RayY As Double = 0
'........
Dim clr As Pen
            If VertDist < HorizDist Then
                WallDistance = VertDist
                OffSetGrid = VertY Mod ObjectSize
                clr = Pens.Blue
                RayX = Math.Round(VertX)
                RayY = Math.Round(VertY)
            Else
                OffSetGrid = HorizX Mod ObjectSize
                WallDistance = HorizDist
                clr = Pens.BlueViolet
                RayX = Math.Round(HorizX)
                RayY = Math.Round(HorizY)
            End If
            'imgverticallineGraphics.DrawLine(Pens.Blue, New Point(player.PosX + 4, player.PosY + 4), New Point(RayX, RayY))
  WallDistance = WallDistance * Math.Cos(RayRadians - player.Radians) 'avoiding the Fish Effect
            RayHeight = (ObjectSize / WallDistance) * 200 ' is the height screen

- agora testo se os valores são diferentes... se forem diferentes desenhasse a linha vertical e soma-se o X seguinte e guardasse os valores finais da linha:

If (PreviousRayX <> Math.Round(RayX) And PreviousRayY <> Math.Round(RayY) And OffSetGrid <> 0 And OffSetGrid <> ObjectSize) Then
                imgverticallineGraphics.DrawLine(clr, New Point(RayCounts, 300 / 2 - RayHeight / 2), New Point(RayCounts, 300 / 2 + RayHeight / 2))
                PreviousRayX = Math.Round(RayX)
                PreviousRayY = Math.Round(RayY)
                RayCounts = RayCounts + 1
            End If
            
            RayRadians = RayRadians + RadiansSteps 'sim mantem-se, porque esta é a rotação da linha

mas estou a obter resultados inesperados: https://imgur.com/nxEbAu3
o meu objetivo é evitar as linhas que tenham finais iguais á anterior(o RayX e RayY e PreviousRayX e PreviousRayY).
o que estou a fazer erradado?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!