Critor : thanks for the news !
Adriweb :
Here is the code (yeah, I should add comments) :
pieces={{{0,0,0,0,0,0,0},{0,0,0,1,0,0,0},{0,0,0,0,0,0,0},{0,1,0,2,0,1,0},{0,0,0,0,0,0,0},{0,0,0,1,0,0,0},{0,0,0,0,0,0,0}},{{1,0,1,0,0,0,1},{1,0,1,1,1,0,1},{0,0,0,0,1,0,1},{0,1,0,0,1,0,0},{0,1,0,1,1,0,0},{1,1,0,0,1,1,0},{1,1,0,0,0,0,0}},{{1,1,1,0,1,1,1},{1,0,0,0,0,0,1},{1,0,0,1,0,0,1},{0,0,1,1,1,0,0},{1,0,0,1,0,0,1},{1,0,0,0,0,0,1},{1,1,1,0,1,1,1}},{{1,1,1,0,1,1,1},{0,0,1,0,0,1,0},{0,0,1,0,1,0,0},{0,0,0,0,0,0,0},{0,1,1,1,1,1,0},{0,0,0,0,0,0,1},{1,0,0,0,1,1,1}},{{1,1,1,0,1,1,1},{1,0,0,0,0,0,1},{1,0,1,0,1,0,1},{0,0,0,0,0,0,0},{1,0,1,0,1,0,1},{1,0,0,0,0,0,1},{1,1,1,0,1,1,1}},{{1,1,1,0,0,0,0},{1,0,0,0,0,1,0},{1,0,0,0,1,0,0},{0,0,0,1,0,0,0},{0,0,1,0,0,0,1},{0,1,0,0,0,0,1},{0,0,0,0,1,1,1}}}
function width() return platform.window:width() end
function height() return platform.window:height() end
function refresh() platform.window:invalidate() end
function generateMaze()
local tempMap,mazePieces,currentRow
tempMap={}
tempMap[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,1,1,1,1,1,1}
tempMap[30]={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,1,1,1,1,1}
mazePieces={}
for i=1,16 do
mazePieces[i]=pieces[math.random(2,6)]
end
mazePieces[math.random(2,16)]=pieces[1]
for i=1,28 do
currentRow={1}
currentRow[30]=1
for j=1,28 do
currentRow[j+1]=mazePieces[math.floor((j-1)/7)+math.floor((i-1)/7)*4+1][(i-1)%7+1][(j-1)%7+1]
end
tempMap[i+1]=currentRow
end
map1=tempMap
end
function sqrt2(a)
x=1
y=0.5*(1+a)
while math.abs(y-x)>0.001 do
x=y
y=0.5*(x+a/x)
end
return y
end
function exp2(a)
return a*a
end
function sign(a)
if a<0 then
return -1
else
return 1
end
end
function render3D(gc,surf,map,cam)
gc:setColorRGB(189,228,255)
gc:fillRect(surf.x,surf.y,surf.w,surf.h/2)
gc:setColorRGB(47,127,0)
gc:fillRect(surf.x,surf.y+surf.h/2,surf.w,surf.h/2)
for i=0,surf.w-1,surf.res do
column=(i*2/surf.w)-1
rayStartX=cam.x
rayStartY=cam.y
rayDirX=math.cos(cam.rot)+math.cos(cam.rot-1.5707963267949)*column
rayDirY=math.sin(cam.rot)+math.sin(cam.rot-1.5707963267949)*column
rayCellX=math.floor(rayStartX)
rayCellY=math.floor(rayStartY)
rayStepX=sqrt2(exp2(rayDirY)/exp2(rayDirX)+1)
rayStepY=sqrt2(exp2(rayDirX)/exp2(rayDirY)+1)
rayLengthX=rayStepX*(rayStartX%1*sign(-rayDirX)+(sign(rayDirX)+1)/2)
rayLengthY=rayStepY*(rayStartY%1*sign(-rayDirY)+(sign(rayDirY)+1)/2)
hit=nil
while not hit do
if rayLengthX<rayLengthY then
rayLengthX=rayLengthX+rayStepX
rayCellX=rayCellX+sign(rayDirX)
wallSide=0
else
rayLengthY=rayLengthY+rayStepY
rayCellY=rayCellY+sign(rayDirY)
wallSide=1
end
if map[rayCellX][rayCellY]~=0 then
hit=true
wallType=map[rayCellX][rayCellY]
end
end
if wallSide==0 then
wallDist=math.abs((rayCellX-rayStartX+(1-sign(rayDirX))/2)/rayDirX)
else
wallDist=math.abs((rayCellY-rayStartY+(1-sign(rayDirY))/2)/rayDirY)
end
columnHeight=math.abs(math.floor(surf.h/wallDist))
columnStart=surf.h/2-columnHeight/2
if columnStart<0 then
columnStart=0
end
if columnHeight+columnStart>=surf.h then
columnHeight=surf.h-columnStart
end
if wallSide==1 then
gc:setColorRGB(100,0,0)
else
gc:setColorRGB(140,0,0)
end
if wallType==2 then
gc:setColorRGB(255,255,255)
end
gc:fillRect(i+surf.x,columnStart+surf.y,surf.res,columnHeight)
end
end
function drawMap(gc,map,cam)
gc:setColorRGB(69,45,0)
gc:setPen("medium","smooth")
gc:drawRect(0,0,66,66)
gc:setColorRGB(222,189,127)
gc:fillRect(0,0,66,66)
startX=1 startY=1
if cam.x>=6 then startX=math.floor(cam.x)-5 end
if cam.y>=6 then startY=math.floor(cam.y)-5 end
if cam.x+5>#map then startX=#map-10 end
if cam.y+5>#map[1] then startY=#map[1]-10 end
for i=startX,startX+10,1 do
for j=startY,startY+10,1 do
if map[i][j]~=0 then
if map[i][j]==1 then
gc:setColorRGB(120,78,0)
elseif map[i][j]==2 then
gc:setColorRGB(255,255,255)
end
gc:fillRect(60-(i*6-startX*6),j*6-startY*6,6,6)
end
end
end
gc:setColorRGB(69,45,0)
gc:fillArc(60-(cam.x*6-startX*6-3),cam.y*6-startY*6-3,5,5,0,360)
end
function on.escapeKey()
menu=1
won=nil
refresh()
end
on.escapeKey()
function on.enterKey()
menu=nil
mapDraw=nil
camera={x=3,y=3,rot=1.05}
screen={x=0,y=0,w=width(),h=height(),res=2}
generateMaze()
refresh()
end
function on.arrowKey(ar)
if not menu then
turn=nil
if ar=="right" then
camera.rot=camera.rot-0.1
end
if ar=="left" then
camera.rot=camera.rot+0.1
end
if ar=="up" then
if map1[math.floor(camera.x+math.cos(camera.rot)/3)][math.floor(camera.y+math.sin(camera.rot)/3)]~=1 then
camera.x=camera.x+math.cos(camera.rot)/3
camera.y=camera.y+math.sin(camera.rot)/3
end
end
if ar=="down" then
if map1[math.floor(camera.x-math.cos(camera.rot)/4)][math.floor(camera.y-math.sin(camera.rot)/4)]~=1 then
camera.x=camera.x-math.cos(camera.rot)/4
camera.y=camera.y-math.sin(camera.rot)/4
end
end
if map1[math.floor(camera.x)][math.floor(camera.y)]==2 then
menu=1
won=1
end
refresh()
end
end
function on.charIn(ch)
if not menu then
if ch=="m" then
mapDraw=not mapDraw
elseif ch=="*" and screen.w<width() then
screen.w=screen.w+width()/height()*5
screen.h=screen.h+5
screen.x=width()/2-screen.w/2
screen.y=height()/2-screen.h/2
elseif ch=="/" and screen.w>100 then
screen.w=screen.w-width()/height()*5
screen.h=screen.h-5
screen.x=width()/2-screen.w/2
screen.y=height()/2-screen.h/2
elseif ch=="h" then screen.res=2
elseif ch=="l" then screen.res=4
end
refresh()
end
end
function on.paint(gc)
if menu then
gc:setColorRGB(0,0,255)
gc:setFont("sansserif","r",30)
gc:drawString("MAZES 3D",75,0,"top")
if won then
gc:drawString("You won !",80,150,"top")
end
gc:setFont("serif","b",10)
gc:drawString("Press Enter to start",100,100,"top")
else
render3D(gc,screen,map1,camera)
if mapDraw then
drawMap(gc,map1,camera)
end
end
gc:setColorRGB(0,0,0)
gc:setFont("sansserif","r",8)
gc:drawString("Lua Mazes 3D - Par Loic Pujet",10,200,"top")
end