unit phy; interface procedure loadObject(_x, _y, _w, _h, _velx, _vely:integer; _jmp:boolean); function isSolid(x, y, velx, vely:integer):boolean; function mapCollType(_type, x, y, w, h:integer):boolean; function CollTwoObj(x1,y1,w1,h1,x2,y2,w2,h2:integer):boolean; procedure jumpObj(vel:integer); procedure calc(gravity:boolean); function getX:integer; function getY:integer; function getVelX:integer; function getVelY:integer; function getJmp:boolean; function canSeeObj(x1, y1, x2, y2:integer):boolean; implementation uses items_store, maps, vars; const MAX_VELY=32; TILE_SIZE=16; var x, y, w, h, velx, vely:integer; jmp:boolean; function CollTwoObj(x1,y1,w1,h1,x2,y2,w2,h2:integer):boolean; begin if (x1+w1>x2) and (x1y2) and (y1 MAP_W * TILE_SIZE); end; function onMapObjectCheck(x, y, w, h : Integer) : Boolean; begin onMapObjectCheck := mapBoundCheck(x, y) or mapBoundCheck(x + w, y + h); end; function isSolid(x, y, velx, vely:integer):boolean; begin isSolid := getBlockColl(getMap(x, y)) <> 0; end; function mapColl(x, y, w, h, velx, vely:integer):boolean; var i, j:integer; minx, miny, maxx, maxy:integer; begin if onMapObjectCheck(x, y, w, h) then begin mapColl := true; exit; end; minx:=x div TILE_SIZE; miny:=y div TILE_SIZE; maxx:=(x+w-1) div TILE_SIZE; maxy:=(y+h-1) div TILE_SIZE; for i:=minx to maxx do for j:=miny to maxy do begin if isSolid(i, j, velx, vely) then begin mapColl:=true; exit; end; end; end; function canSeeObj(x1, y1, x2, y2:integer):boolean; var deltax, deltay:integer; signx, signy:integer; error, error2:integer; begin x1:=x1/TILE_SIZE; y1:=y1/TILE_SIZE; x2:=x2/TILE_SIZE; y2:=y2/TILE_SIZE; deltax:=abs(x2-x1); deltay:=abs(y2-y1); if x1x2) or (y1<>y2)) do begin if isSolid(x1, y1, 0, 0) then exit; error2:=error<<1; if error2>-deltaY then begin error:=error-deltaY; x1:=x1+signX; end; if error2MAX_VELY then vely:=MAX_VELY; jmp:=false; if vely>0 then for i:=1 to vely do begin y:=y+1; if mapColl(x, y, w, h, velx, vely) then begin y:=y-1; vely:=0; jmp:=true; break; end; end; else for i:=1 to abs(vely) do begin y:=y-1; if mapColl(x, y, w, h, velx, vely) then begin y:=y+1; vely:=0; jmp:=false; break; end; end; end; function fixVYup:boolean; begin if (vely>-5) and (mapCollType(49, x, y, w, h) or mapCollType(103, x, y, w, h) or mapCollType(108, x, y, w, h)) then vely:=vely-2; else if (vely>-4) and (mapCollType(50, x, y, w, h) or mapCollType(51, x, y, w, h)) then vely:=vely-2; else fixVYup:=true; end; procedure fixVYdown; begin if (vely>5) and (mapCollType(49, x, y, w, h) or mapCollType(103, x, y, w, h)) then vely:=5; else if (vely>4) and (mapCollType(50, x, y, w, h) or mapCollType(51, x, y, w, h)) then vely:=4; end; procedure jumpObj(vel:integer); begin if fixVYup then if jmp then begin vely:=-vel; jmp:=false; end; end; procedure calcX; var i:integer; begin if velx>0 then for i:=1 to velx do begin x:=x+1; if mapColl(x, y, w, h, velx, vely) then begin x:=x-1; velx:=0; break; end; end; else if velx<0 then for i:=1 to abs(velx) do //there for-downto-do have a bug! begin x:=x-1; if mapColl(x, y, w, h, velx, vely) then begin x:=x+1; velx:=0; break; end; end; if velx>0 then velx:=velx-1; else if velx<0 then velx:=velx+1; end; procedure calcY; var i:integer; begin if vely>0 then for i:=1 to vely do begin y:=y+1; if mapColl(x, y, w, h, velx, vely) then begin y:=y-1; vely:=0; break; end; end; else if vely<0 then for i:=1 to abs(vely) do //there for-downto-do have a bug! begin y:=y-1; if mapColl(x, y, w, h, velx, vely) then begin y:=y+1; velx:=0; break; end; end; if vely>0 then vely:=vely-1; else if vely<0 then vely:=vely+1; end; function getX:integer; begin getX:=x; end; function getY:integer; begin getY:=y; end; function getVelX:integer; begin getVelX:=velx; end; function getVelY:integer; begin getVelY:=vely; end; function getJmp:boolean; begin getJmp:=jmp; end; procedure calc(gravity:boolean); begin calcX; if gravity then begin calcGravity; fixVYdown; end; else calcY; end; end.