Author Topic: Raycaster [CMLua]  (Read 717 times)

Cybermonkey

  • Administrator
  • Hero Member
  • *****
  • Posts: 573
    • View Profile
    • Home of EGSL
Raycaster [CMLua]
« on: 08. March 2014, 20:38:55 »
Yep, that's an untextured raycaster ported from Lode's computer graphics tutorials: http://lodev.org/cgtutor/
(works in all graphics modes)

Code: [Select]
-- raycaster for CMLua
-- proof of concept

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,5,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,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,1,0,0,0,1},
  {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,1},
  {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,1,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}};
 
local   cameraX,rayPosX,rayPosY,rayDirX,rayDirY,posX,posY,dirX,dirY,planeX,planeY,time,oldTime
local  sideDistY,sideDistX,deltaDistX,deltaDistY,perpWallDist
local oldDirX,oldPlaneX,frametime,moveSpeed,rotSpeed
local   h,lineHeight,drawStart,drawEnd,hit,side,stepX,stepY,mapX,mapY,x,w,key

local CRSLEFT=19200
local CRSRIGHT=19712
local CRSUP=18432
local CRSDOWN=20480
cls()

posX=22; posY=12
dirX=-1; dirY=0
planeX=0; planeY=0.66
time=0
oldTime=0
page = 0
endgame = false
w=screenwidth()
h=screenheight()

repeat
activepage (page)
clear()

ink (hrgb  (150,100,50))
fillrectangle (0,0,screenwidth(),screenheight()/2)
ink (hrgb (40,40,40))
fillrectangle (0,screenheight()/2,screenwidth(),screenheight())

for x=0, w do
    cameraX=2*x/w-1
    rayPosX=posX
    rayPosY=posY
    rayDirX = dirX + planeX * cameraX
    rayDirY = dirY + planeY * cameraX
   
    mapX=int(rayPosX)
    mapY=int(rayPosY)
    deltaDistX = math.sqrt (1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
    deltaDistY = math.sqrt (1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
    hit=0
   
    if rayDirX < 0 then
        stepX = -1
        sideDistX = (rayPosX - mapX) * deltaDistX
    else
        stepX = 1
        sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX
     end
     if rayDirY < 0 then
        stepY = -1
        sideDistY = (rayPosY - mapY) * deltaDistY
     else
        stepY = 1
        sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY
     end
while hit == 0 do
     if (sideDistX < sideDistY) then
          sideDistX = sideDistX + deltaDistX
          mapX = mapX + stepX
          side = 0
      else
          sideDistY = sideDistY + deltaDistY
          mapY = mapY+ stepY
          side = 1
       end
        --Check if ray has hit a wall
        if (worldMap[mapX][mapY] > 0)  then hit = 1 end
    end
    if side == 0 then
      perpWallDist = math.abs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX)
     else
      perpWallDist = math.abs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY)
    end
     lineHeight = math.abs(int(h / perpWallDist))
     drawStart = int(-lineHeight / 2 + h / 2)
     if drawStart < 0 then drawStart = 0 end
     drawEnd = int(lineHeight / 2 + h / 2)
     
     if drawEnd >= h then drawEnd = h - 1 end
     
     if (worldMap[mapX][mapY]) == 1 then
      ink (hrgb (255,0,0))
      elseif (worldMap[mapX][mapY]) == 2 then
      ink (hrgb (0,255,0))
      elseif (worldMap[mapX][mapY]) == 3 then
      ink (hrgb (0,0,255))
      elseif (worldMap[mapX][mapY]) == 4 then
      ink (hrgb (255,255,255))
     else
     ink (hrgb (255,255,0))
     end
     if side == 1 then
      if (worldMap[mapX][mapY]) ==1 then
     ink (hrgb (128,0,0))
     elseif (worldMap[mapX][mapY]) == 2 then
     ink (hrgb (0,128,0))
     elseif (worldMap[mapX][mapY]) == 3 then
      ink (hrgb (0,0,128))
      elseif (worldMap[mapX][mapY]) == 4 then
      ink (hrgb (128,128,128))
     else
     ink (hrgb (128,128,0))
     end
     end
         
     line (x,drawStart,x, drawEnd)
end

oldTime = time;
time = gettickcount()
frameTime = (time - oldTime) / 1000.0

moveSpeed = frameTime * 5.0
rotSpeed = frameTime * 2.0

if keypressed() then
    key=getkey()
    if key == 27 then
        endgame = true
    end
   
    if key == (CRSUP) then
        if (worldMap[int(posX + dirX * moveSpeed)][int(posY)] ==0) then  posX = posX + dirX * moveSpeed end
        if(worldMap[int(posX)][int(posY + dirY * moveSpeed)] ==0) then posY = posY + dirY * moveSpeed end
    end

    if key == (CRSDOWN) then
        if (worldMap[int(posX - dirX * moveSpeed)][int(posY)] == 0) then posX = posX - dirX * moveSpeed end
        if(worldMap[int(posX)][int(posY - dirY * moveSpeed)] ==0) then posY = posY-dirY * moveSpeed end
    end

    if key == (CRSRIGHT) then
      oldDirX = dirX
      dirX = dirX * math.cos(-rotSpeed) - dirY * math.sin(-rotSpeed)
      dirY = oldDirX * math.sin(-rotSpeed) + dirY * math.cos(-rotSpeed)
      oldPlaneX = planeX
      planeX = planeX * math.cos(-rotSpeed) - planeY * math.sin(-rotSpeed)
      planeY = oldPlaneX * math.sin(-rotSpeed) + planeY * math.cos(-rotSpeed)
    end
   
    if key == (CRSLEFT) then
      oldDirX = dirX;
      dirX = dirX * math.cos(rotSpeed) - dirY * math.sin(rotSpeed)
      dirY = oldDirX * math.sin(rotSpeed) + dirY * math.cos(rotSpeed)
      oldPlaneX = planeX
      planeX = planeX * math.cos(rotSpeed) - planeY * math.sin(rotSpeed)
      planeY = oldPlaneX * math.sin(rotSpeed) + planeY * math.cos(rotSpeed)
    end
   
   
    end

visualpage (page)
sleep (10)
page = page + 1
if page > 1 then
    page = 0
end
until endgame == true
Best regards,
Cybermonkey

Osgeld

  • Newcomer
  • *
  • Posts: 33
    • View Profile
Re: Raycaster [CMLua]
« Reply #1 on: 10. March 2014, 03:12:47 »
ray casters are fun