DEADSOFTWARE

Small refactoring of physics module
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 8 Sep 2017 16:33:32 +0000 (19:33 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 8 Sep 2017 16:33:32 +0000 (19:33 +0300)
BUGS
src/drop.mpsrc
src/mobs.pas
src/phy.pas
src/player.mpsrc

diff --git a/BUGS b/BUGS
index a3ecce904a5d4aeeef0c830f7807080da6d2c860..d57ab45883f859ba3a04f41ac81ddda75ef85f37 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -1,51 +1,38 @@
-(+) - Исправлено. Ну или типа того.
-(*) - Не критично и/или слишком сложно что бы сделать по-быстрому.
+- Реализованы не все мобы которые были
+    * Курица
+    * Корова
+    * Гриная корова
+    * Крипер
+    * Свинья
+    * Пигмен
+    * Овца
+    * Паук
+- Добавить ещё мобов
+    * Спрут
+    * Пещерный паук
+- Добавить эффекты при смерти мобов
+- Мобы не дохнут от солнечного света
+- Под водой скорость разлома блоков не уменьшается
+- При создании мира с сундуком, оный может висеть в воздухе
+- Иногда вместо травы генерируется грязь. (баг или фича - хз)
+- Починить спавнеры
+- Починить установку блока при прыжке
+- По лестнице/воде можно лезть даже если она стоит выше игрока
+- Даже в четвёртой альфе грибы генерировались в пещерах! Нужно вернуть!
+- Предметы не сгорают в лаве (и никогда не сгорали, но всё же)
+- Не сбрасывается анимация игрока при старте новой игры
+- Кактусы не убивают
 
-+ Можно выпасть за гранцу карты
-+ Выпадение за карту после загрузки мира
-+ Ломаются кактусы и снег на старте игры
-Реализованы не все мобы которые были
-  + Зомби
-    Курица
-    Корова
-    Гриная корова
-    Крипер
-    Свинья
-    Пигмен
-    Овца
-    Паук
-Зомби не может номально выпрыгнуть из воды
-Мобы не дохнут от солнечного света
-+ Убогая текстура дождя
-* Медленное обновление падающих блоков
-+ Какая-то фигня со светом на старте игры
-+ У кого-то почему-то не масштабируется экран
-От падения с высоты нет урона
-Под водой скорость разлома блоков не уменьшается
-* Не зажимаются две кнопки одновременно (это вообще решаемо?)
-* В бете 8 была поддержка звука, надо вернуть.
-* Запилить загрузку старых сохранений (см. cavecraft forever)
-+ Софтклавиши для переключения предметов на ремне перепутаны
-+ Печи и мобы не сохраняются и не загружаются (не забыть инкрементировать версию формата карт)
-При создании мира с сундуком, оный может висеть в воздухе
-+ Зависание при попытке листать пустой список сохранений
-Иногда вместо травы генерируется грязь. (баг или фича - хз)
-Перепроверить генерацию предметов в cокровищницах
-Починить спавнеры
-+ Уголь встречается на поверхности реже чем железо
-Починить установку блока при прыжке
-Перепроверить рост деревьев
-+ Печь не светится когда работает
-* Потеря контрастности при малом количестве источников света 
-+ Слишком много золота
-* Курсор на ремне должен быть чётче
-+ Один уголь выплавляет 7 предметов, хотя должно быть 8
-По лестнице можно лезть даже если она стоит выше игрока
-+ Игрок возраждается в точке своей смерти, вместо точки спавна
-+ От больших грибов больно уж чорные тени. У тыкв тоже надо поправить.
-После удаления всех сохранений кнопки остаются на вид активными
-Даже в четвёртой альфе грибы генерировались в пещерах! Нужно вернуть!
-+ Текстурпаки вроде как не работают
-+ Нужно автоматически генерировать манифест и jad
-* Предметы не сгорают в лаве (и никогда не сгорали, но всё же)
-Нужно избавиться от библеотек-блобов
+- Запилить блочный формат сохранений с переменным числом записей и версионированием блоков.
+- Перепроверить генерацию предметов в cокровищницах
+- Перепроверить рост деревьев
+
+- Курсор на ремне должен быть чётче
+- В бете 8 была поддержка звука, надо вернуть.
+- Медленное обновление падающих блоков
+- Потеря контрастности при малом количестве источников света 
+- После удаления всех сохранений кнопки остаются на вид активными
+
+- Запилить загрузку старых сохранений (см. cavecraft forever)
+- Не зажимаются две кнопки одновременно (это вообще решаемо в MP?)
+- Нужно избавиться от библеотек-блобов
index a691f98beb2a6ccf62830a85632598b463f2fe40..e6f95cd28668e8be4d4b7d97c42b270d9eb61608 100644 (file)
@@ -131,11 +131,11 @@ implementation
     for i:=0 to MAX_DROP do\r
      if isNull(i)=false then\r
       begin\r
-       phy.loadObject(drop_x[i], drop_y[i], DROP_W, DROP_H, 0, drop_vely[i], false);\r
-       phy.calc(true);\r
-       drop_x[i]:=phy.getX;\r
-       drop_y[i]:=phy.getY;\r
-       drop_vely[i]:=phy.getVelY;\r
+       Phy.SetObject(drop_x[i], drop_y[i], DROP_W, DROP_H, 0, drop_vely[i], false);\r
+       Phy.Step(true);\r
+       drop_x[i]:=Phy.GetX;\r
+       drop_y[i]:=Phy.GetY;\r
+       drop_vely[i]:=Phy.GetVY;\r
       end;\r
   end;\r
 \r
index c255d0ea2f265ad7b19bdcce60a44c70452e5b48..519cf9cd0a6f698634bbf94fecb90aaa142d86c5 100644 (file)
@@ -44,16 +44,16 @@ implementation
 \r
   procedure UseObject(i : integer);\r
     begin\r
-      Phy.LoadObject(mx[i], my[i], tw[mtype[i]], th[mtype[i]], mvx[i], mvy[i], mjump[i]);\r
+      Phy.SetObject(mx[i], my[i], tw[mtype[i]], th[mtype[i]], mvx[i], mvy[i], mjump[i]);\r
     end;\r
 \r
   procedure UpdateObject(i : integer);\r
     begin\r
       mx[i] := Phy.GetX;\r
       my[i] := Phy.GetY;\r
-      mvx[i] := Phy.GetVelX;\r
-      mvy[i] := Phy.GetVelY;\r
-      mjump[i] := Phy.GetJmp;\r
+      mvx[i] := Phy.GetVX;\r
+      mvy[i] := Phy.GetVY;\r
+      mjump[i] := Phy.GetJump;\r
     end;\r
 \r
   procedure InitTab(typ, w, h, hp, jump : integer);\r
@@ -93,13 +93,13 @@ implementation
       else if vec > 0 then x := (mx[i] + GetW(i) + 4) / 16;\r
       else x := (mx[i] + GetW(i) / 2) / 16;\r
       y := (my[i] + GetH(i) - 8) / 16;\r
-      result := Phy.IsSolid(x, y, mvx[i] + vec, mvy[i]);\r
+      result := Phy.IsSolid(x, y);\r
     end;\r
 \r
   procedure Swim(i, vec : integer);\r
     begin\r
-      if Phy.MapCollType(50, mx[i], my[i], GetW(i), GetH(i) / 2) or\r
-         Phy.MapCollType(51, mx[i], my[i], GetW(i), GetH(i) / 2)\r
+      if Phy.AreaWithBlock(50, mx[i], my[i], GetW(i), GetH(i) / 2) or\r
+         Phy.AreaWithBlock(51, mx[i], my[i], GetW(i), GetH(i) / 2)\r
       then begin\r
         if (vec <> 0) and IsSolidStep(i, vec) then mvy[i] := -10 else mvy[i] := -2;\r
       end;\r
@@ -123,13 +123,13 @@ implementation
   procedure Jump(i, vec : integer);\r
     begin\r
       UseObject(i);\r
-      Phy.JumpObj(GetJumpHeight(i));\r
+      Phy.Jump(GetJumpHeight(i));\r
       UpdateObject(i);\r
     end;\r
 \r
   function CollisionWithPlayer(i : integer) : boolean;\r
     begin\r
-      result := CollTwoObj(\r
+      result := Phy.IntersectRects(\r
         mx[i], my[i], GetW(i), GetH(i),\r
         Player.GetX, Player.GetY, Player.GetW, Player.GetH\r
       );\r
@@ -141,10 +141,9 @@ implementation
     begin\r
       x := mx[i] + GetW(i) / 2;\r
       y := my[i] + GetH(i) / 2;\r
-      if mtype[i] = zomby then\r
-        begin\r
-          Drop.Create(Items.rottenMeat, x, y, Random(3));\r
-        end;\r
+      if mtype[i] = zomby then begin\r
+        Drop.Create(Items.rottenMeat, x, y, Random(3));\r
+      end;\r
       mtype[i] := none;\r
     end;\r
 \r
@@ -180,7 +179,7 @@ implementation
 \r
       (* Вижу игрока - сразу агрюсь и бегу за ним некоторое время *)\r
       if (mpos[i] = 0) and (Player.GetX - mx[i] < 0) or (mpos[i] = 1) and (Player.GetX - mx[i] > 0) then\r
-        if Phy.CanSeeObj(mx[i], my[i], Player.GetX, Player.GetY) then\r
+        if Phy.RayTraced(mx[i], my[i], Player.GetX, Player.GetY) then\r
           begin\r
             mb[i] := angryTime;\r
             mc[i] := angry;\r
@@ -206,7 +205,7 @@ implementation
         if mb[i] <= 0 then mc[i] := stay;\r
       end else if mc[i] = angry then begin\r
         if mb[i] <= 0 then begin\r
-          if Phy.CanSeeObj(mx[i], my[i], Player.GetX, Player.GetY) then begin\r
+          if Phy.RayTraced(mx[i], my[i], Player.GetX, Player.GetY) then begin\r
             (* Видижу игрока - устанавливаю время преследования *)\r
             mb[i] := angryTime;\r
           end else begin\r
@@ -272,7 +271,7 @@ implementation
       i : integer;\r
     begin\r
       for i := 0 to lastMob do if mtype[i] <> none then\r
-        if CollTwoObj(x, y, w, h, mx[i], my[i], GetW(i), GetH(i)) then\r
+        if Phy.IntersectRects(x, y, w, h, mx[i], my[i], GetW(i), GetH(i)) then\r
           begin\r
             mvx[i] := mvx[i] + addvx;\r
             mvy[i] := mvy[i] + addvy;\r
@@ -302,7 +301,7 @@ implementation
       for i := 0 to lastMob do\r
         begin\r
           UseObject(i);\r
-          Phy.Calc(true);\r
+          Phy.Step(true);\r
           UpdateObject(i);\r
         end;\r
     end;\r
index 431f18034826a9fc28e56ff6b1c9cedc39e0a947..2b795c4d8bc3524aac4cbec37b4e4f385d3bf073 100644 (file)
-unit phy;\r
+unit Phy;\r
 \r
 interface\r
- procedure loadObject(_x, _y, _w, _h, _velx, _vely:integer; _jmp:boolean);\r
 \r
- function isSolid(x, y, velx, vely:integer):boolean;\r
+  function IsSolid(x, y : integer) : boolean;\r
+  function RayTraced(x1, y1, x2, y2 : integer) : boolean;\r
+  function AreaWithBlock(block, x, y, w, h : integer) : boolean;\r
+  function IntersectRects(x1, y1, w1, h1, x2, y2, w2, h2 : integer) : boolean;\r
 \r
- function mapCollType(_type, x, y, w, h:integer):boolean;\r
+  procedure SetObject(_x, _y, _w, _h, _vx, _vy : integer; _jmp : boolean);\r
+  procedure Jump(vel : integer);\r
+  procedure Step(gravity : boolean);\r
 \r
- function CollTwoObj(x1,y1,w1,h1,x2,y2,w2,h2:integer):boolean;\r
-\r
- procedure jumpObj(vel:integer);\r
- procedure calc(gravity:boolean);\r
-\r
- function getX:integer;\r
- function getY:integer;\r
- function getVelX:integer;\r
- function getVelY:integer;\r
- function getJmp:boolean;\r
-\r
- function canSeeObj(x1, y1, x2, y2:integer):boolean;\r
+  function GetX : integer;\r
+  function GetY : integer;\r
+  function GetVX : integer;\r
+  function GetVY : integer;\r
+  function GetGCV : integer;\r
+  function GetJump : boolean;\r
 \r
 implementation\r
- uses items_store, maps, vars;\r
- const\r
-  MAX_VELY=32;\r
-  TILE_SIZE=16;\r
- var\r
-  x, y, w, h, velx, vely:integer;\r
-  jmp:boolean;\r
-\r
-function CollTwoObj(x1,y1,w1,h1,x2,y2,w2,h2:integer):boolean;\r
- begin\r
-  if (x1+w1>x2) and (x1<x2+w2) and (y1+h1>y2) and (y1<y2+h2) then\r
-   CollTwoObj:=true;\r
- end;\r
-\r
- procedure loadObject(_x, _y, _w, _h, _velx, _vely:integer; _jmp:boolean);\r
-  begin\r
-   x:=_x;\r
-   y:=_y;\r
-   w:=_w;\r
-   h:=_h;\r
-   velx:=_velx;\r
-   vely:=_vely;\r
-   jmp:=_jmp;\r
-  end;\r
 \r
- function mapBoundCheck(x, y : Integer) : Boolean;\r
-   begin\r
-     mapBoundCheck := (x < 0) or (x > MAP_W * TILE_SIZE);\r
-   end;\r
+  uses items_store, maps, vars;\r
 \r
- function onMapObjectCheck(x, y, w, h : Integer) : Boolean;\r
-   begin\r
-     onMapObjectCheck := mapBoundCheck(x, y) or mapBoundCheck(x + w, y + h);\r
-   end;\r
-\r
- function isSolid(x, y, velx, vely:integer):boolean;\r
-   begin\r
-     isSolid := getBlockColl(getMap(x, y)) <> 0;\r
-   end;\r
+  const\r
+    maxVelocity = 32;\r
+    tileSize = 16;\r
 \r
- function mapColl(x, y, w, h, velx, vely:integer):boolean;\r
-   var\r
-    i, j:integer;\r
-    minx, miny, maxx, maxy:integer;\r
-   begin\r
-     if onMapObjectCheck(x, y, w, h) then\r
-       begin\r
-         mapColl := true;\r
-         exit;\r
-       end;\r
-\r
-     minx:=x div TILE_SIZE;\r
-     miny:=y div TILE_SIZE;\r
-     maxx:=(x+w-1) div TILE_SIZE;\r
-     maxy:=(y+h-1) div TILE_SIZE;\r
-     for i:=minx to maxx do\r
-     for j:=miny to maxy do\r
-       begin\r
-         if isSolid(i, j, velx, vely) then\r
-           begin\r
-             mapColl:=true;\r
-             exit;\r
-           end;\r
-       end;\r
-  end;\r
-\r
- function canSeeObj(x1, y1, x2, y2:integer):boolean;\r
   var\r
-   deltax, deltay:integer;\r
-   signx, signy:integer;\r
-   error, error2:integer;\r
-  begin\r
-   x1:=x1/TILE_SIZE;\r
-   y1:=y1/TILE_SIZE;\r
-   x2:=x2/TILE_SIZE;\r
-   y2:=y2/TILE_SIZE;\r
-  \r
-   deltax:=abs(x2-x1);\r
-   deltay:=abs(y2-y1);\r
+    x, y, w, h, vx, vy, gcv : integer;\r
+    jmp : boolean;\r
 \r
-   if x1<x2 then\r
-    signx:=1;\r
-   else\r
-    signx:=-1;\r
+  function IntersectRects(x1, y1, w1, h1, x2, y2, w2, h2 : integer) : boolean;\r
+    begin\r
+      result := (x1 + w1 > x2) and (x1 < x2 + w2) and (y1 + h1 > y2) and (y1 < y2 + h2);\r
+    end;\r
 \r
-   if y1<y2 then\r
-    signy:=1;\r
-   else\r
-    signy:=-1;\r
+  procedure SetObject(x_, y_, w_, h_, vx_, vy_ : integer; jmp_ : boolean);\r
+    begin\r
+      x := x_;\r
+      y := y_;\r
+      w := w_;\r
+      h := h_;\r
+      vx := vx_;\r
+      vy := vy_;\r
+      jmp := jmp_;\r
+    end;\r
 \r
-   error:=deltaX-deltaY;\r
+  function MapBoundCheck(x, y : Integer) : Boolean;\r
+    begin\r
+      result := (x < 0) or (x > MAP_W * tileSize);\r
+    end;\r
 \r
-   while((x1<>x2) or (y1<>y2)) do\r
+  function OnMapObjectCheck(x, y, w, h : Integer) : Boolean;\r
     begin\r
-     if isSolid(x1, y1, 0, 0) then\r
-      exit;\r
-\r
-     error2:=error<<1;\r
-     if error2>-deltaY then\r
-      begin\r
-       error:=error-deltaY;\r
-       x1:=x1+signX;\r
-      end;\r
+      result := MapBoundCheck(x, y) or MapBoundCheck(x + w, y + h);\r
+    end;\r
 \r
-     if error2<deltaX then\r
-      begin\r
-       error:=error+deltaX;\r
-       y1:=y1+signY;\r
-      end;\r
+  function IsSolid(x, y : integer) : boolean;\r
+    begin\r
+      isSolid := GetBlockColl(getMap(x, y)) <> 0;\r
     end;\r
-   canSeeObj:=true;\r
-  end;\r
 \r
- function mapCollType(_type, x, y, w, h:integer):boolean;\r
-  var\r
-   i, j:integer;\r
-   minx, miny, maxx, maxy:integer;\r
-  begin\r
-   minx:=x div TILE_SIZE;\r
-   miny:=y div TILE_SIZE;\r
-   maxx:=(x+w-1) div TILE_SIZE;\r
-   maxy:=(y+h-1) div TILE_SIZE;\r
-   for i:=minx to maxx do\r
-   for j:=miny to maxy do\r
+  function MapColl(x, y, w, h : integer) : boolean;\r
+    var\r
+      i, j : integer;\r
+      minx, miny, maxx, maxy : integer;\r
     begin\r
-     if getMap(i, j)=_type then\r
-      begin\r
-       mapCollType:=true;\r
-       exit;\r
+      if OnMapObjectCheck(x, y, w, h) then begin\r
+        MapColl := true;\r
+        exit;\r
       end;\r
+\r
+      minx := x div tileSize;\r
+      miny := y div tileSize;\r
+      maxx := (x + w - 1) div tileSize;\r
+      maxy := (y + h - 1) div tileSize;\r
+\r
+      for j := miny to maxy do\r
+        for i := minx to maxx do\r
+          if IsSolid(i, j) then begin\r
+            MapColl:=true;\r
+            exit;\r
+          end;\r
     end;\r
- end;\r
 \r
- procedure calcGravity;\r
-  var\r
-   i:integer;\r
-  begin\r
-   vely:=vely+1;\r
-   if vely>MAX_VELY then\r
-    vely:=MAX_VELY;\r
-\r
-   jmp:=false;\r
-\r
-   if vely>0 then\r
-    for i:=1 to vely do\r
-     begin\r
-      y:=y+1;\r
-      if mapColl(x, y, w, h, velx, vely) then\r
-       begin\r
-        y:=y-1;\r
-        vely:=0;\r
-        jmp:=true;\r
-        break;\r
+ function RayTraced(x1, y1, x2, y2 : integer) : boolean;\r
+   var\r
+     deltax, deltay : integer;\r
+     signx, signy : integer;\r
+     error, error2 : integer;\r
+   begin\r
+     x1 := x1 / tileSize;\r
+     y1 := y1 / tileSize;\r
+     x2 := x2 / tileSize;\r
+     y2 := y2 / tileSize;\r
+  \r
+     deltax := Abs(x2 - x1);\r
+     deltay := Abs(y2 - y1);\r
+\r
+     if x1 < x2 then signx := 1 else signx := -1;\r
+     if y1 < y2 then signy := 1 else signy := -1;\r
+     error := deltaX - deltaY;\r
+\r
+     while (x1 <> x2) or (y1 <> y2) do begin\r
+       if IsSolid(x1, y1) then exit;\r
+\r
+       error2 := error << 1;\r
+       if error2 > -deltaY then begin\r
+         error := error - deltaY;\r
+         x1 := x1 + signX;\r
        end;\r
-     end;\r
-   else\r
-    for i:=1 to abs(vely) do\r
-     begin\r
-      y:=y-1;\r
-      if mapColl(x, y, w, h, velx, vely) then\r
-       begin\r
-        y:=y+1;\r
-        vely:=0;\r
-        jmp:=false;\r
-        break;\r
+\r
+       if error2 < deltaX then begin\r
+         error := error + deltaX;\r
+         y1 := y1 + signY;\r
        end;\r
      end;\r
-  end;\r
 \r
- function fixVYup:boolean;\r
-  begin\r
-   if (vely>-5) and\r
-      (mapCollType(49, x, y, w, h) or \r
-       mapCollType(103, x, y, w, h) or\r
-       mapCollType(108, x, y, w, h)) then\r
-        vely:=vely-2;\r
-   else\r
-   if (vely>-4) and\r
-      (mapCollType(50, x, y, w, h) or \r
-       mapCollType(51, x, y, w, h)) then\r
-        vely:=vely-2;\r
-   else\r
-    fixVYup:=true;\r
-  end;\r
+     result := true;\r
+   end;\r
 \r
- procedure fixVYdown;\r
-  begin\r
-   if (vely>5) and\r
-      (mapCollType(49, x, y, w, h) or \r
-       mapCollType(103, x, y, w, h)) then\r
-        vely:=5;\r
-   else\r
-   if (vely>4) and\r
-      (mapCollType(50, x, y, w, h) or \r
-       mapCollType(51, x, y, w, h)) then\r
-        vely:=4;\r
-  end;\r
+  function AreaWithBlock(block, x, y, w, h : integer) : boolean;\r
+    var\r
+      i, j : integer;\r
+      minx, miny, maxx, maxy : integer;\r
+    begin\r
+      minx := x div tileSize;\r
+      miny := y div tileSize;\r
+      maxx := (x + w - 1) div tileSize;\r
+      maxy := (y + h - 1) div tileSize;\r
+      for j := miny to maxy do\r
+        for i := minx to maxx do\r
+          if GetMap(i, j) = block then begin\r
+            result := true;\r
+            exit;\r
+          end;\r
+    end;\r
 \r
- procedure jumpObj(vel:integer);\r
-  begin\r
-   if fixVYup then\r
-   if jmp then\r
+  function Signum(x : integer) : integer;\r
     begin\r
-     vely:=-vel;\r
-     jmp:=false;\r
+      if x > 0 then Signum := 1\r
+      else if x < 0 then Signum := -1\r
+      else Signum := 0\r
     end;\r
-  end;\r
 \r
- procedure calcX;\r
-  var\r
-   i:integer;\r
-  begin\r
-   if velx>0 then\r
-    for i:=1 to velx do\r
-     begin\r
-      x:=x+1;\r
-      if mapColl(x, y, w, h, velx, vely) then\r
-       begin\r
-        x:=x-1;\r
-        velx:=0;\r
-        break;\r
-       end;\r
-     end;\r
-   else\r
-   if velx<0 then\r
-    for i:=1 to abs(velx) do //there for-downto-do have a bug!\r
-     begin\r
-      x:=x-1;\r
-      if mapColl(x, y, w, h, velx, vely) then\r
-       begin\r
-        x:=x+1;\r
-        velx:=0;\r
-        break;\r
-       end;\r
-     end;\r
+  procedure CalcGravity;\r
+    var\r
+      vec : integer;\r
+      i : integer;\r
+    begin\r
+      gcv := 0;\r
+      jmp := false;\r
+      vy := vy + 1;\r
+      if vy > maxVelocity then vy := maxVelocity;\r
+\r
+      i := Abs(vy);\r
+      vec := Signum(vy);\r
+      while (i > 0) and not MapColl(x, y + vec, w, h) do begin\r
+        y := y + vec;\r
+        i := i - 1;\r
+      end;\r
+      if i > 0 then begin\r
+        vy := 0;\r
+        gcv := i * vec;\r
+        jmp := true;\r
+      end;\r
+    end;\r
 \r
-   if velx>0 then\r
-    velx:=velx-1;\r
-   else\r
-   if velx<0 then\r
-    velx:=velx+1;\r
-  end;\r
+  function FixVYup : boolean;\r
+    begin\r
+      if (vy > -5) and\r
+         (AreaWithBlock(49, x, y, w, h) or\r
+         AreaWithBlock(103, x, y, w, h) or\r
+         AreaWithBlock(108, x, y, w, h))\r
+      then begin\r
+        vy := vy - 2;\r
+      end else if (vy > -4) and\r
+        (AreaWithBlock(50, x, y, w, h) or \r
+        AreaWithBlock(51, x, y, w, h))\r
+      then begin\r
+        vy := vy - 2;\r
+      end else begin\r
+        result := true;\r
+      end;\r
+    end;\r
 \r
- procedure calcY;\r
-  var\r
-   i:integer;\r
-  begin\r
-   if vely>0 then\r
-    for i:=1 to vely do\r
-     begin\r
-      y:=y+1;\r
-      if mapColl(x, y, w, h, velx, vely) then\r
-       begin\r
-        y:=y-1;\r
-        vely:=0;\r
-        break;\r
-       end;\r
-     end;\r
-   else\r
-   if vely<0 then\r
-    for i:=1 to abs(vely) do //there for-downto-do have a bug!\r
-     begin\r
-      y:=y-1;\r
-      if mapColl(x, y, w, h, velx, vely) then\r
-       begin\r
-        y:=y+1;\r
-        velx:=0;\r
-        break;\r
-       end;\r
-     end;\r
+  procedure FixVYdown;\r
+    begin\r
+      if (vy > 5) and\r
+        (AreaWithBlock(49, x, y, w, h) or \r
+        AreaWithBlock(103, x, y, w, h))\r
+      then begin\r
+        vy := 5;\r
+      end else if (vy > 4) and\r
+        (AreaWithBlock(50, x, y, w, h) or \r
+         AreaWithBlock(51, x, y, w, h))\r
+      then begin\r
+        vy := 4;\r
+      end;\r
+    end;\r
 \r
-   if vely>0 then\r
-    vely:=vely-1;\r
-   else\r
-   if vely<0 then\r
-    vely:=vely+1;\r
-  end;\r
+  procedure Jump(vel : integer);\r
+    begin\r
+      if jmp and FixVYup then begin\r
+        vy := -vel;\r
+        jmp := false;\r
+      end;\r
+    end;\r
 \r
- function getX:integer;\r
-  begin\r
-   getX:=x;\r
-  end;\r
+  procedure CalcX;\r
+    var\r
+      vec : integer;\r
+      i : integer;\r
+    begin\r
+      i := Abs(vx);\r
+      vec := Signum(vx);\r
+      while (i > 0) and not MapColl(x + vec, y, w, h) do begin\r
+        x := x + vec;\r
+        i := i - 1;\r
+      end;\r
+      if i > 0 then vx := 0 else vx := vx - vec;\r
+    end;\r
 \r
- function getY:integer;\r
-  begin\r
-   getY:=y;\r
-  end;\r
+  procedure CalcY;\r
+    var\r
+      vec : integer;\r
+      i : integer;\r
+    begin\r
+      i := Abs(vy);\r
+      vec := Signum(vy);\r
+      while (i > 0) and not MapColl(x, y + vec, w, h) do begin\r
+        y := y + vec;\r
+        i := i - 1;\r
+      end;\r
+      if i > 0 then vy := 0 else vy := vy - vec;\r
+    end;\r
 \r
function getVelX:integer;\r
-  begin\r
-   getVelX:=velx;\r
-  end;\r
 function GetX : integer;\r
+    begin\r
+      result := x;\r
+    end;\r
 \r
function getVelY:integer;\r
-  begin\r
-   getVelY:=vely;\r
-  end;\r
 function GetY : integer;\r
+    begin\r
+      result := y;\r
+    end;\r
 \r
- function getJmp:boolean;\r
-  begin\r
-   getJmp:=jmp;\r
-  end;\r
+  function GetVX : integer;\r
+    begin\r
+      result := vx;\r
+    end;\r
+\r
+  function GetVY : integer;\r
+    begin\r
+      result := vy;\r
+    end;\r
 \r
- procedure calc(gravity:boolean);\r
-  begin\r
-   calcX;\r
+  function GetGCV : integer;\r
+    begin\r
+      result := gcv;\r
+    end;\r
 \r
-   if gravity then\r
+  function GetJump : boolean;\r
     begin\r
-      calcGravity;\r
-      fixVYdown;\r
+      result := jmp;\r
     end;\r
-   else \r
-    calcY;\r
+\r
+  procedure Step(gravity : boolean);\r
+    begin\r
+      CalcX;\r
+      if gravity then begin\r
+        CalcGravity;\r
+        FixVYdown;\r
+      end else begin \r
+        CalcY;\r
+      end;\r
   end;\r
 \r
 end.\r
index 1891939e113195d38530b4fb149d2a35378a3c43..812a2b46829db0f2f7569a59afe7fb310bb5b3c5 100644 (file)
 unit player;\r
 \r
 interface\r
- const\r
-  ANIM_HAND=0;\r
-  ANIM_LEGS=1;\r
-\r
- var\r
-  fly:boolean;\r
-  hp, hunger, air:integer;\r
-  posi:integer;//Сторона в которую повёрнут игрок\r
-  velx,vely:integer;//Переменные для физики игрока\r
-  jmp, an_pr:boolean;\r
-  s_get_drp:boolean;\r
-  invslot:integer;\r
-\r
- procedure setX(val:integer);\r
- procedure setY(val:integer);\r
- function getX:integer;\r
- function getY:integer;\r
- function getW:integer;\r
- function getH:integer;\r
-\r
- procedure loadSkin(str, path:string);\r
- procedure freeSkin;\r
- procedure draw(camx, camy:integer);\r
- procedure playAnim(anim:integer);\r
- procedure cancelAnim(anim:integer);\r
-\r
- procedure dropItem(item, sum:integer);\r
- procedure biteIt(hp : integer; vector : integer);\r
-\r
- procedure calcPhysics;\r
-\r
- procedure gotoUP;\r
- procedure gotoDOWN;\r
- procedure gotoLEFT;\r
- procedure gotoRIGHT;\r
-\r
- procedure getDrop;\r
+\r
+  const\r
+    ANIM_HAND=0;\r
+    ANIM_LEGS=1;\r
+\r
+  var\r
+    fly : boolean;\r
+    hp, hunger, air : integer;\r
+    posi : integer;\r
+    velx, vely : integer;\r
+    jmp, an_pr : boolean;\r
+    s_get_drp : boolean;\r
+    invslot : integer;\r
+\r
+  function GetX : integer;\r
+  function GetY : integer;\r
+  function GetW : integer;\r
+  function GetH : integer;\r
+  procedure SetX(val : integer);\r
+  procedure SetY(val : integer);\r
+\r
+  procedure LoadSkin(str, path : string);\r
+  procedure FreeSkin;\r
+  procedure Draw(camx, camy : integer);\r
+  procedure PlayAnim(anim : integer);\r
+  procedure CancelAnim(anim : integer);\r
+\r
+  procedure DropItem(item, sum : integer);\r
+  procedure BiteIt(hp : integer; vector : integer);\r
+\r
+  procedure CalcPhysics;\r
+\r
+  procedure GotoUP;\r
+  procedure GotoDOWN;\r
+  procedure GotoLEFT;\r
+  procedure GotoRIGHT;\r
+\r
+  procedure GetDrop;\r
 \r
 implementation\r
- uses func, phy, vars, Canvas, drop, items, jsr75i, inv;\r
- const\r
-  PLAYER_W=8;\r
-  PLAYER_H=32;\r
-  PLAYER_SPEED=2;\r
-\r
-  POSI_LEFT=0;\r
-  POSI_RIGHT=1;\r
-  PLAYER_ANIM_DEL=1;\r
- var\r
-  plx, ply:integer;\r
-\r
-  //Skin\r
-  PlayerBody: array [0..1] of image;\r
-  PlayerHand: array [0..1, 0..3] of image;\r
-  PlayerLegs: array [0..1, 0..2] of image;\r
-  animHand, animLegs, animDelay:integer;\r
-\r
- procedure setX(val:integer);\r
-  begin\r
-   plx:=val;\r
-  end;\r
-\r
- procedure setY(val:integer);\r
-  begin\r
-   ply:=val;\r
-  end;\r
-\r
- function getX:integer;\r
-  begin\r
-   getX:=plx;\r
-  end;\r
-\r
- function getY:integer;\r
-  begin\r
-   getY:=ply;\r
-  end;\r
-\r
- function getW:integer;\r
-  begin\r
-   getW:=PLAYER_W;\r
-  end;\r
-\r
- function getH:integer;\r
-  begin\r
-   getH:=PLAYER_H;\r
-  end;\r
-\r
- procedure setVelX(val:integer);\r
-  begin\r
-   velx:=val;\r
-  end;\r
-\r
- procedure setVelY(val:integer);\r
-  begin\r
-   vely:=val;\r
-  end;\r
-\r
- function getVelX:integer;\r
-  begin\r
-   getVelX:=velx;\r
-  end;\r
-\r
- function getVelY:integer;\r
-  begin\r
-   getVelY:=vely;\r
-  end;\r
-\r
- procedure setJmp(val:boolean);\r
-  begin\r
-   jmp:=val;\r
-  end;\r
-\r
- function getJmp:boolean;\r
-  begin\r
-   getJmp:=jmp;\r
-  end;\r
-\r
- procedure dropItem(item, sum:integer);\r
-  begin\r
-   if posi=POSI_LEFT then\r
-    drop.create(item, sum, getX-8, getY);\r
-   else\r
-    drop.create(item, sum, getX+getW, getY);\r
-  end;\r
-\r
- procedure loadSkin(str, path:string);\r
+\r
+  uses func, phy, vars, Canvas, drop, items, jsr75i, inv;\r
+\r
+  const\r
+    PLAYER_W=8;\r
+    PLAYER_H=32;\r
+    PLAYER_SPEED=2;\r
+    POSI_LEFT=0;\r
+    POSI_RIGHT=1;\r
+    PLAYER_ANIM_DEL=2;\r
+    jumpVelocity = 7;\r
+\r
   var\r
-   im:image;\r
-   i:integer;\r
-  begin\r
-   im:=ld_tex(str, path, 'mobs/');\r
+    plx, ply:integer;\r
+    playerBody: array [0..1] of image;\r
+    playerHand: array [0..1, 0..3] of image;\r
+    playerLegs: array [0..1, 0..2] of image;\r
+    animHand, animLegs, animDelay:integer;\r
 \r
-   PlayerBody[POSI_LEFT]:=rotate_image_from_image(im, 0, 0, 8, 20, 0);\r
-   PlayerBody[POSI_RIGHT]:=rotate_image_from_image(im, 8, 0, 8, 20, 0);\r
+  procedure SetX(val : integer);\r
+   begin\r
+     plx := val;\r
+   end;\r
 \r
-   PlayerHand[POSI_LEFT, 0]:=rotate_image_from_image(im, 40, 0, 4, 12, 0);\r
-   PlayerHand[POSI_RIGHT, 0]:=rotate_image_from_image(im, 44, 0, 4, 12, 0);\r
+  procedure SetY(val : integer);\r
+    begin\r
+      ply := val;\r
+    end;\r
 \r
-   for i:=1 to 3 do\r
+  function GetX : integer;\r
     begin\r
-     PlayerHand[POSI_LEFT, i]:=rotate_image_from_image(im, 16, (i-1)*6, 12, 6, 0);\r
-     PlayerHand[POSI_RIGHT, i]:=rotate_image_from_image(im, 28, (i-1)*6, 12, 6, 0);\r
+      result := plx;\r
     end;\r
 \r
-   for i:=0 to 2 do\r
+  function GetY : integer;\r
     begin\r
-     PlayerLegs[POSI_LEFT, i]:=rotate_image_from_image(im, i*12, 20, 12, 12, 0);\r
-     PlayerLegs[POSI_RIGHT, i]:=rotate_image_from_image(im, 36+i*12, 20, 12, 12, 0);\r
+      result := ply;\r
     end;\r
-  end;\r
 \r
- procedure freeSkin;\r
-  var\r
-   i, j:integer;\r
-   nullimg:image;\r
-  begin\r
-   for i:=0 to 1 do\r
+  function GetW : integer;\r
+    begin\r
+      result := PLAYER_W;\r
+    end;\r
+\r
+  function GetH : integer;\r
+    begin\r
+      result := PLAYER_H;\r
+    end;\r
+\r
+  procedure SetVelX(val : integer);\r
+    begin\r
+      velx := val;\r
+    end;\r
+\r
+  procedure SetVelY(val : integer);\r
+    begin\r
+      vely := val;\r
+    end;\r
+\r
+  function GetVelX : integer;\r
+    begin\r
+      result := velx;\r
+    end;\r
+\r
+  function GetVelY : integer;\r
+    begin\r
+      result := vely;\r
+    end;\r
+\r
+  procedure SetJmp(val : boolean);\r
+    begin\r
+     jmp := val;\r
+    end;\r
+\r
+  function GetJmp : boolean;\r
+    begin\r
+      result := jmp;\r
+    end;\r
+\r
+  procedure DropItem(item, sum : integer);\r
     begin\r
-     PlayerBody[i]:=nullimg;\r
-     for j:=0 to 3 do\r
-      PlayerHand[i, j]:=nullimg;\r
-     for j:=0 to 2 do\r
-      PlayerLegs[i, j]:=nullimg;\r
+      if posi = POSI_LEFT then Drop.Create(item, sum, GetX - 8, GetY);\r
+      else Drop.Create(item, sum, GetX + GetW, GetY);\r
     end;\r
-  end;\r
 \r
- procedure playAnim(anim:integer);\r
-  begin\r
-   if anim=ANIM_HAND then\r
+  procedure LoadSkin(str, path:string);\r
+    var\r
+      im : image;\r
+      i : integer;\r
     begin\r
-     animHand:=animHand+1;\r
-     if animHand>3 then\r
-      animHand:=1;\r
+      im := ld_tex(str, path, 'mobs/');\r
+      playerBody[POSI_LEFT] := rotate_image_from_image(im, 0, 0, 8, 20, 0);\r
+      playerBody[POSI_RIGHT] := rotate_image_from_image(im, 8, 0, 8, 20, 0);\r
+      playerHand[POSI_LEFT, 0] := rotate_image_from_image(im, 40, 0, 4, 12, 0);\r
+      playerHand[POSI_RIGHT, 0] := rotate_image_from_image(im, 44, 0, 4, 12, 0);\r
+      for i := 1 to 3 do begin\r
+        playerHand[POSI_LEFT, i] := rotate_image_from_image(im, 16, (i - 1) * 6, 12, 6, 0);\r
+        playerHand[POSI_RIGHT, i] := rotate_image_from_image(im, 28, (i - 1) * 6, 12, 6, 0);\r
+      end;\r
+      for i:=0 to 2 do begin\r
+        playerLegs[POSI_LEFT, i] := rotate_image_from_image(im, i * 12, 20, 12, 12, 0);\r
+        playerLegs[POSI_RIGHT, i] := rotate_image_from_image(im, 36 + i * 12, 20, 12, 12, 0);\r
+      end;\r
     end;\r
-   else\r
-   if anim=ANIM_LEGS then\r
+\r
+  procedure FreeSkin;\r
+    var\r
+      i, j : integer;\r
+      nullimg : image;\r
     begin\r
-     if animDelay=0 then\r
-      begin\r
-       animLegs:=animLegs+1;\r
-       if animLegs>2 then\r
-        animLegs:=0;\r
+      for i := 0 to 1 do begin\r
+        playerBody[i] := nullimg;\r
+        for j:=0 to 3 do playerHand[i, j] := nullimg;\r
+        for j:=0 to 2 do playerLegs[i, j] := nullimg;\r
       end;\r
+    end;\r
 \r
-     animDelay:=animDelay+1;\r
-     if animDelay>PLAYER_ANIM_DEL then\r
-      animDelay:=0;\r
+  procedure PlayAnim(anim : integer);\r
+    begin\r
+      if anim = ANIM_HAND then begin\r
+        animHand := animHand + 1;\r
+        if animHand > 3 then animHand:=1;\r
+      end else if anim = ANIM_LEGS then begin\r
+        if animDelay = 0 then begin\r
+          animLegs := animLegs + 1;\r
+          if animLegs > 2 then animLegs := 0;\r
+        end;\r
+        animDelay:=animDelay+1;\r
+        if animDelay > PLAYER_ANIM_DEL then animDelay := 0;\r
+      end;\r
     end;\r
-  end;\r
 \r
- procedure cancelAnim(anim:integer);\r
-  begin\r
-   if anim=ANIM_HAND then\r
+  procedure CancelAnim(anim : integer);\r
     begin\r
-     animHand:=0;\r
+      if anim = ANIM_HAND then animHand := 0;\r
+      else if anim = ANIM_LEGS then animLegs := 0;\r
     end;\r
-   else\r
-   if anim=ANIM_LEGS then\r
+\r
+  procedure Draw(camx, camy : integer);\r
+    var\r
+      x, y : integer;\r
     begin\r
-     animLegs:=0;\r
+      x := GetX;\r
+      y := GetY;\r
+      DrawImage(playerBody[posi], x - camx, y - camy);\r
+      DrawImage(playerLegs[posi, animLegs], x - 2 - camx, y + 20 - camy);\r
+\r
+      if animHand = 0 then DrawSmallItem(Inv.GetItem(invslot), x - camx, y + 14 - camy);\r
+      else if posi = POSI_RIGHT then DrawSmallItem(Inv.GetItem(invslot), x + 10 - camx, y + 5 - camy + animHand);\r
+      else if posi = POSI_LEFT then DrawSmallItem(Inv.GetItem(invslot), x - 10 - camx, y + 5 - camy + animHand);\r
+\r
+      if (animHand = 0) or (posi = POSI_RIGHT) then DrawImage(playerHand[posi, animHand], x + 2 - camx, y + 8 - camy);\r
+      else DrawImage(playerHand[posi, animHand], x - 6 - camx, y + 8 - camy);\r
     end;\r
-  end;\r
 \r
- procedure draw(camx, camy:integer);\r
-  var\r
-   x, y:integer;\r
-  begin\r
-   x:=getX;\r
-   y:=getY;\r
-\r
-   DrawImage(PlayerBody[posi], x-camx, y-camy);\r
-   DrawImage(PlayerLegs[posi, animLegs], x-2-camx, y+20-camy);\r
-\r
-   if animHand=0 then\r
-    drawSmallItem(inv.getItem(invslot), x-camx, y+14-camy);\r
-   else\r
-   if posi=POSI_RIGHT then\r
-    drawSmallItem(inv.getItem(invslot), x+10-camx, y+5-camy+animHand);\r
-   else\r
-   if posi=POSI_LEFT then\r
-    drawSmallItem(inv.getItem(invslot), x-10-camx, y+5-camy+animHand);\r
-\r
-   if (animHand=0) or (posi=POSI_RIGHT) then\r
-    DrawImage(PlayerHand[posi, animHand], x+2-camx, y+8-camy);\r
-   else\r
-    DrawImage(PlayerHand[posi, animHand], x-6-camx, y+8-camy);\r
-  end;\r
-\r
-  procedure biteIt(damage : integer; vector : integer);\r
-   begin\r
-    hp := hp - damage;\r
-   end;\r
+  procedure BiteIt(damage : integer; vector : integer);\r
+    begin\r
+      hp := hp - damage;\r
+      velx := velx + vector;\r
+    end;\r
 \r
-procedure loadPhy;\r
- begin\r
-  phy.loadObject(getX, getY, getW, getH, getVelX, getVelY, getJmp);\r
- end;\r
-\r
-procedure storePhy;\r
- begin\r
-  setX(phy.getX);\r
-  setY(phy.getY);\r
-  setVelX(phy.getVelX);\r
-  setVelY(phy.getVelY);\r
-  setJmp(phy.getJmp);\r
- end;\r
-\r
- //Player collision.\r
-{function coll:boolean;\r
- begin\r
-  coll:=CollObj(getX, getY, getW, getH);\r
- end;\r
-\r
-//Player collision by block id.\r
-function coll_bl(id:integer):boolean;\r
- begin\r
-  coll_bl:=CollObjBlock(getX, getY, getW, getH, id);\r
- end;\r
-\r
-//Player collision by XY.\r
-function coll_xy(xx,yy:integer):boolean;\r
- begin\r
-  coll_xy:=CollObjXY(getX, getY, getW, getH, xx, yy);\r
- end;\r
-\r
-//Controll jump velocity\r
-procedure jmp_ctrl;\r
- begin\r
-  if (coll_bl(49)) or (coll_bl(103)) or (coll_bl(108)) then\r
-   vely:=5;\r
-  if (coll_bl(50)) or (coll_bl(51)) then\r
-   vely:=4;\r
-  if (coll_bl(0)) and (coll_bl(50) or coll_bl(51)) then\r
-   vely:=7;\r
- end;\r
-\r
-//Controll fall velocity\r
- procedure phy_ctrl;\r
-  begin\r
-   if (coll_bl(49)) or (coll_bl(103)) then\r
-    vely:=-5;\r
-   if (coll_bl(50)) or (coll_bl(51)) then\r
-    if vely<-4 then\r
-     vely:=-4;\r
-  end;}\r
-\r
- procedure calcPhysics;\r
-  var\r
-   old_vely:integer;\r
-   cl:boolean;\r
-  begin\r
-   loadPhy;\r
-   phy.calc(not fly);\r
-   storePhy;\r
-\r
-   {if fly=false then\r
+  procedure LoadPhy;\r
     begin\r
-     old_vely:=vely;\r
-     calcGravY(getX, getY, getW, getH, CONST_PHY_ACC, vely, CONST_PHY_MAXVEL, jmp);\r
-     setY(PhyGetY);\r
-     vely:=PhyGetVelY;\r
-     jmp:=PhyGetJump;\r
-     cl:=PhyGetColl;\r
-\r
-     if cl then\r
-      if old_vely<-10 then\r
-       hp:=(hp-(abs(old_vely)-10));\r
-    end;}\r
-  end;\r
-\r
- procedure gotoUP;\r
-  begin\r
-   if fly then\r
-    setVelY(-PLAYER_SPEED);\r
-   else\r
+      Phy.SetObject(GetX, GetY, GetW, GetH, GetVelX, GetVelY, GetJmp);\r
+    end;\r
+\r
+  procedure StorePhy;\r
     begin\r
-     loadPhy;\r
-     jumpObj(7);\r
-     storePhy;\r
+      SetX(Phy.GetX);\r
+      SetY(Phy.GetY);\r
+      SetVelX(Phy.GetVX);\r
+      SetVelY(Phy.GetVY);\r
+      SetJmp(Phy.GetJump);\r
     end;\r
-  end;\r
 \r
procedure gotoDOWN;\r
-  begin\r
-   if fly then\r
-    setVelY(PLAYER_SPEED);\r
-  end;\r
 procedure CalcPhysics;\r
+    var\r
+      vel : integer;\r
+    begin\r
+      vel := vely;\r
 \r
procedure gotoLEFT;\r
-  begin\r
-   setVelX(-PLAYER_SPEED);\r
     LoadPhy;\r
+      Phy.Step(not fly);\r
+      StorePhy;\r
 \r
-   posi:=POSI_LEFT;\r
+      if (vel > 0) and (Phy.GetGCV - vel < -10) then BiteIt(vel - 10, Random(5) - 2);\r
+    end;\r
 \r
-   if fly=false then\r
-    playAnim(ANIM_LEGS);\r
-  end;\r
+  procedure GotoUP;\r
+    begin\r
+      if fly then begin\r
+        SetVelY(-PLAYER_SPEED);\r
+      end else begin\r
+        LoadPhy;\r
+        Phy.Jump(jumpVelocity);\r
+        StorePhy;\r
+      end;\r
+    end;\r
 \r
- procedure gotoRIGHT;\r
-  begin\r
-   setVelX(PLAYER_SPEED);\r
+  procedure GotoDOWN;\r
+    begin\r
+      if fly then SetVelY(PLAYER_SPEED);\r
+    end;\r
 \r
-   posi:=POSI_RIGHT;\r
+  procedure GotoLEFT;\r
+    begin\r
+      SetVelX(-PLAYER_SPEED);\r
+      posi := POSI_LEFT;\r
+      if not fly then PlayAnim(ANIM_LEGS);\r
+    end;\r
 \r
-   if fly=false then\r
-    playAnim(ANIM_LEGS);\r
-  end;\r
+  procedure GotoRIGHT;\r
+    begin\r
+      SetVelX(PLAYER_SPEED);\r
+      posi := POSI_RIGHT;\r
+      if not fly then playAnim(ANIM_LEGS);\r
+    end;\r
 \r
- procedure getDrop;\r
-  var\r
-   i, maxd, sum:integer;\r
-  begin\r
-   maxd:=drop.max;\r
-   for i:=0 to maxd do\r
-    if drop.isNull(i)=false then\r
-     if CollTwoObj(getX, getY, getW, getH, drop.getX(i), drop.getY(i), drop.getW, drop.getH) then\r
-      begin\r
-       sum:=inv.giveItem(drop.getItem(i), drop.getSum(i));\r
-       drop.setSum(sum, i);\r
-       drop.fixNull(i);\r
+  procedure GetDrop;\r
+    var\r
+      i, maxd, sum : integer;\r
+    begin\r
+      maxd := Drop.Max;\r
+      for i := 0 to maxd do if Drop.IsNull(i) = false then begin\r
+        if Phy.IntersectRects(GetX, GetY, GetW, GetH, Drop.GetX(i), Drop.GetY(i), Drop.GetW, Drop.GetH) then begin\r
+            sum:=inv.giveItem(drop.getItem(i), drop.getSum(i));\r
+            drop.setSum(sum, i);\r
+            drop.fixNull(i);\r
+        end;\r
       end;\r
-  end;\r
+    end;\r
 \r
 initialization\r
 \r