Advertisement
Redxone

[PICO8] Sudo3D Raycaster

Nov 13th, 2017
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.15 KB | None | 0 0
  1. local w,h = 127, 90
  2.  
  3. -- starting x and y
  4. posx = 15
  5. posy = 11
  6. xvel = 0
  7. yvel = 0
  8. damp = 2
  9. fric = 4
  10. -- direction vector (looking direction)
  11. dirx = 0  -- angle size of rays
  12. diry = 0  -- left/right offset of rays
  13. -- up/down
  14. dirz = 0
  15. -- 2d angles in which rays enter the world at
  16. planex = 0       -- (angle rotation)
  17. planey = 0.66    -- (angle size)
  18. -- field of vision
  19. -- this takes the viewport "width" (planey) and the
  20. -- max ray angles (dirx), and divides them to find the fov
  21. -- 1:1 = 90
  22. -- some simple algebra is used to change this to be fov
  23. -- variable dependant, hence why dirx isn't defined.
  24. -- dirx / planey
  25. fov = 100
  26. bobz  = 0
  27. bobv  = 1
  28. viewbob = 0.36
  29.  
  30. -- misc
  31. rotspd = 0.045
  32. movspd = 0.10
  33. lookspd = 0.8
  34.  
  35. running = true
  36. linebug = 0
  37. debug = false
  38.  
  39.  
  40. world = {
  41.   {1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1},
  42.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  43.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  44.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  45.   {1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
  46.   {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
  47.   {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1},
  48.   {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
  49.   {1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
  50.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  51.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  52.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  53.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  54.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  55.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  56.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  57.   {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  58.   {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  59.   {1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  60.   {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  61.   {1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  62.   {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  63.   {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  64.   {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
  65. }
  66.  
  67.  
  68. function rad(n)
  69.    return n * (3.14159/180) + (0.001)
  70. end
  71.  
  72. function msin(n) return sin(n*0.159) end
  73. function mcos(n) return cos(n*0.159) end
  74.  
  75. function mcut(n,degree)
  76.   if(abs(n) > 1/degree)return n
  77.   return flr(n * degree)/degree
  78. end
  79.  
  80. function updatefov()
  81.    dirx   = -(planey / (fov/90))
  82. end
  83.  
  84.  
  85. function wmap(x,y)
  86.    x = flr(x)
  87.    y = flr(y)
  88.    return world[y][x]
  89. end
  90.  
  91. function _init()
  92.   cls()
  93. end
  94.  
  95. function drawhud()
  96.    rectfill(0,h,128,128,5)
  97.    if(debug)then
  98.     print("rayx: " .. raydx,0,h+8,7)
  99.     print("rayy: " .. raydy,0,h+16,7)
  100.     print("checkerr: " .. linebug,0,h+24,7)
  101.    end
  102. end
  103.  
  104. function _draw()
  105.    updatefov()
  106.    rectfill(0,0,w,(h+dirz+bobz)/2,15)
  107.    rectfill(0,(h+dirz+bobz)/2,w,h,4)
  108.     for x = 0, w do
  109.       -- camera offset relative to middle
  110.       -- -n = left, 0 = middle, +n = right
  111.       local camx  = (2 * x) / w -1
  112.  
  113.       -- min/max ranges of ray directions
  114.       local rdirx = dirx + planex * camx
  115.       local rdiry = diry + planey * camx
  116.       local mapx = flr(posx)
  117.       local mapy = flr(posy)
  118.       local sidex, sidey, stepx, stepy, wall, side
  119.       local hit = 0
  120.  
  121.       -- length of ray from current x/yside to the next one
  122.       local rdirl=sqrt(rdirx * rdirx + rdiry * rdiry)
  123.       raydx = rdirl/abs(rdirx) -- distance from one x-side to the other
  124.       raydy = rdirl/abs(rdiry) -- distance from one y-side to the other
  125.  
  126.  
  127.       -- was a north-south or east-west wall hit?
  128.       -- determine direction to move ray towards
  129.       if(rdirx < 0)then
  130.         stepx = -1
  131.         -- length to first x side
  132.         sidex = (posx - mapx) * raydx
  133.       else
  134.         stepx = 1
  135.         sidex = (mapx + 1.0 - posx) * raydx
  136.       end
  137.  
  138.       if(rdiry < 0)then
  139.         stepy = -1
  140.         -- length to first y side
  141.         sidey = (posy - mapy) * raydy
  142.       else
  143.         stepy = 1
  144.         sidey = (mapy + 1.0 - posy) * raydy
  145.       end
  146.       -- draw lines
  147.       while (hit == 0) do
  148.         -- move ray along the map until it hits a wall
  149.         if(sidex < sidey)then
  150.           -- this is an north-south wall side.
  151.           sidex  += raydx
  152.           mapx += stepx
  153.           side = 0
  154.         else
  155.           -- this is an east-west wall side.
  156.           sidey += raydy
  157.           mapy += stepy
  158.           side = 1
  159.         end
  160.         -- check if ray has hit a wall
  161.         if(world[mapy][mapx] > 0) hit = 1
  162.       end
  163.  
  164.       -- calculate distance ray has traveled from the player
  165.       -- then use that distance to determine wall height
  166.       if(side == 0)then
  167.          wall = (mapx - posx + (1 - stepx) /2 ) / rdirx
  168.       else
  169.          wall = (mapy - posy + (1 - stepy) /2 ) / rdiry
  170.       end
  171.  
  172.       -- calculate height of line
  173.       local lineh = flr( (h / wall) )
  174.      
  175.       -- calculate lowest/highest pixel to fill stripe
  176.       drawstart =       flr(-lineh /2 + (h+dirz+bobz)/2)
  177.       drawend   =       flr( lineh /2 + (h+dirz+bobz)/2)
  178.       if(drawstart < 0) drawstart = 0
  179.       if(drawend >= h ) drawend   = h - 1
  180.  
  181.       -- get color of wall
  182.       box = wmap(mapx,mapy)
  183.       if(side == 0)then -- x sides
  184.             if(box == 1)then boxcol = 8     -- red
  185.         elseif(box == 2)then boxcol = 11    -- green
  186.         elseif(box == 3)then boxcol = 12    -- blue
  187.         elseif(box == 4)then boxcol = 7     -- white
  188.         elseif(box == 5)then boxcol = 10    -- yellow
  189.         else boxcol = 7 end            -- white
  190.       elseif(side == 1)then -- y sides
  191.             if(box == 1)then boxcol = 2    -- violet
  192.         elseif(box == 2)then boxcol = 3     -- dark-green
  193.         elseif(box == 3)then boxcol = 1     -- dark-blue
  194.         elseif(box == 4)then boxcol = 6     -- gray
  195.         elseif(box == 5)then boxcol = 9     -- white
  196.         else boxcol = 7 end  -- orange  
  197.       end
  198.  
  199.       -- draw striped line
  200.       line(x, drawstart, x, drawend, boxcol)
  201.    end
  202.    if(debug)then
  203.      print("xv: " .. xvel/dirx, 0,8,0)
  204.      print("yv: " .. yvel/diry, 0,16,0)
  205.      print("z: " .. dirz, 0,24,0)
  206.      print("rang: " .. dirx, 0,32,0)
  207.      print("roff: " .. diry, 0,40,0)
  208.      print("prot: " .. planex, 0,48,0)
  209.      print("pwid: " .. planey, 0,56,0)
  210.    end
  211.    drawhud()
  212. end
  213.  
  214. function rotate(rdir)
  215.   local oldx = dirx
  216.   local oldpx = planex
  217.   dirx   = dirx   * mcos(rdir) - diry   * msin(rdir)
  218.   diry   = oldx   * msin(rdir) + diry   * mcos(rdir)
  219.   planex = planex * mcos(rdir) - planey * msin(rdir)
  220.   planey = oldpx  * msin(rdir) + planey * mcos(rdir)
  221. end
  222.  
  223.  
  224. function _update60()
  225.    local moved = false
  226.  
  227.    -- player input!
  228.    if(btn(2))then -- up
  229.       if(xvel/dirx < movspd)xvel += dirx * movspd/damp
  230.       if(yvel/diry < movspd)yvel += diry * movspd/damp
  231.       moved = true
  232.    end
  233.  
  234.    if(btn(3))then -- down
  235.       if(xvel/dirx > -movspd)xvel -= dirx * movspd/damp
  236.       if(yvel/diry > -movspd)yvel -= diry * movspd/damp
  237.       moved = true
  238.    end
  239.  
  240.    if(btn(0))then -- strafe left
  241.       rotate(rad(90))
  242.       if(xvel/dirx > -movspd)xvel -= dirx * movspd/damp
  243.       if(yvel/diry > -movspd)yvel -= diry * movspd/damp
  244.       rotate(-rad(90))
  245.      moved = true
  246.    end
  247.    if(btn(1))then -- strafe right
  248.       rotate(-rad(90))
  249.       if(xvel/dirx > -movspd)xvel -= dirx * movspd/damp
  250.       if(yvel/diry > -movspd)yvel -= diry * movspd/damp
  251.       rotate(rad(90))
  252.       moved = true
  253.    end
  254.  
  255.    if(btn(2,1))then -- look up
  256.       dirz += lookspd
  257.    end
  258.  
  259.    if(btn(3,1))then -- look down
  260.       dirz -= lookspd
  261.    end
  262.  
  263.    -- collision
  264.    if(wmap(posx+xvel, posy) != 0)then
  265.       xvel = -(xvel/2)
  266.    end
  267.    if(wmap(posx,posy+yvel) != 0)then
  268.       yvel = -(yvel/2)
  269.    end
  270.  
  271.    -- bob whilst moving
  272.    if(xvel != 0 or yvel != 0)then
  273.       bobz += viewbob * bobv
  274.       if(bobz > 5) bobv *= -1
  275.       if(bobz < -5) bobv *= -1
  276.    else
  277.       bobz /= 2
  278.       if(abs(bobz) < 0.001) bobz = 0
  279.    end
  280.  
  281.    -- slow when not moving
  282.    if(not moved)then
  283.       -- friction
  284.       xvel /= fric
  285.       yvel /= fric
  286.    end
  287.  
  288.    -- move
  289.    posx += xvel
  290.    posy += yvel
  291.  
  292.    -- rotation!
  293.    if(btn(1,1))then -- right
  294.       rotate(rotspd)
  295.    end
  296.    if(btn(0,1))then -- left
  297.       rotate(-rotspd)
  298.    end
  299.  
  300.    --pmx = mx
  301.    --pmy = my
  302. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement