Redxone

[CC] - Raycaster port from Pico8

Dec 22nd, 2017
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.62 KB | None | 0 0
  1.  
  2. if(fs.exists("blittle"))then os.loadAPI("blittle") end
  3.  
  4. defWindow = term.current()
  5. if(fs.exists("blittle"))then
  6.   litWindow = blittle.createWindow()
  7. else
  8.   litWindow = term.current()
  9. end
  10.  
  11. local w,h = term.getSize()
  12. mode = 1
  13. -- starting x and y
  14. posx = 15
  15. posy = 11
  16. xvel = 0
  17. yvel = 0
  18. damp = 2
  19. -- direction vector (looking direction)
  20. dirx = 0  -- angle size of rays
  21. diry = 0  -- left/right offset of rays
  22. -- up/down
  23. dirz = 0
  24. -- 2d angles in which rays enter the world at
  25. planex = 0       -- (angle rotation)
  26. planey = 1.33    -- (angle size)
  27. -- field of vision
  28. -- this takes the viewport "width" (planey) and the
  29. -- max ray angles (dirx), and divides them to find the fov
  30. -- 1:1 = 90
  31. -- some simple algebra is used to change this to be fov
  32. -- variable dependant, hence why dirx isn't defined.
  33. -- dirx / planey
  34. fov = 60
  35. bobz  = 0
  36. bobv  = 1
  37. viewbob = 0.15
  38. dobob = true
  39.  
  40. -- misc
  41. rotspd = 0.045
  42. movspd = 0.10
  43. lookspd = 0.8
  44. mw, ms, ma, md, ml, mr, mup, mdown = false, false, false, false, false, false, false, false
  45.  
  46. running = true
  47. linebug = 0
  48. debug = false
  49.  
  50.  
  51. world = {
  52.   {1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,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,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
  57.   {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
  58.   {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1},
  59.   {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
  60.   {1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
  61.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  62.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  63.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  64.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  65.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  66.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  67.   {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  68.   {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  69.   {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  70.   {1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  71.   {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  72.   {1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  73.   {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  74.   {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  75.   {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
  76. }
  77.  
  78. function renderMode()
  79.     if(mode == 1 and fs.exists("blittle"))then
  80.         term.clear()
  81.         term.redirect(litWindow)
  82.         w,h = term.getSize()
  83.     end
  84.     if(mode == 0)then
  85.         term.clear()
  86.         term.redirect(defWindow)
  87.         w,h = term.getSize()
  88.     end
  89.     _draw()
  90. end
  91.  
  92. function renderSwap()
  93.     if(mode == 1)then mode = 0 end
  94.     renderMode()
  95. end
  96.  
  97. function rad(n)
  98.    return n * (3.14159/180) + (0.001)
  99. end
  100.  
  101. function mcut(n,degree)
  102.   if(math.abs(n) > 1/degree)then return n end
  103.   return math.floor(n * degree)/degree
  104. end
  105.  
  106. function updatefov()
  107. -- dirx*-1 / planey = n*90 = fov
  108. -- planey = -dirx * (fov/90)
  109.    dirx   = -(planey / (fov/90))
  110. end
  111.  
  112.  
  113. function wmap(x,y)
  114.    x = math.floor(x)
  115.    y = math.floor(y)
  116.    return world[y][x]
  117. end
  118.  
  119. function _init()
  120.   cls()
  121. end
  122.  
  123.  
  124. function _draw()
  125.    mw, ms, ma, md, ml, mr, mup, mdown = false, false, false, false, false, false, false, false
  126.    updatefov()
  127.    term.setBackgroundColor(colors.gray)
  128.    term.clear()
  129.     for x = 0, w do
  130.       -- camera offset relative to middle
  131.       -- -n = left, 0 = middle, +n = right
  132.       local camx  = (2 * x) / w -1
  133.  
  134.       -- min/max ranges of ray directions
  135.       local rdirx = dirx + planex * camx
  136.       local rdiry = diry + planey * camx
  137.       local mapx = math.floor(posx)
  138.       local mapy = math.floor(posy)
  139.       local sidex, sidey, stepx, stepy, wall, side
  140.       local hit = 0
  141.  
  142.       -- length of ray from one side to another
  143.       local rdirl=math.sqrt(rdirx * rdirx + rdiry * rdiry)
  144.       -- Normally i'd have a second sqrt for each ray delta.
  145.       -- This is a little faster than that, and prevents the small chance of
  146.       -- strange sqrt underflows.
  147.       raydx = rdirl/math.abs(rdirx)
  148.       raydy = rdirl/math.abs(rdiry)
  149.      
  150.         -- find which direction to step in
  151.         -- this step direction moves the ray around the map.
  152.         -- these side variables are for determining north/south/east/west sides of the walls.
  153.       if(rdirx < 0)then
  154.         stepx = -1
  155.         sidex = (posx - mapx) * raydx
  156.       else
  157.         stepx = 1
  158.         sidex = (mapx + 1.0 - posx) * raydx
  159.       end
  160.  
  161.       if(rdiry < 0)then
  162.         stepy = -1
  163.         sidey = (posy - mapy) * raydy
  164.       else
  165.         stepy = 1
  166.         sidey = (mapy + 1.0 - posy) * raydy
  167.       end
  168.       -- draw lines
  169.       while (hit == 0) do
  170.         -- keep moving ray until it hits
  171.         if(sidex < sidey)then
  172.           sidex = sidex + raydx
  173.           mapx = mapx + stepx
  174.           side = 0
  175.         else
  176.           sidey = sidey + raydy
  177.           mapy = mapy + stepy
  178.           side = 1
  179.         end
  180.         -- check if ray has hit a wall
  181.         if(world[mapy][mapx] > 0)then hit = 1 end
  182.       end
  183.  
  184.       -- Calculate distance ray has traveled, this is later used to determine the height
  185.       -- to draw the wall.
  186.       if(side == 0)then
  187.          wall = (mapx - posx + (1 - stepx) /2 ) / rdirx
  188.       else
  189.          wall = (mapy - posy + (1 - stepy) /2 ) / rdiry
  190.       end
  191.  
  192.       -- calculate height of line
  193.       local lineh = math.floor( (h / wall) )
  194.      
  195.       -- calculate lowest/highest pixel to fill stripe
  196.       drawstart =       math.floor(-lineh /2 + (h+dirz+bobz)/2)
  197.       drawend   =       math.floor( lineh /2 + (h+dirz+bobz)/2)
  198.       if(drawstart < 0)then drawstart = 0 end
  199.       if(drawend >= h )then drawend   = h - 1 end
  200.  
  201.       -- get color of wall
  202.       box = wmap(mapx,mapy)
  203.       if(side == 0)then -- x sides
  204.             if(box == 1)then boxcol = colors.red
  205.         elseif(box == 2)then boxcol = colors.lime    -- green
  206.         elseif(box == 3)then boxcol = colors.lightBlue    -- blue
  207.         elseif(box == 4)then boxcol = colors.white    -- white
  208.         elseif(box == 5)then boxcol = colors.yellow   -- yellow
  209.         else boxcol = colors.white end            -- white
  210.       elseif(side == 1)then -- y sides
  211.             if(box == 1)then boxcol = colors.orange    -- violet
  212.         elseif(box == 2)then boxcol = colors.green     -- dark-green
  213.         elseif(box == 3)then boxcol = colors.blue    -- dark-blue
  214.         elseif(box == 4)then boxcol = colors.lightGray     -- gray
  215.         elseif(box == 5)then boxcol = colors.white     -- white
  216.         else boxcol = colors.white end
  217.       end
  218.  
  219.       -- draw striped line
  220.       paintutils.drawLine(x, drawstart, x, drawend, boxcol)
  221.    end
  222. end
  223.  
  224. function rotate(rdir)
  225.   local oldx = dirx
  226.   local oldpx = planex
  227.   dirx   = dirx   * math.cos(rdir) - diry   * math.sin(rdir)
  228.   diry   = oldx   * math.sin(rdir) + diry   * math.cos(rdir)
  229.   planex = planex * math.cos(rdir) - planey * math.sin(rdir)
  230.   planey = oldpx  * math.sin(rdir) + planey * math.cos(rdir)
  231. end
  232.  
  233. local pmx = 0
  234. local pmy = 0
  235.  
  236. function _update60()
  237.    local e = {os.pullEvent()}
  238.    if(e[1] == "key")then
  239.       local k = e[2]
  240.       if(k == keys.w    )then mw = true    else mw = false    end
  241.       if(k == keys.s    )then ms = true    else ms = false    end
  242.       if(k == keys.a    )then ma = true    else ma = false    end
  243.       if(k == keys.d    )then md = true    else md = false    end
  244.       if(k == keys.up   )then mup = true   else mup = false   end
  245.       if(k == keys.down )then mdown = true else mdown = false end
  246.       if(k == keys.left )then ml = true    else ml = false    end
  247.       if(k == keys.right)then mr = true    else mr = false    end
  248.       if(k == keys.b)then dobob = not dobob end
  249.       if(k == keys.g)then renderSwap() end
  250.    end
  251.    local moved = false
  252.  
  253.    -- player input!
  254.    if(mw)then -- up
  255.       if(xvel/dirx < movspd)then xvel = xvel + dirx * movspd/damp end
  256.       if(yvel/diry < movspd)then yvel = yvel + diry * movspd/damp end
  257.       moved = true
  258.    end
  259.  
  260.    if(ms)then -- down
  261.       if(xvel/dirx > -movspd)then xvel = xvel - dirx * movspd/damp end
  262.       if(yvel/diry > -movspd)then yvel = yvel - diry * movspd/damp end
  263.       moved = true
  264.    end
  265.  
  266.    if(md)then -- strafe right
  267.       rotate(rad(90))
  268.       if(xvel/dirx > -movspd)then xvel = xvel - dirx * movspd/damp end
  269.       if(yvel/diry > -movspd)then yvel = yvel - diry * movspd/damp end
  270.       rotate(-rad(90))
  271.      moved = true
  272.    end
  273.    if(ma)then -- strafe left
  274.       rotate(-rad(90))
  275.       if(xvel/dirx > -movspd)then xvel = xvel - dirx * movspd/damp end
  276.       if(yvel/diry > -movspd)then yvel = yvel - diry * movspd/damp end
  277.       rotate(rad(90))
  278.       moved = true
  279.    end
  280.  
  281.    if(mup)then -- look up
  282.       dirz = dirz + lookspd
  283.    end
  284.  
  285.    if(mdown)then -- look down
  286.       dirz = dirz - lookspd
  287.    end
  288.  
  289.    -- collision
  290.    if(wmap(posx+xvel, posy) ~= 0)then
  291.       xvel = -(xvel/2)
  292.    end
  293.    if(wmap(posx,posy+yvel) ~= 0)then
  294.       yvel = -(yvel/2)
  295.    end
  296.  
  297.    -- bob whilst moving
  298.    if( (xvel ~= 0 or yvel ~= 0) and dobob)then
  299.       bobz = bobz + viewbob * bobv
  300.       if(bobz >  1.2)then bobv = bobv * -1 end
  301.       if(bobz < -1.2)then bobv = bobv * -1 end
  302.    else
  303.       bobz = bobz / 2
  304.       if(math.abs(bobz) < 0.001)then bobz = 0 end
  305.    end
  306.  
  307.    -- slow when not moving
  308.    if(not moved)then
  309.       xvel = 0
  310.       yvel = 0
  311.    end
  312.  
  313.    -- move
  314.    posx = posx + xvel
  315.    posy = posy + yvel
  316.  
  317.    -- rotation!
  318.    if(ml)then -- right
  319.       rotate(rotspd)
  320.    end
  321.    if(mr)then -- left
  322.       rotate(-rotspd)
  323.    end
  324. end
  325.  
  326. renderMode()
  327. while running do
  328.     term.current().setVisible(false)
  329.     _draw()
  330.     _update60()
  331.     term.current().setVisible(true)
  332. end
Add Comment
Please, Sign In to add comment