Code:
from math import *
from hpprime import *
MA=None
MH=None
def ISKEYDOWN(k):
return (keyboard()>>k)&1
def mapSelect():
global MA
global MH
MA=[
[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0], #1.9
[ 0.0, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 0],
[ 0.0, 1.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.9, 0],
[ 0.0, 1.9, 0.0, 3.7, 3.7, 4.6, 4.9, 5.2, 5.5, 5.5, 0.0, 1.9, 0],
[ 0.0, 1.9, 0.0, 3.7, 0.0, 0.0, 1.0, 0.0, 0.0, 5.5, 0.0, 1.9, 0],
[ 0.0, 1.9, 0.0, 3.4, 0.0, 7.3, 7.3, 7.3, 0.0, 6.4, 0.0, 1.9, 0],
[ 0.0, 1.9, 0.0, 3.1, 0.0, 7.3, 7.3, 7.3, 0.0, 6.7, 0.0, 1.9, 0],
[ 0.0, 1.9, 0.0, 2.8, 0.0, 7.3, 7.3, 7.3, 0.0, 7.0, 0.0, 1.9, 0],
[ 0.0, 1.9, 0.0, 1.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.9, 0],
[ 0.0, 1.9, 0.0, 1.9, 1.7, 1.4, 1.1, 0.8, 0.5, 0.2, 0.0, 1.9, 0],
[ 0.0, 1.9, 0.0, 0.0, 0.0, 0.0, 1.1, 0.0, 0.0, 0.0, 0.0, 1.9, 0],
[ 0.0, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9, 0],
[ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0]]
MH=[
[ 5.7, 5.2, 5.7, 2.2, 2.7, 2.2, 0, 2.2, 2.7, 2.2, 5.7, 5.2, 5.7], #0.8
[ 5.2, 3.1, 3.3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 3.3, 3.1, 5.2],
[ 5.7, 3.3, 5.7, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 5.7, 3.3, 5.7],
[ 2.2, 0.1, 2.0, 0.4, 0.7, 0.1, 0.1, 0.1, 0.1, 0.4, 2.0, 0.1, 2.2],
[ 2.7, 0.1, 2.0, 0.1, 9.9, 9.3, 8.9, 9.3, 9.9, 0.7, 2.0, 0.1, 2.7],
[ 2.2, 0.1, 2.0, 0.1, 9.3, 1.6, 1.6, 1.6, 9.3, 0.1, 2.0, 0.1, 2.2],
[ 2.7, 0.1, 2.0, 0.1, 9.9, 1.3, 1.6, 1.6, 9.9, 0.1, 2.0, 0.1, 2.7],
[ 2.2, 0.1, 2.0, 0.1, 9.3, 1.0, 0.7, 0.4, 7.4, 0.1, 2.0, 0.1, 2.2],
[ 2.7, 0.1, 2.0, 0.7, 9.9, 9.3, 9.9, 9.3, 9.9, 0.2, 2.0, 0.1, 2.7],
[ 2.2, 0.1, 2.0, 0.4, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 2.0, 0.1, 2.2],
[ 5.7, 3.3, 5.7, 2.0, 2.0, 2.0, 0.9, 2.0, 2.0, 2.0, 5.7, 3.3, 5.7],
[ 5.2, 3.1, 3.3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 3.3, 3.1, 5.2],
[ 5.7, 5.2, 5.7, 2.2, 2.7, 2.2, 2.2, 2.2, 2.7, 2.2, 5.7, 5.2, 5.7]]
def getMapVal(mm,x,y):
global gridWidth
global gridHeight
x=floor(x)
y=floor(y)
if x<0 or x>gridWidth-1 or y<0 or y>gridHeight-1:
return 0
else:
return mm[x][y]
def next(v,d):
if v%1==0:
return v+d
else:
if d>0:
return ceil(v)
else:
return floor(v)
def include(inter,x,y):
a=min(x,y)
y=max(x,y)
for i in inter:
if a<=i[1]:
return a>=i[0] and y<=i[1]
return False
def reunion(inter,x,y):
a=floor(min(x,y))
y=ceil(max(x,y))
for index,i in enumerate(inter):
#print(i)
if a<=i[1]+1:
if y>=i[0]-1:
inter[index]=[min(a,i[0]),max(y,i[1])];
return inter
else:
inter.insert(index,[a,y]);
return inter
inter.append([a,y])
return inter
def ray(x0,y0,r,mode,MA,MH,xc):
global z
global u
global d
global p
global t
global gridWidth
global gridHeight
"""
LOCAL X,Y,XT,YT,DX,DY,D,INTER;
LOCAL V1,V2,LX,LY,L,I,TB,C;
LOCAL HV,TOP,LT,BOT,LB,LV1,LV2,COLS;
LOCAL OK;
"""
ok=True
dx=copysign(1,cos(r))
dy=copysign(1,sin(r))
x=x0
y=y0
xt=0
yt=0
l=[]
inter=[]
q=0
LV1=getMapVal(MH,x,y)
LV2=getMapVal(MA,x,y)
lt=0
lb=0
TOP=0
BOT=0
if z+u<LV2:
lb=-1
else:
lb=h
if z+u>LV1+LV2:
lt=h
else:
lt=-1
V1=0
V2=0
while ok and ((x<=gridWidth-1 and dx>0) or (x>=0 and dx<0)) and ((y<=gridHeight-1 and dy>0) or (y>=0 and dy<0)):
#print(V1,LV1)
lx=x
ly=y
hv=1
if dx!=0:
x=next(x,dx);
yt=ly+(x-lx)*tan(r)
if dy!=0:
y=next(y,dy)
xt=lx+(y-ly)/tan(r)
if dy==0:
y=yt
elif dx==0:
x=xt
elif (xt-x0)**2+(y-y0)**2<(x-x0)**2+(yt-y0)**2:
x=xt
else:
y=yt
if y==yt and mode==0:
hv=(2 if dx<0 else 3)
d=sqrt((x-x0)**2+(y-y0)**2)*cos(r-t);
V1=getMapVal(MH,x+dx/100,y+dy/100);
V2=getMapVal(MA,x+dx/100,y+dy/100);
#print(x,y)
cols=[127,191,95,159]
if mode==1:
for i in range(len(cols)):
cols[i]/=d+1
elif mode==2:
for i in range(len(cols)):
cols[i]=255-(255-cols[i])/(d+1)
if z+u>LV1+LV2 and LV1+LV2>0:
tb=max(h/2-(LV1+LV2-u-z)*h/d,-1)
if tb>=0 or tb<=h-1 or lt>=0 or lt<=h-1:
l.append(lt)
l.append(tb)
l.append(cols[1])
q+=3
inter=reunion(inter,lt,tb)
if z+u<LV2:
tb=min(h/2+(u-LV2+z)*h/d,h)
if tb<=h-1 or tb>=0 or lb>=0 or lb<=h-1:
try:
l[q]=tb
l[q+1]=lb
l[q+2]=cols[1]
except IndexError:
l.append(tb)
l.append(lb)
l.append(cols[1])
q+=3
inter=reunion(inter,lb,tb)
if V1>0 and d>0:
TOP=max(h/2-(V1+V2-u-z)*h/d,-1)
BOT=min(h/2+(u-V2+z)*h/d,h)
if V1+V2>LV1+LV2 or V2<LV2:
if TOP<=h-1 or BOT>=0:
try:
l[q]=TOP
l[q+1]=BOT
l[q+2]=cols[hv]
except IndexError:
l.append(TOP)
l.append(BOT)
l.append(cols[hv])
q+=3
inter=reunion(inter,TOP,BOT)
lt=TOP
lb=BOT
LV1=V1
LV2=V2
ok=not include(inter,max(h/2-(max(9.9,z+u)-u-z)*h/d,0),min(h/2+(u+z)*h/d,h-1))
#print(V1,LV1)
#print('done')
for i in range(q-3,-1,-3):
fillrect(1,xc,l[i],xc+p,l[i+1],int(l[i+2])*0x010101,int(l[i+2])*0x010101)
def CANGO(X,Y,MA,MH):
global z
global d
V1=getMapVal(MH,X,Y);
V2=getMapVal(MA,X,Y);
return z>=V2+V1-d and v==0 or z>=V2+V1 or z+u+E<=V2
def main():
global MA
global MH
global a
global x
global y
global z
global t
global u
global d
global E
global v
global w
global h
global p
global gridWidth
global gridHeight
w=320
h=240
dimgrob(1,320,240,0)
dimgrob(2,320,240,0)
mode=1 # 1=shading, 2=fog, 0=none
mapSelect()
gridWidth=len(MA[0]);
gridHeight=len(MA);
dimgrob(3,1,h/2,0)
dimgrob(4,1,h/2,0)
dimgrob(2,1,h,0)
dimgrob(1,w,h,0)
for j in range(h/2):
E=128/(1+(h/2-j)*20/h);
fillrect(3,0,j,1,j,int(E)*0x10000,int(E)*0x10000);
fillrect(4,0,j,0,j,0xff0000+(255-E)*0x100+255-E,0xff0000+(255-E)*0x100+255-E);
k=0
p=25 # ray width
a=pi/3
x=-1.5
y=gridHeight/2-((gridHeight+1)%2)/2
z=0
t=10**-11;
u=0.5 # eye_height
d=0.3 # climbing_margin
E=0.1 # player_height - eye_height
v=0; # vertical speed
FPSD=0.1 # FPS step
g=2 # FPS target
while k!=4:
k=int(eval('GETKEY'));
f=int(eval('Ticks'))
mode=(mode+ISKEYDOWN(49))%3;
g=max(g+(ISKEYDOWN(50)-ISKEYDOWN(45))*FPSD,FPSD);
t+=(ISKEYDOWN(8)-ISKEYDOWN(7))*pi/24
dx=cos(t);
dy=sin(t);
NX=x-0.1*dx*(ISKEYDOWN(12)-ISKEYDOWN(2));
NY=y-0.1*dy*(ISKEYDOWN(12)-ISKEYDOWN(2));
if NX!=x or NY!=y:
if CANGO(NX,NY,MA,MH):
x=NX;
y=NY;
elif CANGO(NX,y,MA,MH):
x=NX
else:
if CANGO(x,NY,MA,MH):
y=NY
V1=getMapVal(MH,x,y)
V2=getMapVal(MA,x,y)
if V1+V2>z and z>=V1+V2-d:
z=V1+V2
if (z==0 or z==V1+V2) and k==30:
v+=0.2
NZ=max(z+v,0);
if z+u+0.1<=V2 and NZ+u+0.1>V2:
NZ=V2-U-0.1
V=0
if y>V1+V2 and NZ<V1+V2:
NZ=V1+V2;
z=NZ
if z!=0 and z!=V1+V2:
v-=0.05;
else:
v=0
i=t-a/2
s=a*p/w
if mode==0:
fillrect(1,0,h/2+z,320,h-1,0x7f0000,0x7f0000)
elif mode==1:
blit(1,0,h/2+z,3)
blit(1,1,0,1)
else:
blit(2,0,h/2+z,4)
for c in range(0,w,p):
color=0x0F056B if mode==1 else (0x77B5FE if mode==0 else 0xDFF2FF)
fillrect(1,c,0,c+p,h/2+z-1,color,color);
ray(x,y,i,mode,MA,MH,c);
#eval('BLIT_P(G1,C,0,C+P,H,G2)')
i+=s
f=int(eval('Ticks'))-f
p=max(p-(1 if (f<1000/(g*0.7)) else 0)+(1 if f>1000/(g*1.3) else 0),1)
textout(1,0,0,"Quality : "+str(int(100/p))+" %",0xff0000);
#TEXTOUT_P("Speed : "+ROUND(1000/F,1)+" fps",G1,0,10,1,RGB(255,0,0));
#TEXTOUT_P("Target : "+G+" fps (change with +/-)",G1,0,20,1,RGB(255,0,0));
#textout(1,0,30,''+str([x,y]),0xff0000);
blit(0,0,0,1);
main()