reklama

Umíme ve Flashi – 20. díl – detekce kolize II.

V dnešním díle upravíme detekci kolize do obecně použitelné podoby, umožňující zjišťovat kolizi dvou objektů v aktuálních pozicích včetně užitečné funkce, zjišťující možnou kolizi dvou objektů, která teprve nastane.

Funkce detekce kolize

V předchozím díle jsme měli funkce, detekující kolize objektů, umístěné přímo na symbolu podlahy, což není zrovna praktické řešení, ovšem pro prvotní seznámení se s touto problematikou nám vyhovovalo. Dnes se zaměříme na převedení těchto funkcí do obecné podoby, která nám umožní pohodlné zjištění detekce kolize dvou objektů.

Otevřeme si zdrojový soubor z minulého dílu (ke stažení zde) a do prvního snímku začneme psát upravené funkce. První, kterou z minulého skriptu vytvoříme, nám bude sloužit pro zjišťování aktuální kolize dvou objektů:

hit = function (ref_obj:Object, test_obj:Object) {
 dotyk = new Object();
 dotyk.cast = "nic";
 sour_x = test_obj._x;
 sour_y = test_obj._y;
 sour_w = test_obj._width;
 sour_h = test_obj._height;
 for (i=1; i<test_obj._width; i++) {
  if (ref_obj.hitTest(sour_x+i, sour_y+sour_h, true)) {
   trace("dotyk spodní");
   dotyk.cast = "spodni";
  }
 }
 for (i=1; i<test_obj._width; i++) {
  if (ref_obj.hitTest(sour_x+i, sour_y, true)) {
   trace("dotyk horní");
   dotyk.cast = "horni";
  }
 }
 for (i=1; i<test_obj._height; i++) {
  if (ref_obj.hitTest(sour_x, sour_y+i, true)) {
   trace("dotyk levý");
   dotyk.cast = "leva";
  }
 }
 for (i=1; i<test_obj._height; i++) {
  if (ref_obj.hitTest(sour_x+sour_w, sour_y+i, true)) {
   trace("dotyk pravý");
   dotyk.cast = "prava";
  }
 }
 return dotyk;
};

Nová funkce „hit“ požaduje dvě proměnné typu „Object“. Je to pochopitelné, protože potřebujme testovat pozici dvou objektů. Uvedená funkce je téměř shodná s tou, kterou jsme použili v minulém díle. Opět v ní testujeme průnik prvního objektu s krajními body objektu druhého.

Pomocí čtyř cyklů FOR projdeme každou stranu druhého objektu po 1px. Pokud bychom chtěli zjemnit detekci, můžeme proměnnou „i“ navyšovat o nižší hodnoty než je „1“, ale v tomto případě by došlo ke zbytečnému navýšení náročnosti na procesor, proto volíme jako nejnižší hodnotu číslo 1.

Funkce „hit“ nám podle výsledků vrací v proměnné „cast“ objektu „dotyk“ informaci o tom, kterou stranou se testovaný objekt dotýká prvního objektu „ref_obj“. Pokud není žádný dotyk, hodnota proměnné „cast“ je nezměněná, tedy „nic“.

Druhá funkce, kterou si připravíme, nám umožňuje s předstihem zjišťovat kolizi dvou objektů. Tato funkce najde uplatnění při pohybu figurkou. Umožní nám zjistit blízkost objektu, vůči kterému pohybující figurku testujeme. Nejčastěji tak budeme zjišťovat blízkou přítomnost podlahy, abychom zajistili co nejtěsnější umístění figurky právě k objektu podlahy.

Funkce v minulém díle sice padající figurku správně zastavila v okamžiku, kdy se dostala k hranici podlahy, ale vzhledem k hodnotě posunutí, která byla nastavena na 5px se mohlo stát, že figurka zůstala „viset“ až 5px nad okrajem objektu podlahy.

Funkce pro detekci budoucí kolize vypadá takto:

