Author Topic: Random Maze + Racaster  (Read 643 times)

Cybermonkey

  • Administrator
  • Hero Member
  • *****
  • Posts: 574
    • View Profile
    • Home of EGSL
Random Maze + Racaster
« on: 10. March 2014, 23:09:40 »
As already mentioned, here it is:
Code: [Select]
-- raycaster for CMLua
-- proof of concept

width = 19 --use only odd numbers!
height = 19 -- here, too

function show_maze(mapx,mapy)
    for j = 1, width  do
         for i = 1, height  do
            if worldMap[j][i] == 0 then
             ink (hrgb (200,200,200))
                fillrectangle (i*8,j*8,i*8+8,j*8+8)
            elseif worldMap[j][i] == 1 then
               ink (hrgb (20,20,20))
                fillrectangle (i*8,j*8,i*8+8,j*8+8)
            elseif worldMap[j][i] == 3 then
               ink (hrgb (0,0,255))
                fillrectangle (i*8,j*8,i*8+8,j*8+8)
                elseif worldMap[j][i] == 4 then
               ink (hrgb (250,250,250))
                fillrectangle (i*8,j*8,i*8+8,j*8+8)
         end
      end
      ink (hrgb (255,255,0))
    fillrectangle (mapy*8,mapx*8,mapy*8+8,mapx*8+8)
  end
end


function init_maze()
     for y = 1 , height  do
         for x = 1, width  do
            worldMap[x][y] = 1
         end
      end
end

function carve_maze(x, y)
local      x1, y1 ,x2, y2 , dx, dy, dir, cnt
      dir = int (rnd()*3)+1
      cnt = 0
   while cnt < 4 do
       dx = 0
       dy = 0
       if dir == 0 then
              dx = 1
        elseif dir == 1 then
               dy = 1
         elseif dir == 2 then
                dx = -1
          else  dy = -1
         end
         x1 = x + dx
         y1 = y + dy
         x2 = x1 + dx
         y2 = y1 + dy
         if (x2 > 0) and (x2 < width) and (y2 > 0) and (y2 < height) and (worldMap[x1][y1] == 1) and (worldMap[x2][y2] == 1) then
           worldMap[x1][y1]=0
           worldMap[x2][y2]=0
            carve_maze(x2, y2)
         end
         dir = (dir + 1) % 4;
         cnt = cnt + 1
      end
   end

function generate_maze()
      worldMap[2][2] = 0
      carve_maze(2, 2)
      worldMap[2][3]=0
      worldMap[3][3]=0
      worldMap[3][2]=0
      --worldMap[3][4]=0
      worldMap[2][1]=3
      worldMap[width-10][height]=4
      if worldMap[width-10][height-1] ~= 0 then
worldMap[width-10][height-1]=0
      end
end

worldMap = {}
for i=1,width do
worldMap[i]={}
end


init_maze()
generate_maze()
 
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
local clRed = hrgb (255,0,0)
local clGreen = hrgb (0,255,0)
local clBlue = hrgb (0,0,255)
local clWhite = hrgb (255,255,255)
local clYellow =hrgb (255,255,0)
local clDarkGreen = hrgb (0,128,0)
local clDarkBlue = hrgb (0,0,128)
local clDarkRed = hrgb (128,0,0)
local clDarkYellow = hrgb (128,128,0)
local clGrey = hrgb (128,128,128)

cls()

posX=3; posY=3
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  (120,120,120))
fillrectangle (0,0,screenwidth(),screenheight()/2)
ink (hrgb (60,60,60))
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 (clRed)
      elseif (worldMap[mapX][mapY]) == 2 then
      ink (clGreen)
      elseif (worldMap[mapX][mapY]) == 3 then
      ink (clBlue)
      elseif (worldMap[mapX][mapY]) == 4 then
      ink (clWhite)
     else
     ink (clYellow)
     end
     if side == 1 then
      if (worldMap[mapX][mapY]) ==1 then
     ink (clDarkRed)
     elseif (worldMap[mapX][mapY]) == 2 then
     ink (clDarkGreen)
     elseif (worldMap[mapX][mapY]) == 3 then
      ink (clDarkBlue)
      elseif (worldMap[mapX][mapY]) == 4 then
      ink (clGrey)
     else
     ink (clDarkYellow)
     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 == (120) then
        if (worldMap[int(posX + planeX * moveSpeed)][int(posY)] ==0) then  posX = posX + planeX * moveSpeed end
        if(worldMap[int(posX)][int(posY + planeY * moveSpeed)] ==0) then posY = posY + planeY * moveSpeed end
    end

    if key == (121) then
        if (worldMap[int(posX - planeX * moveSpeed)][int(posY)] == 0) then posX = posX - planeX * moveSpeed end
        if(worldMap[int(posX)][int(posY - planeY * moveSpeed)] ==0) then posY = posY-planeY * 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
show_maze(int (posX),int(posY))

if (int (posX)==width-10) and (int (posY)==height-1) then
    locate (15,20,"You found a secret!")
end

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


Try to find the secret ... (that is the white block). You are the yellow rectangle on the map.
« Last Edit: 14. March 2014, 18:23:48 by Cybermonkey »
Best regards,
Cybermonkey