Ir ao conteúdo

Cambalinho

Membro Pleno
  • Posts

    902
  • Cadastrado em

  • Última visita

posts postados por Cambalinho

  1. eu tenho este código\função, sim VB6, para implementar o RayCasting:

    Private Sub RayCasting()
        Dim HorizontalRay As Ray
        Dim VerticalRay As Ray
        Dim RayHitX As Double
        Dim RayHitY As Double
        Dim DirX As Double
        Dim DirY As Double
        Dim MapX As Integer
        Dim MapY As Integer
        Dim HitWall As Long
        Dim RayAngleStep As Double
        Dim RayCount As Long
        Dim RayAngle As Double
        Dim HorDist As Double
        Dim VertDist As Double
        Dim VertTested As Boolean
        Dim HorizTested As Boolean
        
        On Error Resume Next
        VertTested = False
        HorizTested = False
        RayAngleStep = (PI / 3) / 320
        RayAngle = Player1.RotationRadian - (PI / 3 / 2)
        GameBitmap.ForeColor vbGreen
        For RayCount = 0 To 320
        
            ' Calcular a direção com base na rotação do jogador:
            DirX = Cos(-RayAngle)
            DirY = Sin(-RayAngle)
        
            ' Calcular Interceção Horizontal:
            If (DirY >= 0 And DirY <= PI) Then ' Se o jogador está olhando para cima
                HorizontalRay.PosY = Fix(Player1.PosY / WallSize) * WallSize - 1
                ' Calcular o passo Y e X para os raycast:
                HorizontalRay.StepY = -WallSize
                HorizontalRay.StepX = WallSize / Tan(-RayAngle)
            Else ' Se o jogador está olhando para baixo
                HorizontalRay.PosY = Fix(Player1.PosY / WallSize) * WallSize + WallSize
                ' Calcular o passo Y e X para os raycast
                HorizontalRay.StepY = WallSize
                HorizontalRay.StepX = WallSize / Tan(RayAngle)
                
            End If
            HorizontalRay.PosX = Player1.PosX + (Player1.PosY - HorizontalRay.PosY) / Tan(-RayAngle)
            
            ' Calcular Interceção Vertical:
            If (DirX <= (PI / 2) And DirX <= (3 * PI / 2)) Then ' Olhando para a direita
                VerticalRay.PosX = Fix(Player1.PosX / WallSize) * WallSize + WallSize
                VerticalRay.StepX = WallSize ' mover para direita
                VerticalRay.StepY = VerticalRay.StepX * Tan(RayAngle)
            ElseIf (DirX > (PI / 2) And DirX > (3 * PI / 2)) Then ' Olhando para a esquerda
                VerticalRay.PosX = Fix(Player1.PosX / WallSize) * WallSize - 1 ' Ajuste para o pixel anterior da parede
                VerticalRay.StepX = -WallSize ' mover para esquerda
                VerticalRay.StepY = VerticalRay.StepX * Tan(-RayAngle)
            End If
            
            ' Calcular o Y de acordo com a inclinação do raio
            VerticalRay.PosY = Player1.PosY + (Player1.PosX - VerticalRay.PosX) * Tan(-RayAngle)
           
            'Testar a colisão nas paredes:
            Do
                'Interceção Horizontal:
                'Testar se está fora do mapa:
                If (HorizontalRay.PosX < 0) Or (HorizontalRay.PosX > (10 * WallSize)) Or (HorizontalRay.PosY < 0) Or (HorizontalRay.PosY > (10 * WallSize)) Then
                    'Exit Do
                End If
                'Testar se o bloco é 1 parede:
                MapX = Fix(HorizontalRay.PosX / WallSize)
                MapY = Fix(HorizontalRay.PosY / WallSize)
                HitWall = Level1(MapY, MapX)
                If (HitWall = vbBlack) Then
                    
                Else
                    'se não for parede soma para a próxima interseção:
                    HorizontalRay.PosX = HorizontalRay.PosX + HorizontalRay.StepX
                    HorizontalRay.PosY = HorizontalRay.PosY + HorizontalRay.StepY
                End If
                
                          
                'Interceção Vertical:
                'Testar se está fora do mapa:
                If (VerticalRay.PosX < 0) Or (VerticalRay.PosX > (10 * WallSize)) Or (VerticalRay.PosY < 0) Or (VerticalRay.PosY > (10 * WallSize)) Then
                    'Exit Do
                End If
                'Testar se o bloco é 1 parede:
                MapX = Fix(VerticalRay.PosX / WallSize)
                MapY = Fix(VerticalRay.PosY / WallSize)
                HitWall = Level1(MapY, MapX)
                If (HitWall = vbBlack) Then
                    Exit Do
                Else
                    'se não for parede soma para a próxima interseção:
                    VerticalRay.PosX = VerticalRay.PosX + VerticalRay.StepX
                    VerticalRay.PosY = VerticalRay.PosY + VerticalRay.StepY
                End If
                
            Loop
            
            'Obter o comprimento do raio:
            HorDist = Sqr(Square(HorizontalRay.PosX) + Square(HorizontalRay.PosY))
            VertDist = Sqr(Square(VerticalRay.PosX) + Square(VerticalRay.PosY))
            
            'Confirmar qual é o raio mais pequeno:
            If (HorDist < VertDist) Then
                RayHitX = HorizontalRay.PosX
                RayHitY = HorizontalRay.PosY
            Else
                RayHitX = VerticalRay.PosX
                RayHitY = VerticalRay.PosY
            End If
            
            'Desenhar o raio pequeno:
            GameBitmap.DrawLine Fix(Player1.PosX), Fix(Player1.PosY), Fix(RayHitX), Fix(RayHitY)
            
      'eu acredito que tenho 1 erro aqui:
            'Aumentar o ângulo\radiano do raio:
            RayAngle = RayAngle + RayAngleStep
            'se o radiano for super que 360 ou (2*PI) ou inferior que -360 ou (-2*PI)
            If (RayAngle <= (-2 * PI)) Then RayAngle = 0
            If (RayAngle >= (2 * PI)) Then RayAngle = (-2 * PI)
        Next
        
        GameBitmap.ForeColor vbBlack
    End Sub

    ainda tenho alguns erros de cálculo, porque alguns radianos\ângulos podem ficar em espelho 😞
    e agora a rotação:

     

    Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
        
        If (KeyCode = vbKeyEscape) Then
            FreeResources
        ElseIf (KeyCode = vbKeyLeft) Then
            Player1.RotationRadian = Player1.RotationRadian - 0.1
            playercos = Cos(Player1.RotationRadian)
            playersin = Sin(Player1.RotationRadian)
            If (Player1.RotationRadian >= 2 * PI) Then Player1.RotationRadian = 0
            If (Player1.RotationRadian <= -2 * PI) Then Player1.RotationRadian = 0
            If (Player1.RotationRadian > 0) Then Player1.RotationRadian = -2 * PI
            Me.Caption = "Rotation degrees: " & CStr(ConvertRadiansToDegrees(Player1.RotationRadian))
        ElseIf (KeyCode = vbKeyRight) Then
            Player1.RotationRadian = Player1.RotationRadian + 0.1
            playercos = Cos(Player1.RotationRadian)
            playersin = Sin(Player1.RotationRadian)
            If (Player1.RotationRadian >= 2 * PI) Then Player1.RotationRadian = 0
            If (Player1.RotationRadian <= -2 * PI) Then Player1.RotationRadian = 0
            If (Player1.RotationRadian > 0) Then Player1.RotationRadian = -2 * PI
            Me.Caption = "Rotation degrees: " & CStr(ConvertRadiansToDegrees(Player1.RotationRadian))
        ElseIf (KeyCode = vbKeyUp) Then
            Player1.PosY = Player1.PosY + playersin
            Player1.PosX = Player1.PosX + playercos
        ElseIf (KeyCode = vbKeyDown) Then
            Player1.PosY = Player1.PosY - playersin
            Player1.PosX = Player1.PosX - playercos
        End If
        
    End Sub

    eu penso que o meu problema é quando o radiano, do player é zero, tenho de diminuir  30º... porque a visão é 60º... alguém me pode explicar melhor o meu erro?
     

    • Amei 1
  2. 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
  3. ainda bem que testou  o código.. tenho 1DLL criada no VB6, com funções API, e consigo o dobro 😉
    mas penso conseguir mais desempenho(sempre que altero o Forecolor e FillColor, o brush e a pen são recriados e selecionados... estou a pensar mudar isso e usar variáveis para pen e brush... assim só crio 1 vez.. apenas estou confuso devido ao brush\pen de origem ou anterior... deveria o guardar ou ignorar?)
    agora tenho outro problema, por isso ontem criei o topico... queria resolver 1 bug gráfico 😞

    • Curtir 1
  4. 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
  5. em VB2010, como posso fazer 1 game loop e timers com precisão?

     o máximo que consigo é 100FPS e só desenhar 2 circulos preenchido com 1 cor 😞

    
    Public Class Form1
    
        Dim blnGameloop As Boolean = True
        Dim FrameCount As Integer
        Dim FPS As Integer
    
        Dim result As New Bitmap(900, 500)
        Dim gresult As Graphics = Graphics.FromImage(result)
        Dim g As Graphics
        Dim tmr As Integer
    
        Dim PosX As Integer
        Dim PosY As Integer
    
        Private Sub ClearMemory()
            blnGameloop = False
            result.Dispose()
            g.Dispose()
            gresult.Dispose()
            End
        End Sub
    
        Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
            ClearMemory()
    
        End Sub
    
        Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
            If (e.KeyCode = Keys.Escape) Then
                ClearMemory()
            ElseIf (e.KeyCode = Keys.Up) Then
                PosY -= 1
            ElseIf (e.KeyCode = Keys.Down) Then
                PosY += 1
            ElseIf (e.KeyCode = Keys.Left) Then
                PosX -= 1
            ElseIf (e.KeyCode = Keys.Right) Then
                PosX += 1
            End If
        End Sub
    
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.Show()
            Me.Focus()
            tmr = TimeOfDay.Second
            Do
    
                Application.DoEvents()
    
                g = Me.CreateGraphics
                gresult.FillRectangle(Brushes.Blue, 0, 0, Me.Width, Me.Height)
                gresult.FillEllipse(Brushes.Aqua, PosX, PosY, 100, 100)
                gresult.FillEllipse(Brushes.Brown, PosX + 50, PosY + 50, 100, 100)
                gresult.DrawString("FPS: " & CStr(FPS), Me.Font, Brushes.Black, 10, 10)
                g.DrawImage(result, 0, 0)
                FrameCount += 1
                If (tmr <> TimeOfDay.Second) Then
                    FPS = FrameCount
                    FrameCount = 0
                    tmr = TimeOfDay.Second
                End If
    
            Loop While (blnGameloop = True)
        End Sub
    
    End Class

    parecem 2 tópicos, mas 1 depende do outro

    • Curtir 1
  6. eis o código para desenhar 1 linha:
     

    WallDistance = WallDistance * Cos(RayRadians - Player.Radians) 'avoiding the Fish Effect
            RayHeight = (ObjectSize / WallDistance) * 200 ' is the height screen\
            a.drawline(x0,y0,x1,y1) A.DrawLine 475 + 50 + RayCounts, 200 / 2 - RayHeight / 2, 475 + 50 + RayCounts, 200 / 2 + RayHeight / 2

    a linha vertical aparece sem problemas... agora queria mostrar com textura:
     

    'obter o a linha mais curta(horizontal ou vertical):
            If VertDist < HorizDist Then
                ' Draw the vertical ray:
                A.DrawLine Fix(Player.PosX), Fix(Player.PosY), Fix(VertX), Fix(VertY)
                WallDistance = VertDist
                GridX = VertX Mod ObjectSize
                GridY = VertY Mod ObjectSize
            Else
                ' Draw the horizontal ray:
                A.DrawLine Fix(Player.PosX), Fix(Player.PosY), Fix(HorizX), Fix(HorizY)
                
                WallDistance = HorizDist
                
                GridX = HorizX Mod ObjectSize
                GridY = HorizY Mod ObjectSize
            End If
            'Debug.Print GridX & "  " & GridY
            WallDistance = WallDistance * Cos(RayRadians - Player.Radians) 'avoiding the Fish Effect
            RayHeight = (ObjectSize / WallDistance) * 200 ' is the height screen\
            'a.drawline(x0,y0,x1,y1) A.DrawLine 475 + 50 + RayCounts, 200 / 2 - RayHeight / 2, 475 + 50 + RayCounts, 200 / 2 + RayHeight / 2
            If (GridX = 0) Then
                StretchBlt A.MemoryHDC, 475 + 50 + RayCounts, 200 / 2 - RayHeight / 2, 475 + 50 + RayCounts, 200 / 2 + RayHeight / 2, picWall1.hdc, 0, GridY, 1, picWall1.Height, SRCCOPY
            Else
                StretchBlt A.MemoryHDC, 475 + 50 + RayCounts, 200 / 2 - RayHeight / 2, 475 + 50 + RayCounts, 200 / 2 + RayHeight / 2, picWall1.hdc, GridX, 0, picWall1.Width, 1, SRCCOPY
            End If

    mas não desenha nada de jeito 😞
    os calculos podem estar errados sem me aparecer:
    image.thumb.png.a764846cb86737491015dabf4bda3175.png

    onde errei para obter a linha da imagem?

    • Curtir 1
  7. veja este 'if':
     

    If ((MapX <= 9 Or MapX >= 0 Or MapY <= 9 Or MapY >= 0) Or (LevelMap0(MapY, MapX) <> vbBlue)) Then

    o objetivo  é evitar que o 'MapX' e 'MapY' sejam inferiores a zero e superiores a 9.... e depois verificar no array LevelMap0() seja 'Blue'...
    eu uso o 'on Error Resume Next', mas quero evitar isso.... o que tenho de errado neste 'if'?
    parece simples, mas estava-me a fazer muita confusão, porque obtenho 1 erro de index do array("out of range") 😞

    • Curtir 1
  8. vejam este print errado 😞
    eis o código actual:
      

    Private Sub DrawRays2()
        Dim AY As Double
        Dim AX As Double
        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
        
        MapX = Player.MapX
        MapY = Player.MapY
        On Error Resume Next
        
    '    'Check for horizontal intersections:
        If ((Player.Radians > 0 And Player.Radians < PI)) Then 'Facing down
            AY = (Int(Player.PosY / ObjectSize) * ObjectSize) + ObjectSize ' Calculate grid position
            AX = Player.PosX + (AY - Player.PosY) / Tan(Player.Radians)
            StepY = ObjectSize
        ElseIf ((Player.Radians = 0 And Player.Radians = PI)) Then
            AY = Player.PosY
            AX = Player.PosX
        Else 'Facing Up
            AY = (Int(Player.PosY / ObjectSize) * ObjectSize) - 1
            AX = Player.PosX + (AY - Player.PosY) / Tan(Player.Radians)
            StepY = -ObjectSize
        End If
    
        
        HorizX = AX
        HorizY = AY
        StepX = StepY / Tan(Player.Radians)
        MapX = Fix((HorizX) / ObjectSize)
        MapY = Fix((HorizY) / ObjectSize)
        A.SetPixel (Fix(HorizX)), (Fix(HorizY)), ColorConstants.vbCyan
        If LevelMap0(MapY, MapX) <> vbBlue Then
    
            Do
    
                HorizX = HorizX + StepX
                HorizY = HorizY + StepY
    
                MapX = Fix((HorizX) / ObjectSize)
                MapY = Fix((HorizY) / ObjectSize)
                A.SetPixel (Fix(HorizX)), (Fix(HorizY)), ColorConstants.vbCyan
                If LevelMap0(MapY, MapX) = vbBlue Then
                    Exit Do
                End If
                DoEvents
            Loop
        End If
    
    
        HorizDist = Sqr(((HorizX - Player.PosX) * (HorizX - Player.PosX)) + ((HorizY - Player.PosY) * (HorizY - Player.PosY)))
        
        
        'Check for vertical intersections:
        If ((Player.Radians < PI / 2 Or Player.Radians > 3 * PI / 2)) Then 'Facing right
            AX = (Int(Player.PosX / ObjectSize) * ObjectSize) + ObjectSize ' Calculate grid position
            AY = Player.PosY + (Player.PosX - AX) * -Tan(Player.Radians)
            StepX = ObjectSize
        ElseIf ((Player.Radians = PI / 2 Or Player.Radians = 3 * PI / 2)) Then
            AY = Player.PosY
            AX = Player.PosX
        Else 'Facing left
            AX = (Int(Player.PosX / ObjectSize) * ObjectSize) - 1
            AY = Player.PosY + (Player.PosX - AX) * -Tan(Player.Radians)
            StepX = -ObjectSize
        End If
        
        
        VertX = AX
        VertY = AY
        StepY = StepX * Tan(Player.Radians)
        MapX = Fix((VertX) / ObjectSize)
        MapY = Fix((VertY) / ObjectSize)
        A.SetPixel (Fix(VertX)), (Fix(VertY)), vbYellow
        If LevelMap0(MapY, MapX) <> vbBlue Then
            Do
                    
                VertX = VertX + StepX
                VertY = VertY + StepY
                
                
                MapX = Fix((VertX) / ObjectSize)
                MapY = Fix((VertY) / ObjectSize)
                A.SetPixel (Fix(VertX)), (Fix(VertY)), vbYellow
                If LevelMap0(MapY, MapX) = vbBlue Then
                    Exit Do
                End If
                
                DoEvents
            Loop
        End If
        
        
        VertDist = Sqr(((VertX - Player.PosX)) * ((VertX - Player.PosX))) + (((VertY - Player.PosY)) * ((VertY - Player.PosY)))
        A.ForeColor vbRed
        
        'obter o a linha mais curta(horizontal ou vertical):
        If VertDist < HorizDist Then
            ' Draw the vertical ray:
            
            A.DrawLine Fix(Player.PosX), Fix(Player.PosY), Fix(VertX), Fix(VertY)
            WallDistance = VertDist
            Debug.Print VertDist & vbTab & "Draw Vertical" & vbTab & HorizDist & vbTab & "Horizontal line"
        Else
            ' Draw the horzontal ray:
            
            A.DrawLine Fix(Player.PosX), Fix(Player.PosY), Fix(HorizX), Fix(HorizY)
            WallDistance = HorizDist
            Debug.Print HorizDist & vbTab & " Draw Horizontal" & vbTab & VertDist & vbTab & "vertical line"
        End If
        
        WallDistance = WallDistance * Cos(Player.Radians)
        RayHeight = ObjectSize / WallDistance * 320
        A.ForeColor vbBlue
        A.DrawLine 475 + 50, 200 / 2 - RayHeight / 2, 475 + 50, 200 / 2 + RayHeight / 2
       
    End Sub

    printed:"334,308881610545     Draw Horizontal    1816,56277706662    vertical line"
    porque a linha vertical é 1816? se o limite é 9*33= 297 e sim noto mais bugs, mas tudo na interceção vertical 😞
    PS: o numero de frames é aproximadamente 1500.... mas  o 'Debug.Print' usa imensos recursos... mas é para testar os valores, nada mais 😉

    image.png

  9. tenho esta função para fazer o RayCasting usando a Trignometria(estou a testar os pontos Horizontais:
     

    Private Sub DrawRays2()
        Dim AY As Double
        Dim AX As Double
        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
        
        MapX = Player.MapX
        MapY = Player.MapY
        On Error Resume Next
        
        'Check for horizontal intersections:
        If ((Player.Radians >= 0 And Player.Radians <= PI)) Then 'Facing down
            AY = (Int(Player.PosY / ObjectSize) * ObjectSize) + ObjectSize ' Calculate grid position
            StepY = ObjectSize
        Else 'Facing Up
            AY = (Int(Player.PosY / ObjectSize) * ObjectSize) - 1
            StepY = -ObjectSize
        End If
        
        AX = Player.PosX + (AY - Player.PosY) / Tan(Player.Radians)
        HorizX = AX
        HorizY = AY
        StepX = StepY / Tan(Player.Radians)
        MapX = Fix((HorizX) / ObjectSize)
        MapY = Fix((HorizY) / ObjectSize)
        A.SetPixel (Fix(HorizX)), (Fix(HorizY)), ColorConstants.vbCyan
        
        Do
                
            HorizX = HorizX + StepX
            HorizY = HorizY + StepY
            
            MapX = Fix((HorizX + 1) / ObjectSize)
            MapY = Fix((HorizY + 1) / ObjectSize)
            A.SetPixel (Fix(HorizX)), (Fix(HorizY)), ColorConstants.vbCyan
            If LevelMap0(MapY, MapX) = vbBlue Then
                Exit Do
            End If
            DoEvents
        Loop
        
        HorizDist = Sqr(((HorizX - Player.PosX) * (HorizX - Player.PosX)) + ((HorizY - Player.PosY) * (HorizY - Player.PosY)))
       
    end sub

    porque não termina quando chega á parede?(dependendo do Radiano)

  10. como fazer o RayCasting em VB6?

    eu tenho esta função para desenhar 1 linha do RayCasting:
     

    Private Sub DrawRays2()
        Dim AY As Double
        Dim AX As Double
        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
        
        On Error Resume Next
        
        ' Check for horizontal intersections:
        If (Player.Radians >= 0 And Player.Radians <= PI) Then ' Facing down
            AY = (Int(Player.PosY / ObjectSize) * ObjectSize) + ObjectSize ' Calculate grid position
            StepY = ObjectSize
        Else 'Facing Up
            AY = (Int(Player.PosY / ObjectSize) * ObjectSize) - 1
            StepY = -ObjectSize
        End If
        AX = Player.PosX + (AY - Player.PosY) / Tan(Player.Radians)
        HorizX = AX
        HorizY = AY
        StepX = StepY / Tan(Player.Radians)
        MapX = Fix((HorizX) / ObjectSize)
        MapY = Fix((HorizY) / ObjectSize)
        
        A.SetPixel (Fix(HorizX)), (Fix(HorizY)), ColorConstants.vbCyan
        If ((MapY < 9 Or MapY >= 0) Or (MapX < 9 Or MapX >= 0)) Then
            If LevelMap0(MapY, MapX) <> vbBlue Then
                Do
                    HorizX = HorizX + StepX
                    HorizY = HorizY + StepY
                    A.SetPixel (Fix(HorizX)), (Fix(HorizY)), ColorConstants.vbCyan
                    MapX = Fix((HorizX) / ObjectSize)
                    MapY = Fix((HorizY) / ObjectSize)
                    If ((MapY > 9 Or MapY < 0) Or (MapX > 9 Or MapX < 0)) Then Exit Do
                    If LevelMap0(MapY, MapX) = vbBlue Then
                        A.SetPixel (Fix(HorizX)), (Fix(HorizY)), ColorConstants.vbCyan
                        Exit Do
                    End If
                    DoEvents
                Loop
            End If
        End If
        HorizDist = Sqr(((HorizX - Player.PosX) * (HorizX - Player.PosX)) + ((HorizY - Player.PosY) * (HorizY - Player.PosY)))
        
        
        ' Check for vertical intersections:
        If (Player.Radians >= (PI / 2) And Player.Radians <= (3 * PI / 2)) Then ' Facing right
            AX = (Int(Player.PosX / ObjectSize) * ObjectSize) - 1 ' Calculate grid position
            StepX = -ObjectSize
        Else 'Facing left
            AX = (Int(Player.PosX / ObjectSize) * ObjectSize) + ObjectSize
            StepX = ObjectSize
        End If
        AY = Player.PosY + (Player.PosX - AX) * -Tan(Player.Radians)
        VertX = AX
        VertY = AY
        StepY = StepX * Tan(Player.Radians)
        MapX = Fix((VertX) / ObjectSize)
        MapY = Fix((VertY) / ObjectSize)
        A.SetPixel (Fix(VertX)), (Fix(VertY)), vbYellow
        
        If LevelMap0(MapY, MapX) <> vbBlue Then
            Do
                VertX = VertX + StepX
                VertY = VertY + StepY
                If (VertX < 0 Or VertX > (9 * ObjectSize) Or VertY < 0 Or VertY > (9 * ObjectSize)) Then Exit Sub
                A.SetPixel (Fix(VertX)), (Fix(VertY)), vbYellow
                MapX = Fix((VertX) / ObjectSize)
                MapY = Fix((VertY) / ObjectSize)
                If ((MapY > 9 And MapY < 0) Or (MapX > 9 And MapX < 0)) Then Exit Do
                If LevelMap0(MapY, MapX) = vbBlue Then
                    A.SetPixel (Fix(VertX)), (Fix(VertY)), vbYellow
                    Exit Do
                End If
                DoEvents
            Loop
        End If
        
        VertDist = Sqr((VertX - Player.PosX) * (VertX - Player.PosX)) + ((VertY - Player.PosY) * (VertY - Player.PosY))
        A.ForeColor vbRed
        WallDistance = Max(VertDist, HorizDist) * Cos(Player.Radians)
        If (WallDistance = VertDist) Then
            A.DrawLine Fix(Player.PosX), Fix(Player.PosY), Fix(VertX), Fix(VertY)
        Else
            A.DrawLine Fix(Player.PosX), Fix(Player.PosY), Fix(HorizX), Fix(HorizY)
        End If
        RayHeight = ObjectSize / WallDistance * 320
        A.ForeColor vbBlue
        A.DrawLine 475 + 50, 200 / 2 - RayHeight / 2, 475 + 50, 200 / 2 + RayHeight / 2
        
    End Sub

    mas noto alguns erros:
    1 - a linha desenhada pode ultrapassar o tamanho da tabela\array(9*ObjectSize);
    2 - dependendo de alguns angulos,a linha não é desenhada...
    eu tenho os if's para tentar evitar esses erros, mas parecem ignorados 😞
    onde estou a errar?

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!