I am pretty sure Nim's sin() and cos() work exact same way as the C++ ones. I 
never had an issue with them working differently. I think error is some place 
else.

Some thing I noticed:

  * you use uint32 for time while C++ uses double.
  * you hard code w to 640 while C++ does not.
  * your right and left key is flipped from the C++ code.
  * C++ article warns about the problem you hare having.
  * you are doing one extra line should be 0 ..< 640 not 0..640



running your code i get: (61, 29) Error: type mismatch: got <array[0..3, int]> 
but expected 'array[0..3, int32]'

I switched to using .byte for color values. I switched to using w and h like 
C++ code.

I can't find the issue in you code, ... but I did my own C++ to nim conversion 
and it works without issues:
    
    
    import sdl2
    import math
    
    var worldMap =[
      [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1],
      [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1],
      [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
      [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
    ]
    
    proc main() =
      
      var
        posX: float = 22 # x and y start position
        posY: float = 12
        dirX: float = -1 # initial direction vector
        dirY: float = 0
        planeX: float = 0 # the 2d raycaster version of camera plane
        planeY: float = 0.66
        
        time: float = 0 # time of current frame
        oldTime: float = 0 # time of previous frame
        
        w = 680
        h = 420
        
        window = createWindow("NIM RayCasting", 100,100,cint w,cint h, 
SDL_WINDOW_SHOWN or SDL_WINDOW_OPENGL)
        render = createRenderer(window, -1, Renderer_Accelerated or 
Renderer_PresentVsync)
        
        evt = sdl2.defaultEvent
        runGame = true
      
      while(runGame):
        
        render.setDrawColor(0,0,0,255)
        render.clear()
        
        for x in 0 ..< w:
          # calculate ray position and direction
          var
            cameraX = 2 * float(x) / float(w) - 1 # x-coordinate in camera space
            rayDirX = dirX + planeX * cameraX
            rayDirY = dirY + planeY * cameraX
            # which box of the map we're in
            mapX: int = int(floor(posX))
            mapY: int = int(floor(posY))
            
            # length of ray from current position to next x or y-side
            sideDistX: float
            sideDistY: float
            
            # length of ray from one x or y-side to next x or y-side
            deltaDistX = abs(1 / rayDirX)
            deltaDistY = abs(1 / rayDirY)
            perpWallDist: float
            
            # what direction to step in x or y-direction (either +1 or -1)
            stepX: int
            stepY: int
            
            hit = 0 # was there a wall hit?
            side: int # was a NS or a EW wall hit?
          
          # calculate step and initial sideDist
          if rayDirX < 0:
            stepX = -1
            sideDistX = (posX - float(mapX)) * deltaDistX
          else:
            stepX = 1
            sideDistX = (float(mapX) + 1.0 - posX) * deltaDistX
          
          if rayDirY < 0:
            stepY = -1
            sideDistY = (posY - float(mapY)) * deltaDistY
          else:
            stepY = 1
            sideDistY = (float(mapY) + 1.0 - posY) * deltaDistY
          
          # perform DDA
          while hit == 0:
            # jump to next map square, OR in x-direction, OR in y-direction
            if sideDistX < sideDistY:
              sideDistX += deltaDistX
              mapX += stepX
              side = 0
            else:
              sideDistY += deltaDistY
              mapY += stepY
              side = 1
            # Check if ray has hit a wall
            if worldMap[mapX][mapY] > 0:
              hit = 1
          
          # Calculate distance projected on camera direction (Euclidean 
distance will give fisheye effect!)
          if side == 0:
            perpWallDist = (float(mapX) - posX + (1 - stepX) / 2) / rayDirX
          else:
            perpWallDist = (float(mapY) - posY + (1 - stepY) / 2) / rayDirY
          
          # Calculate height of line to draw on screen
          var lineHeight = (int)(float(h) / perpWallDist)
          
          # calculate lowest and highest pixel to fill in current stripe
          var drawStart = -lineHeight div 2 + h div 2
          if drawStart < 0:
            drawStart = 0
          var drawEnd = lineHeight div 2 + h div 2
          if drawEnd >= h:
            drawEnd = h - 1
          
          # choose wall color
          var color: array[4, byte]
          case(worldMap[mapX][mapY]):
            of 1: color = [245.byte,66,66,255] # Rojo
            of 2: color = [66.byte,255,95,255] # Verde
            of 3: color = [66.byte,81,245,255] # Azul
            of 4: color = [255.byte,255,255,255] # Blanco
            else: color = [255.byte,255,255,255] # Naranja
          
          # give x and y sides different brightness
          if side == 1:
            for i in 0..2:
              color[i] = color[i] div 2
          
          # draw the pixels of the stripe as a vertical line
          render.setDrawColor(color[0], color[1], color[2], color[3])
          render.drawLine(cint(x),cint(drawStart),cint(x),cint(drawEnd))
        
        # timing for input and FPS counter
        oldTime = time
        time = float getTicks()
        var frameTime = (time - oldTime) / 1000.0 # frameTime is the time this 
frame has taken, in seconds
        
        render.present()
        
        # speed modifiers
        var moveSpeed = frameTime * 5.0 # the constant value is in 
squares/second
        var rotSpeed = frameTime * 3.0 # the constant value is in radians/second
        
        while pollEvent(evt):
          if evt.kind == QuitEvent:
            runGame = false
            break
        
        var state = getKeyboardState()
        
        # move forward if no wall in front of you
        if state[int SDL_SCANCODE_W] != 0:
          if worldMap[int(posX + dirX * moveSpeed)][int(posY)] == 0:
            posX += dirX * moveSpeed
          if worldMap[int(posX)][int(posY + dirY * moveSpeed)] == 0:
            posY += dirY * moveSpeed
        
        # move backwards if no wall behind you
        if state[int SDL_SCANCODE_S] != 0:
          if worldMap[int(posX - dirX * moveSpeed)][int(posY)] == 0:
            posX -= dirX * moveSpeed
          if worldMap[int(posX)][int(posY - dirY * moveSpeed)] == 0:
            posY -= dirY * moveSpeed
        
        # rotate to the right
        if state[int SDL_SCANCODE_D] != 0:
          # both camera direction and camera plane must be rotated
          var oldDirX = dirX
          dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed)
          dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed)
          var oldPlaneX = planeX
          planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed)
          planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed)
        
        # rotate to the left
        if state[int SDL_SCANCODE_A] != 0:
          # both camera direction and camera plane must be rotated
          var oldDirX = dirX
          dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed)
          dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed)
          var oldPlaneX = planeX
          planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed)
          planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed)
    
    main()
    
    
    Run

Reply via email to