As already mentioned, here it is:
-- 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.