I like to move it, move it!
Ciele
  1. Reagovať na akciu hráča - dotyk, krížový kurzor.
  2. Vykreslenie posúvania dlaždice.
Úvod
Na tomto cvičení sa naučíte reagovať na hráčovu akciu, teda dotyk a potiahnutie dlaždice, alebo použitie kurzorových tlačidiel.
Postup
  1. Tento krok je zameraný na stlačenia kurzorového tlačidla. Je treba si uvedomiť všeobecné obmedzenie, že môžete pohybovať iba dlaždicami susediacimi stenou s prázdnou dlaždicou.
    Ak chcete pohybovať vybranou dlaždicou, je potrebné zistiť, o akú dlaždicu sa jedná v závislosti od pozície v poli dlaždíc a od usporiadania na hracom poli. Pri stlačení kurzorového tlačidla musíme určiť, ktorá susediaca dlaždica tlačidlu zodpovedá a či sa daná dlaždica nenachádza mimo poľa (prípad, kedy stlačíme kurzorové tlačidlo doľava, pričom prázdna dlaždica sa nachádza na pravom okraji hracieho poľa, a teda neexistuje dlaždica vyhovujúca akcii).
    Úloha:  Otvorte si projekt HelloAndroid z minulého cvičenia alebo si ho stiahnite a importujte do vývojového prostredia Eclipse.
    Úloha:  Deklarujte v triede /src/tuke.fei.hello/GameView.java premennú mySelectedTile typu int, ktorá bude predstavovať zvolenú dlaždicu na posunutie, hodnota bude rovná pozícii v poli dlaždíc myTiles takisto, ako je aj určená hodnota prázdnej dlaždice.
    Úloha:  Deklarujte príznak myIsAllowed typu boolean, ktorý bude značiť, či vybraná dlaždica spĺňa podmienku a je možné jej posunutie.
    Poznámka:  Existuje niekoľko štandardných metód volaných prostredím na každom objekte typu View, medzi ne sa zaraďujú aj metódy obsluhujúce používateľskú akciu.
    Úloha:  Prepíšte metódu onKeyDown(int, KeyEvent) obsluhujúcu akciu stlačenia tlačidla, kde prvý parameter určuje kód stlačeného tlačidla. Uložte do premennej mySelectedTile pozíciu zvolenej dlaždice na posunutie v závislosti od stlačeného tlačidla, beriete do úvahy iba kurzorové tlačidlá pohybu.
    Pre ilustráciu, stlačíte pravé kurzorové tlačidlo, teda chcete posunúť dlaždicu naľavo od prázdnej dlaždice. V takom prípade bude hodnota premennej mySelectedTile rovná dekrementovanej hodnote pozície prázdnej dlaždice, obdobne v ďalších prípadoch.
    Poznámka:  Kódy jednotlivých tlačidiel sú uložené v triede KeyEvent, napr. KeyEvent.KEYCODE_DPAD_UP obsahuje kód kurzorového tlačidla smerom hore.
    V tomto momente musíte určiť, či je možné posunutie danej dlaždice, a či vôbec dlaždica na danej pozícii v poli existuje. Musíte teda overiť 4 prípady - či sa jedná o dlaždicu napravo, naľavo, nad alebo pod prázdnou dlaždicou.
    Úloha:  Vytvorte metódy isUpTile(int), isDownTile(int), isLeftTile(int), isRightTile(int) s návratovým typom boolean, pre ktoré parametrom bude uložená pozícia zvolenej dlaždice.
    Úloha:  Implementujte dané metódy tak, aby rozhodli, či daná dlaždica vyhovuje podmienke nimi určenej.
    Úloha:  Doplňte akcie na stlačenie tlačidla v metóde onKeyDown() tak, aby sa v závislosti od vyhodnotenia príslušnej podmienky vyhodnotil príznak pre možnosť posunutia.
    Úloha:  Ak existuje dlaždica, ktorú je možné posunúť, vykonajte príslušné zmeny nad poľom dlaždíc. Pre túto akciu môžete vytvoriť metódu changeTiles().
    V prípade, že hráč stlačil tlačidlo a daná dlaždica má byť posunutá, je nutné vyvolať vykreslenie zmeny, teda opätovné vyvolanie metódy onDraw(). Na opätovné vykreslenie celého plátna je možné využiť metódu invalidate(). V rámci šetrenia zdrojov bude lepšie využívať metódu invalidate(Rect), ktorá vykreslí iba oblasť definovanú Rect objektom v parametre metódy. V tomto prípade teda bude stačiť vykresliť daný riadok/stĺpec v závislosti od smeru, v ktorom sa bude pohybovať dlaždica.
    Úloha:  Doplňte v príslušných miestach metódy príznaky označujúce, či sa bude vykresľovať riadok, teda dlaždica sa nachádza napravo alebo naľavo, alebo sa bude vykresľovať stĺpec, teda dlaždica sa nachádza pod alebo nad prázdnou dlaždicou.
    Úloha:  Vykreslite v závislosti od pohybu dlaždice opätovne hracie pole volaním metódy invalidate(Rect). Vytvorte si na to pomocné metódy redrawRow() a redrawCol().
    Poznámka:  Pri vytváraní Rect objektu môžete využiť v prípade vykresľovania riadku metódu getRight(), ktorá predstavuje x-ovú súradnicu bodov pravého ohraničenia obrazovky, v prípade stĺpca využite metódu getBottom(), ktorá určuje y-ovú súradnicu najspodnejších bodov obrazovky.
    Úloha:  Vytvorte a implementujte verejnú metódu isSolved() s návratovým typom boolean, ktorá zistí, či je daná hra vyriešená - teda pole dlaždíc je usporiadané.
    Úloha:  Zabezpečte, aby sa overenie stavu hry vykonalo pred vyvolaním akcie na stlačenie tlačidla - v prípade, že je hra vyriešená, nemôže byť už žiadna dlaždica posunutá.
    Úloha:  Upravte premiešanie dlaždíc na začiatku hry tak, aby sa pri miešaní vykonávali iba prípustné kroky - musia byť splnené podmienky hry uvádzané vyššie.
  2. Nasledujúce kroky sú zamerané na obsluhu dotykových udalostí. Pri vývoji tejto hry budete využívať 3 druhy dotykovej akcie - dotyk, uvoľnenie, ťahanie, pričom ťahanie je akcia medzi dotykom a uvoľnením. Tento krok sa zamerava na dotykovú akciu.
    Úloha:  Aby ste boli schopní vykresľovať plynulý pohyb dlaždice, deklarujte premenné prostredia pre x-ovú a y-ovú súradnicu prvotného dotyku a ďalej premenné pre orientačné súradnice ľavého horného rohu zvolenej dlaždice, všetky typu int.
    Úloha:  Prepíšte metódu onTouchEvent(MotionEvent) obsluhujúcu dotykové akcie, kde parameter určuje druh vykonanej akcie - prípustnými akciami sú MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP, MotionEvent.ACTION_MOVE. Druh vykonanej akcie určíte zavolaním metódy getAction() na MotionEvent objekte z parametra.
    Princíp pohybu dlaždice v prípade dotykových akcií spočíva v určení zvolenej dlaždice a jej splnení podmienky pre posun pri prvotnom dotyku, v rámci ťahania sa bude vykresľovať pohyb dlaždice, ktorý sa následne vyhodnotí pri uvoľnení dotyku.
    Úloha:  Doplňte metódu o podmienku stavu hry, kedy v prípade, že je hra vyriešená, nevykoná sa žiadna akcia.
    Úloha:  Implementujte časť metódy, ktorá reaguje na prvotný dotyk. Tu je potrebné odpamatať si súradnice dotyku získané volaním metód getX() a getY() na objekte z parametra a následne z nich určiť, ktorá dlaždica bola vybraná na základe výpočtu a uloženia príslušného riadku a stĺpca.
    Úloha:  Uložte do premennej mySelectedTile pozíciu zvolenej dlaždice s následným vyhodnotením príznaku pre umožnenie pohybu dlaždice a príznakov, či sa v prípade pohybu dlaždice bude vykresľovať riadok/stĺpec.
  3. Tento krok sa zamerava na implementáciu akcie ťahania, ktorá je definovaná ako akcia, ktorá je volaná medzi dotykom a uvoľnením dotyku pri akomkoľvek pohybe. V tomto kroku je dobré si uvedomiť, že budete vykresľovať posunutie dlaždice v rámci obmedzenia, že povolená dlaždica sa môže pohybovať iba v oblasti zahŕňajúcej prázdnu dlaždicu a oblasti dlaždici vlastnej, a to aj v prípade, že samotná pozícia ťahu presahuje túto oblasť v akomkoľvek smere.
    Predstava plynulého posunu dlaždice zahŕňa výpočet a vykreslenie dlaždice pri každom volaní akcie ťahu. Aj keď súradnice ťahu presiahnu vymedzenú oblasť, v ktorej daná dlaždica môže byť posúvaná, pozícia dlaždice sa môže prispôsobiť smeru ťahu ale iba v rámci jej vymedzenej oblasti.
    Úloha:  Začnite implementáciu časti metódy, ktorá reaguje na akciu ťahania. Tu je potrebné podmieniť vykonávanie akcie, že akcia môže byť vykonaná iba ak príznak možnosti pohybu povoľuje posun zvolenej dlaždice.
    Úloha:  Odpamätajte si súradnice ťahu a v kombinácii s uloženými súradnicami po dotyku vypočítajte súradnice pozície dlaždice po posune.
    Úloha:  Vymedzte oblasti, v ktorých zvolená dlaždica môže vykonávať posun a porovnajte vypočítanú pozíciu po posune s danými obmedzeniami.
    Úloha:  Ak dlaždica vyhovuje stanoveným obmedzeniam, vykonajte príslušné vykreslenie v závislosti od pohybu dlaždice.
  4. Tento krok sa zamerava na implementáciu akcie uvoľnenia dotyku. Beriete do úvahy finálne vykreslenie.
    Pri implementácii tohto kroku je potrebné vykonať kontrolu, kde sa nachádza miesto uvoľnenia dotyku v závislosti od čoho sa bude vyvíjať finálne vykreslenie pozície dlaždice. Uvažujeme, že ak sa dotyk uvoľní na pozícii prázdnej dlaždice, zvolená dlaždica sa vykreslí na miesto prázdnej dlaždice, v opačnom prípade sa vykreslí na svoje pôvodné miesto neberúc do úvahy pozíciu, v ktorej sa nachádzala v momente uvoľnenia dotyku.
    Úloha:  Implementujte časti metódy, ktorá reaguje na akciu uvoľnenia dotyku. Odpamätajte si súradnice uvoľnenia dotyku a následne vypočítajte a overte pozíciu v závislosti od čoho bude vykonaná zmena na poli dlaždíc.
    Poznámka:  Nezabudnite aplikovať zmeny vyvolaním vykreslenia hracieho poľa.
Doplňujúce úlohy