Post Reply 
What did I do wrong? (Python)
08-08-2021, 04:59 PM
Post: #1
What did I do wrong? (Python)
So I tried copying a raycasting engine (https://www.hpcalc.org/details/8936) written in PPL, and refactored it into Python to make it run faster. Here is my code:
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()

For some reason this makes the image appear distorted. I verified line by line that I didn't change the algorithm at all. Where did I mess up?
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)