fut_hit = function (ref_obj_2:Object, test_obj_2:Object, x_posuv:Number, y_posuv:Number) {
 dotyk_2 = new Object();
 dotyk_2.cast = "nic";
 sour_x_2 = test_obj_2._x+x_posuv;
 sour_y_2 = test_obj_2._y+y_posuv;
 sour_w_2 = test_obj_2._width;
 sour_h_2 = test_obj_2._height;
 for (a=1; a<test_obj_2._width; a++) {
  if (ref_obj_2.hitTest(sour_x_2+a, sour_y_2+sour_h_2, true)) {
   trace("dotyk spodní");
   dotyk_2.cast = "spodni";
  }
 }
 for (a=1; a<test_obj_2._width; a++) {
  if (ref_obj_2.hitTest(sour_x_2+a, sour_y_2, true)) {
   trace("dotyk horní");
   dotyk_2.cast = "horni";
  }
 }
 for (a=1; a<test_obj._height; a++) {
  if (ref_obj_2.hitTest(sour_x_2, sour_y_2+a, true)) {
   trace("dotyk levý");
   dotyk_2.cast = "leva";
  }
 }
 for (a=1; a<test_obj._height; a++) {
  if (ref_obj_2.hitTest(sour_x_2+sour_w_2, sour_y_2+a, true)) {
   trace("dotyk pravý");
   dotyk_2.cast = "prava";
  }
 }
 return dotyk_2;
};

Pokud se podíváme a porovnáme ji s předchozí funkcí, zjistíme, že se od sebe téměř neliší. První funkci pro jsme pouze obohatili o dvě proměnné, které určují již zmíněný posuv. Protože testujeme objekt vůči souřadnici, můžeme do testované souřadnice vložit i připadnou budoucí hodnotu, která zde představuje polohu objektu, ve které by se figurka nacházela.

Ona budoucí poloha je právě určena pomocí požadovaných proměnných „x_posuv“ a „y_posuv“. Tyto proměnné představují posuv objektu od jeho aktuální polohy.

Poslední funkce bude už přímo sloužit objektu figurky. Pomocí ní funkce zajistíme správné umisťování figurky na objekt podlahy v závislosti na vzájemné poloze obou objektů:

test_hit = function (ref_obj_3:Object, test_obj_3:Object, p_x:Number, p_y:Number) {
 test = fut_hit(ref_obj_3, test_obj_3, p_x*posuv, p_y*posuv);
 if (test.cast == "nic") {
  trace("nic");
  test_obj_3._x += p_x*posuv;
  test_obj_3._y += p_y*posuv;
 } else {
  tx = 1;
  test2 = fut_hit(ref_obj_3, test_obj_3, p_x*tx, p_y*tx);
  if (test2.cast == "nic") {
   do {
    test_obj_3._x += p_x*tx;
    test_obj_3._y += p_y*tx;
    test2 = fut_hit(ref_obj_3, test_obj_3, p_x*2, p_y*2);
   } while (test2.cast == "nic");
  }
 }
};

Jako počáteční proměnné opět požadujeme dva objekty, jeden referenční (objekt podlahy) a druhý testovaný (figurka). Dále potřebujeme znát znaménko posuvu, který chceme uskutečnit. Jedná se o určení směru, kterým se bude dále ubírat objekt figurky. Tyto hodnoty proměnných „p_x“ a „p_y“ jsou buď „-1“ nebo „+1“. V této funkci již využíváme připravenou funkci pro detekci budoucí kolize dvou objektů a podle výsledku buď posuneme objektem na další pozici a nebo, pokud jsme v blízkosti referenčního objektu (podlaha), zjemníme posuv na 1px.

Tímto dosáhneme posouvání objektu až na rozdíl 1px od objektu podlahy. Máme zaručeno, že se objekt nezastaví ve vzdálenosti 1-5px od kraje objektu podlahy. Nakonec už jen na začátek skriptu prvního snímku připíšeme hodnotu proměnné „posuv=5;“ abychom nastavili rychlost figurky.

