Ir ao conteúdo
  • Cadastre-se

Visual Basic Raycasting: como calcular o tamanho da linha vertical?


Posts recomendados

ao desenhar o raio, obtenho o comprimento do raio...
ao saber o comprimento do raio, como calculo a altura da linha? como posso evitar o efeito de peixe?
 

 Dim RayAngle As Double
    Do While (RayWay < RayCount)
        RayAngle = StartRadians + (RaySteps * RayWay)
        RayWidth = A.DrawLineWithAngleAndLength(Int(Player.PosX), Int(Player.PosY), RayAngle, 300, LevelMap0(), 33)
        
        
        lineHeight = 200 / RayWidth * 2
        drawStart = -lineHeight / 2 + 200 / 2
        If drawStart < 0 Then drawStart = 0
        drawEnd = lineHeight / 2 + 200 / 2
        If drawEnd >= 200 Then drawEnd = 200 - 1
        Me.Line (A.Width + RayWay, drawStart)-(A.Width + RayWay, drawEnd), vbWhite
        RayWay = RayWay + 1
    Loop

 

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

eis o código todo mesmo...
não esquecer de mudar o nome do ficheiro no form_load().
 

Public Function BresenhamLine(X0 As Long, Y0 As Long, X1 As Long, Y1 As Long, ByRef Map() As Long, ObjectSize As Long, angle_rad As Double) As Long
   
    Dim dx As Long
    Dim dy As Long
    Dim steps As Double
    Dim Xincrement As Double
    Dim Yincrement As Double
    Dim x As Double
    Dim y As Double
    Dim MapX As Integer
    Dim MapY As Integer
    Dim LineWidth As Long
    x = X0
    y = Y0
    dx = X1 - X0
    dy = Y1 - Y0
    LineWidth = 0
    If (Abs(dx) > Abs(dy)) Then
        steps = Abs(dx)
    Else
        steps = Abs(dy)
    End If
    Xincrement = dx / (steps)
    Yincrement = dy / (steps)
    Dim v As Integer
    For v = 0 To steps
    
       x = x + Xincrement
       y = y + Yincrement
       MapX = Int(x / ObjectSize)
       MapY = Int(y / ObjectSize)
       LineWidth = LineWidth + 1
       If (Map(MapY, MapX) = vbBlue) Then
             Exit For
        End If
    Next v
    ForeColor vbRed
    DrawLine X0, Y0, Int(x), Int(y)
    LineWidth = LineWidth / Cos(angle_rad)

    BresenhamLine = LineWidth
End Function

Public Function DrawLineWithAngleAndLength(X1 As Long, Y1 As Long, angle_rad As Double, Length As Long, Map() As Long, ObjectSize As Long) As Long
   
    ' Calcular as coordenadas finais da linha
    Dim X2 As Long
    Dim Y2 As Long
    X2 = X1 + Length * Cos(angle_rad)
    Y2 = Y1 + Length * Sin(angle_rad)
    
    ' Chame a função BresenhamLine com as coordenadas finais
    DrawLineWithAngleAndLength = BresenhamLine(X1, Y1, X2, Y2, Map(), ObjectSize, angle_rad)
End Function



Private Sub DrawRays(StartRadians As Double, EndRadians As Double, VisionRadians As Double, ScreenWidth As Long, Optional Precision As Long = 1)
    Dim RayCount As Long
    Dim RaySteps As Double
    Dim RayWay As Long
    Dim RayWidth As Long
    Dim RayAngle As Double
    Dim RayHeight As Double
    
    'number of rays:
    RayCount = ScreenWidth / CLng(VisionRadians) * Precision
    
    'getting increment ray:
    RaySteps = (EndRadians - StartRadians) / CDbl(RayCount)
    Do While (RayWay < RayCount)
        'calcule the ray angle\radians:
        RayAngle = StartRadians + (RaySteps * RayWay)
        
        'draw ray and get ray width:
        RayWidth = A.DrawLineWithAngleAndLength(Int(Player.PosX), Int(Player.PosY), RayAngle, 300, LevelMap0(), 33)
        RayHeight = 66 / RayWidth * ScreenWidth / 2
        'Debug.Print RayHeight
        A.ForeColor vbBlue
        A.DrawLine 475 + 50 + RayWay, 200 / 2 - RayHeight / 2, 475 + 50 + RayWay, 200 / 2 + RayHeight / 2
        RayWay = RayWay + 1
    Loop
    
