Stránka sa načítava, prosím čakajte…
© 2005 – 2024 Roman Horváth, všetky práva vyhradené. Dnes je 27. 4. 2024.
Dátum: 20. 4. 2020, pred štyrmi rokmi
Tento príklad demonštruje tieto koncepty:
- položky ponuky a základnú prácu s nimi,
- vstupný riadok a spracovanie jeho obsahu,
- generovanie zvukov (a ukladanie vygenerovaného obsahu do súboru),
- neštandardné ovládanie robota (základný pohyb robota):
- položkami ponuky a ich klávesovými skratkami (Ctrl + «kláves»),
- príkazmi zadávanými prostredníctvom vstupného riadka.
~
import knižnica.*; import static knižnica.Svet.*; import static knižnica.Kláves.*; import static knižnica.ÚdajeUdalostí.*; public class JazdiaciRobot extends GRobot { // Konštanty prehrávania tónov… // Frekvencia najnižšieho tónu: private final static int najnižšíTón = 212; // Frekvenčný „odstup“ tónov: private final static int odstupTónov = 128; // Počet tónov v sérii: private final static int početTónov = 40; // Násobok hlasitosti (spolu s počtom tónov určia mieru útlmu // hlasitosti tónov): private final static double útlmTónov = 0.025; // Trvanie prehrávania jednotlivých tónov: private final static double trvanieTónov = 0.0025; // Deklarácie položiek ponuky: private final PoložkaPonuky vpred; private final PoložkaPonuky vzad; private final PoložkaPonuky vpravo; private final PoložkaPonuky vľavo; private final PoložkaPonuky stoj; private final PoložkaPonuky vystreľ; // Deklarácia zvuku: private final Zvuk zvuk; // Deklarácie atribútov slúžiacich na spracovanie príkazov: private final StringBuffer príkaz = new StringBuffer(); private double parameter = 0.0; // Konštruktor. private JazdiaciRobot() { // Zmení rozmery plátna: super(500, 500, "Jazdiaci robot "); // Inicializácia položiek ponuky: vpred = new PoložkaPonuky("Vpred", VK_D, VK_I); vzad = new PoložkaPonuky("Vzad", VK_Z, VK_K); vpravo = new PoložkaPonuky("Vpravo", VK_P, VK_L); vľavo = new PoložkaPonuky("Vľavo (l)", VK_L, VK_J); stoj = new PoložkaPonuky("Stoj", VK_S, VK_S); vystreľ = new PoložkaPonuky("Vystreľ", VK_T, VK_D); // Čítanie alebo generovanie zvuku: zvuk = dajZvuk(); // Nastavenia sveta: aktivujHistóriuVstupnéhoRiadka(); neskrývajVstupnýRiadok(); začniVstup(); zbaľ(); // Nastavenia robota: farba(tmavohnedá); hrúbkaPera(3); ohranič(); // Spustenie… spustiČasovač(0.04); prekresli(); } // Táto metóda prečíta alebo vyrobí zvuk výstrelu. Ak by bol disk // chránený proti zápisu alebo by nastalo iné zlyhanie, tak by sa // zvuk generoval vždy na požiadanie a to metódou generujZvuk. private Zvuk dajZvuk() { // Ak zvuk nejestvuje, vygenerujeme ho: if (!Súbor.jestvuje("laser.wav")) { // Krátke naladenie generátora (neúspešný pokus o to, aby bol // vygenerovaný zvuk stále rovnaký; generátor zvukov je veľmi // citlivý na predchádzajúci stav, takže každý uložený zvuk // bude odlišný): hrajTón(najnižšíTón + odstupTónov * početTónov); čakaj(0.750); zastavTón(); čakaj(0.300); // Generovanie a uloženie zvuku: if (otvorSúborNaUloženieTónu("laser.wav")) { for (int i = početTónov; i >= 0; --i) { hrajTón(najnižšíTón + odstupTónov * i, i * útlmTónov); čakaj(trvanieTónov); } zastavTón(); čakaj(0.200); if (!zavriSúborNaUloženieTónu()) // Vypíše upozornenie na štandardnom chybovom výstupe: System.err.println("Súbor zvuku sa " + "nepodarilo zapísať."); } else // Vypíše upozornenie na štandardnom chybovom výstupe: System.err.println("Súbor na zápis zvuku " + "sa nepodarilo otvoriť."); } try { // Prečítanie zvuku: return čítajZvuk("laser.wav"); } catch (Throwable t) { // Vypíše podrobné hlásenie na štandardnom chybovom výstupe: t.printStackTrace(); // V prípade zlyhania vráti null: return null; } } // Metóda, ktorá by generovala zvuk, keby ho nebolo možné prečítať // z pevného disku. private void generujZvuk() { // (Generátor je citlivý na predchádzajúci stav, takže každý // nový zvuk bude mierne odlišný od predchádzajúceho.) for (int i = početTónov; i >= 0; --i) hrajTón(najnižšíTón + odstupTónov * i, i * útlmTónov, trvanieTónov); } // Príkaz vystreľ prijíma jeden parameter, ktorý znamená vzdialenosť // dostrelu. Metóda nakreslí žltú čiaru a ak bol úspešne prečítaný // zvuk, prehrá ho, ak nebol, vygeneruje zakaždým nový unikátny. private void vystreľ(double parameter) { if (null == zvuk) generujZvuk(); else zvuk.prehraj(); Bod poloha = poloha(); Farba farba = farba(); double smer = smer(); double hrúbkaPera = hrúbkaPera(); farba(svetložltá); hrúbkaPera(hrúbkaPera / 2.5); vľavo(10 * uhlováRýchlosť()); skoč(); vpred(parameter); hrúbkaPera(hrúbkaPera); smer(smer); farba(farba); poloha(poloha); } // Metóda pomáhajúca pri rozpoznávaní príkazov. private boolean príkazSaZačína(String začiatok) { int length = začiatok.length(); if (príkaz.length() < length) return false; for (int i = 0; i < length; ++i) if (príkaz.charAt(i) != začiatok.charAt(i)) return false; return true; } // Metóda majúca na starosti rozpoznávanie príkazov a ich parametrov. private boolean rozpoznajPríkaz(String rozpoznaj) throws Exception { if (príkazSaZačína(rozpoznaj)) { try { // Parameter je povinný: parameter = Double.parseDouble( príkaz.substring(1 + rozpoznaj.length())); return true; } catch (Exception e) { throw new Exception("Nesprávny parameter!"); } } return false; } // Súkromná metóda slúžiaca na spracovanie príkazov. Toto riešenie // poskytuje vyššiu univerzálnosť, lebo príkazy môžu prúdiť aj // z iného zdroja, než vstupný riadok. private void spracujPríkaz(String reťazec) { // Nastavenie hodnoty atribútu príkaz, ktorý bude v ďalšom bloku // try-catch opakovane využívaný. V OOP sa takýmto spôsobom // vyhýbame zbytočnému posielaniu parametrov medzi súkromnými // metódami. (Toto riešenie nie je bezpečné pri viacvláknových // programoch, nie je tzv. thread-safe, ale dá sa relatívne // jednoducho zabezpečiť. Tento program nie je v súvislosti so // spracovaním príkazov viacvláknový.) príkaz.setLength(0); príkaz.append(reťazec.toLowerCase()); // Test, či je aktuálny príkaz neprázdny: if (0 != príkaz.length()) try { // Rozpoznávanie a vykonávanie príkazov… if (rozpoznajPríkaz("vpred")) vpred(parameter); else if (rozpoznajPríkaz("vzad")) vzad(parameter); else if (rozpoznajPríkaz("vystreľ") || rozpoznajPríkaz("vystrel")) vystreľ(parameter); else if (rozpoznajPríkaz("vpravo")) vpravo(parameter); else if (rozpoznajPríkaz("vľavo") || rozpoznajPríkaz("vlavo")) vľavo(parameter); else if (rozpoznajPríkaz("vpravo")) vpravo(parameter); else if (rozpoznajPríkaz("rýchlosť") || rozpoznajPríkaz("rychlost")) rýchlosť(parameter); else if (rozpoznajPríkaz("rotácia") || rozpoznajPríkaz("rotacia") || rozpoznajPríkaz("rotuj")) uhlováRýchlosť(parameter); else chyba("Neznámy príkaz!"); } catch (Exception e) { // Táto chyba nastáva pri zadaní nečíselného parametra: chyba(e.getMessage()); } } // Potvrdenie údajov jednoducho vykoná vyššie definovanú metódu // s reťazcom prevzatým zo vstupného riadka: @Override public void potvrdenieÚdajov() { spracujPríkaz(prevezmiReťazec()); } // Kreslenie vlastného tvaru, ktorý odzrkadľuje aktuálny smer aj uhlovú // rýchlosť. @Override public void kresliTvar() { farba(tmavozelená); kružnica(); skoč(); vpred(); domov(); farba(čierna); vľavo(10 * uhlováRýchlosť()); skoč(5); vpred(); } // Spracovanie príkazov položiek ponuky (ktoré sú zároveň sprístupnené // prostredníctvom klávesových skratiek – ovládanie klávesovými skratkami // sa odlišuje od ovládania príkazmi; napriek tomu nie sú v príkrom // rozpore, vedia fungovať nezávisle od seba, ale ich rozdielnosť by // určite miatla neinformovaného používateľa, preto sa takéto riešenia // softvéru neodporúčajú ; tu však slúžia na ukážku dvoch rôznych // prístupov). @Override public void voľbaPoložkyPonuky() { // (Väčšina volieb je samovysvetľujúcich.) if (vpred == položkaPonuky()) { rýchlosť(rýchlosť() + 0.25); } else if (vzad == položkaPonuky()) { rýchlosť(rýchlosť() - 0.25); } else if (stoj == položkaPonuky()) { // Vlastné riešenie zastavenia formou postupného spomaľovania // (zrýchlenie je resetované v reakcii na zastavenie): if (rýchlosť() > 0) zrýchlenie(-0.5); else zrýchlenie(0.5); zastavPoSpomalení(); // Keby sme pohyb riešili prostredníctvom zrýchlenia // a maximálnej rýchlosti, tak by na tomto mieste stačilo // uviesť príkaz: zabrzdi(); } else if (vystreľ == položkaPonuky()) { vystreľ(60); } else if (vpravo == položkaPonuky()) { uhlováRýchlosť(uhlováRýchlosť() - 0.5, false); prekresli(); } else if (vľavo == položkaPonuky()) { uhlováRýchlosť(uhlováRýchlosť() + 0.5, false); prekresli(); } } // Reakcia na zastavenie. @Override public void zastavenie() { // Nastaví nulové zrýchlenie, aby sa zrušil prípadný // efekt položky ponuky stoj. zrýchlenie(0, false); } // Hlavná metóda. public static void main(String[] args) { new JazdiaciRobot(); } }
|