Ir ao conteúdo

Posts recomendados

Postado

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

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