End Sub

 

RayCasting3.7z

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

finalmente consegui resultados mais corretos:
 

Public Function BresenhamLine(X0 As Long, Y0 As Long, X1 As Long, Y1 As Long, ByRef Map() As Long, ObjectSize As Long, angle_rad As Double) As Long
   
    Dim dx As Long
    Dim dy As Long
    Dim steps As Double
    Dim Xincrement As Double
    Dim Yincrement As Double
    Dim x As Double
    Dim y As Double
    Dim MapX As Integer
    Dim MapY As Integer
    Dim LineWidth As Long
    x = X0
    y = Y0
    dx = X1 - X0
    dy = Y1 - Y0
    LineWidth = 0
    If (Abs(dx) > Abs(dy)) Then
        steps = Abs(dx)
    Else
        steps = Abs(dy)
    End If
    Xincrement = dx / (steps)
    Yincrement = dy / (steps)
    Dim v As Integer
    For v = 0 To steps
    
       x = x + Xincrement
       y = y + Yincrement
       MapX = Int(x / ObjectSize)
       MapY = Int(y / ObjectSize)
       LineWidth = LineWidth + 1
       If (Map(MapY, MapX) = vbBlue) Then
             Exit For
        End If
    Next v
    ForeColor vbRed
    DrawLine X0, Y0, Int(x), Int(y)
    'Calculate the Distance between Origin and Destination line:
    'CatetoAdjacente=(x - X0)
    'CatetoOposto=(y - Y0)
    'Hip = RaizQuadrada(CatetoAdjacente ^ 2 + CatetoOposto ^ 2)
    LineWidth = Sqr((x - X0) * (x - X0) + (y - Y0) * (y - Y0))
    BresenhamLine = LineWidth
End Function

Public Function DrawLineWithAngleAndLength(X1 As Long, Y1 As Long, angle_rad As Double, Length As Long, Map() As Long, ObjectSize As Long) As Long
   
    ' Calcular as coordenadas finais da linha
    Dim X2 As Long
    Dim Y2 As Long
    X2 = X1 + Length * Cos(angle_rad)
    Y2 = Y1 + Length * Sin(angle_rad)
    
    ' Chame a função BresenhamLine com as coordenadas finais
    DrawLineWithAngleAndLength = BresenhamLine(X1, Y1, X2, Y2, Map(), ObjectSize, angle_rad)
End Function

 

Private Sub DrawRays(StartRadians As Double, EndRadians As Double, VisionRadians As Double, ScreenWidth As Long, Optional Precision As Long = 1)
    Dim RayCount As Long
    Dim RaySteps As Double
    Dim RayWay As Long
    Dim RayWidth As Long
    Dim RayAngle As Double
    Dim RayHeight As Double
    
    'number of rays:
    RayCount = ScreenWidth / CLng(VisionRadians) * Precision
    
    'getting increment ray:
    RaySteps = (EndRadians - StartRadians) / CDbl(RayCount)
    Do While (RayWay < RayCount)
        'calcule the ray angle\radians:
        RayAngle = StartRadians + (RaySteps * RayWay)
        
        'draw ray and get ray width:
        RayWidth = A.DrawLineWithAngleAndLength(Int(Player.PosX), Int(Player.PosY), RayAngle, 300, LevelMap0(), 33)
        RayHeight = 66 / RayWidth * ScreenWidth
        A.ForeColor vbBlue
        A.DrawLine 475 + 50 + RayWay, 200 / 2 - RayHeight / 2, 475 + 50 + RayWay, 200 / 2 + RayHeight / 2
        RayWay = RayWay + 1
    Loop
    
End Sub

image.thumb.png.9018ff9e2fb6559ac641a1f18a0303b7.png

eu sei que os cálculos estão corretos, porque agora obtenho resultados esperados...
eis como obtenho a altura de linha:

'draw ray and get ray width:
        RayWidth = A.DrawLineWithAngleAndLength(Int(Player.PosX), Int(Player.PosY), RayAngle, 300, LevelMap0(), 33)
        RayHeight = 66 / RayWidth * ScreenWidth

a partir daqui, como evito o Efeito de Peixe?
demorei imenso chegar aqui... ao menos aprendi 😉
mas usei pixel a pixel e não o triangulo para percorrer a linha... sim é mais lento.... mas agora quero corrigir o Efeito de Peixe 😉

  • Obrigado 2
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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!