Než ovšem vyzkoušíme nové funkce, musíme je vložit k objektu podlahy. Vybereme proto tento objekt a původní akce přepíšeme tímto skriptem:

onClipEvent (enterFrame) {
 if (Key.isDown(Key.LEFT) && Key.isDown(Key.DOWN)) {
  _root.test_hit(this, _root.obj, -1, 1);
 } else if (Key.isDown(Key.LEFT) && Key.isDown(Key.UP)) {
  _root.test_hit(this, _root.obj, -1, -1);
 } else if (Key.isDown(Key.RIGHT) && Key.isDown(Key.DOWN)) {
  _root.test_hit(this, _root.obj, 1, 1);
 } else if (Key.isDown(Key.RIGHT) && Key.isDown(Key.UP)) {
  _root.test_hit(this, _root.obj, +1, -1);
 } else if (Key.isDown(Key.RIGHT)) {
  _root.test_hit(this, _root.obj, 1, 0);
 } else if (Key.isDown(Key.LEFT)) {
  _root.test_hit(this, _root.obj, -1, 0);
 } else if (Key.isDown(Key.UP)) {
  _root.test_hit(this, _root.obj, 0, -1);
 } else {
  _root.test_hit(this, _root.obj, 0, 1);
 }
}

V události onEnterFrame pomocí funkce „test_hit()“ provádíme testování dotyku objektu figurky s objektem podlahy na hlavní scéně. Všimneme si hodnot značek posuvu a to především v té části, kde požadujeme pouze posuv v jednom směru. Zde ve směru, kde nechceme žádný pohyb, uvedeme hodnotu „0“ a objekt figurky tak testujeme v posunutí pouze jedním směrem.

Nyní už jen otestujeme výslednou animaci, která může vypadat takto. Zdrojový soubor dnešní ukázky je ke stažení zde.

Témata článku: Software, Programování, Cast

1 komentář

Nejnovější komentáře

  • gully, gully 20. 2. 2006 9:08:31
    http://diskuse-zaciname-s-flash-mx-2004.wz.cz
reklama
Určitě si přečtěte

Pojďme programovat elektroniku: Sestavíme si mobil a pošleme SMS

Pojďme programovat elektroniku: Sestavíme si mobil a pošleme SMS

** Kolik stál váš mobilní telefon? ** Základní GSM modem koupíte za stovku ** Umí telefonovat, posílat SMS a zvládne i GPRS

13.  1.  2017 | Jakub Čížek | 27

Auta budoucnosti: V tomto se budete za pár let vozit

Auta budoucnosti: V tomto se budete za pár let vozit

** Velký prostor patřil na letošním veletrhu CES automobilům ** Automobilová budoucnost je elektrická a inteligentní ** Podívejte se, jak je vývoj futuristických autonomních aut daleko

12.  1.  2017 | David Polesný | 34

Český státní blacklist už funguje. Ministerstvo financí se pochlubilo s detaily

Český státní blacklist už funguje. Ministerstvo financí se pochlubilo s detaily

** Dva týdny po Novém roce zajím zeje prázdnotou ** Ministerstvo vydalo metodický pokyn ** Takhle to bude fungovat v praxi

16.  1.  2017 | Jakub Čížek | 44

Opera Neon: Takto prý bude vypadat prohlížeč budoucnosti. Chcete to?

Opera Neon: Takto prý bude vypadat prohlížeč budoucnosti. Chcete to?

** Opera představila Neon ** Koncepci prohlížeče budoucnosti ** Připomíná Chrome OS

16.  1.  2017 | Jakub Čížek | 34


Aktuální číslo časopisu Computer

99 nejlepších programů pro váš počítač

Zvykejte si na umělou inteligenci

Velké testy PC zdrojů a gamepadů

Alternativní zdroje energie

reklama
reklama