Ir ao conteúdo
  • Cadastre-se

Cambalinho

Membro Pleno
  • Posts

    940
  • Cadastrado em

  • Última visita

  1. 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: 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)
  2. 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
  3. basicamente é multiplicar por -1, a velocidade muito obrigado
  4. sabendo que a bola: - direção é 45º; - velocidade é 1... como se calcula a direção da bola, após 1 colisão? (se existem mais parâmetros, me corrigem) 'sem código
  5. ok. muito obrigado por tudo... este caso me fez pensar o que posso adicionar na minha linguagem muito obrigado
  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: onde errei para obter a linha da imagem?
  7. do estilo 'pre-processor' do C.... converter 'AndAlso' a 'then if'
  8. esse teste simples pode usar 'and'? (só para dizer que os valores de X e Y ficam entre zero e 100) exemplo: If (X >=0 and x<=100) Then If (Y >= 0 and Y<=100) Then if(array(y,x)=10) then msgbox "the number is 10" este exemplo é válido?
  9. muito obrigado não se pode usar 1 operador similar ao 'AndAlso' e 'OrAlso', como o .NET?
  10. 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")
  11. 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
  12. 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)
  13. ao grafico: 'Check for horizontal intersections: If ((Player.Radians >= 0 And Player.Radians <= PI)) Then 'Facing down mas deveria ser para cima e não para baixo, certo? eu rodasse para a direita ou esquerda o Radianos são os mesmos ou negativos? parecem correções básicas, mas noto diferenças entre a Matemática(sentido anti-horário) e a Computação(sentido horário).

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