線分と格子の交差判定+ラインアート


線分と格子の交差判定+ラインアート

32*32のサイズの格子と任意の線分との交差判定をするプログラム。
とあるゲームで使うアルゴリズムを試した時の物
線分がラインアートのように動くので、待ち受けになるかも?
このプログラムで頻繁に登場する
(なんかの値>>31|1)
という式は値が0以上なら1を、負なら-1を返す式。便利。
ただしSPALM上なら
(なんかの値<0?-1:1)
の方が早いかも

'端点が壁にめり込んだ時の跳ね返り'
func r(a){
   return (g=a/240*240,abs(rand%4)+1)*(-a>>31|1)
}
vx1=r(rand)
vy1=r(rand)
vx2=r(rand)
vy2=r(rand)
label 0
lock()
clear(0,0,240,240)
if(input(0)){
   end
}
px=px+vx1
py=py+vy1
x=x+vx2
y=y+vy2
if(px<0||px>240){
   vx1=r(px)
   px=g
}
if(py<0||py>240){
   vy1=r(py)
  py=g
}
if(x<0||x>240){
   vx2=r(x)
   x=g
}
if(y<0||y>240){
   vy2=r(y)
   y=g
}
dx=px-x
dy=py-y
'bx,byからex,eyに向かって該当する格子をたどる'
bx=px/32
by=py/32
ex=x/32
ey=y/32
col(0)
for(i=0;i<8;i++){
 line(0,i<<5,240,i<<5)
   line(i<<5,0,i<<5,240)
}
do{
   col((bx<<20)|(by<<4))
   frect((bx<<5)+8,(by<<5)+8,16,16)
   col(0xA000)
   frect(x+dx-2,y+dy-2,5,5)
   move=0
   s=(dx>>31)*32+(x+dx-bx*32)
   t=(dy>>31)*32+(y+dy-by*32)
   u=abs(s*dy)
   v=abs(t*dx)    if(dx&&u<=v&&ex!=bx){
       bx=bx-(dx>>31|1)
       dy=dy-s*dy/dx
       dx=dx-s
       move=1
   }
   if(dy&&v<=u&&ey!=by){
       by=by-(dy>>31|1)
       dx=dx-t*dx/dy
       dy=dy-t
       move=1
   }
}while(move)
col(0xFF0000)
'line(px,py,x,y)''ライン本体'
unlock(1)
goto 0