Jak jsem potkal Android (cestopis)

Prolog


28.6.2013:

Za tři dny začnou prázdniny a napadlo mě, že bych se mohl podívat na programování pro Android.
A protože cíle mají být konkrétní a vzrušující, tak chci napsat hru, variantu svého hada někdy z roku 1987 resp. později 1991 — a dotáhnout to až k vystavení na Android marketu.

Příprava:
Pro Android jsem dřív nepsal, v Javě neprogramoval, Eclipse nepoužívám, ale tuším, že právě tohle jsou nástroje. Na webu nacházím a stahuju

adt-bundle-windows-x86-20130522.zip
Android Development Toolkit.

Nevím, jak to rozběhnu, protože "počítač na práci" nemám připojený k síti, rozbaluju na počítači, který JE v síti, pak přenáším celý adresář – a ono to běží.

Zkouším Tutorials: Build your First App:

a výsledek je aplikace, která běží na AVD – Android Virtual Device, emulátor, který je součástí balíku ADT. Příprava dokončena.

První den

1.7.2013 9:23:47

Začíná projekt ANDY.
Obsah: Napsat hru, která se bude šířit via Gogle Play.
Cile:

  • zkusit vyvinout aplikaci, kterou budou lidi používat
  • potenciální zdroj příjmů
  • naučit se vytvářet aplikace pro Android, abych mohl v srpnu ukázat na letní škole na Lipnici, i jen tak, abych se něco naučil
  • sledovat proces vývoje aplikace jako projektu
  • dokumentovat a možná publikovat blog/text

Kreslim ve FreeMind-u myšlenkovou mapu toho, co všechno potřebuju udělat i naučit se pro úspěšné dokončení projektu.

==20'

Co potřebuju vymyslet a udělat:

  • jaká aplikace
    = jednoduchá hra
  • jaký obchodní model:
    • jen zdarma
    • jen placená
    • reklama ve hře
    • zdarma i placená verse
      • otravné hlášky
      • omezená doba hraní
      • vlastnosti navíc
        • ukládání screenshotu
        • více hadů
        • větší mapa
  • mapa oken, workflow
  • grafika
    • grafika pro různá rozlišení
  • lokalizace
    • česky a anglicky
    • ještě německy?
    • španělsky?
    • žádné texty, jen ikony
  • vlastní program
  • název
  • ikona
  • testování
  • administrativa zařazení do Google Play
    • pro bezplatné aplikace
    • pro placené aplikace
  • www stránka

Co potřebuju umět z programování v Androidu:

  • obecně vytvořit aplikaci
  • použití bitmap
  • kreslení do bitmap a na okno
  • práce s bitmapami pro různá rozlišení
  • vícejazyčné texty
  • práce s časem
  • ukládání dat
  • sdílení výsledků – FB, twitter atd.
  • ukládání screenshotu
  • rozpoznávání pohybů po displeji
  • zakázat otáčení
  • roztáhnout obrázky na celou plochu
  • přehrávání zvuků

Zakládám repository pro správu versí.

Začínám číst tutoriál od Matěje Konečného Vyvíjíme pro Android:
http://www.zdrojak.cz/serialy/vyvijime-pro-android/ stažený ze serveru zdrojak.cz.

Odklikávám podle tutoriálu, Eclipse se ptá na trochu jiné otázky, zřejmě mám novější versi ADT, ale jde to.

Poznávám Activity, Manifest a Toast.

Moje aplikace pořád obsahuje text Hello World, který ve zdrojových textech není, přijdu na to časem, až poznám pojmy layout a res/values/strings.xml.

Řeším, že není vidět zpráva zobrazená voláním funkce Toast, než přijdu na to, že Toast zprávu zobrazí a za chvilku zmizí.

Nemůžu svou aplikaci najít v seznamu aplikací (Zdrojak NENÍ dobré jméno, seznam aplikací se řadí podle abecedy), než přijdu na to, že v Androidu 4, který aktuálně běží v AVD, se seznamem aplikací listuje do stran a ne svisle jako na mém telefonu.

Pouštím se do vlastní tvorby se zobrazováním zpráv a po čase bádání zjišťuju, že nestačí Toast vyrobit, ale je potřeba ho i zobrazit metodou show().

Dobře, mám za sebou první díl tutoriálu, vytvořeno nové AVD, zprovozněna první aplikace, objeven Toast a navíc letmé rozkoukání po resourcech při hledání, proč se zobrazuje Hello World.

==80'

Pokračuju v tutoriálu druhou lekcí.
Dozvídám se, co jsou Activity, View, layouty v res/layout, nastavení velikosti match_parent a fill_parent a taky, jak je to se syntaxí identifikátorů (ale stejně je při programování nebudu psát, jen kopírovat "z toho, co funguje").
A taky o tom, že v manifestu musejí být zapsané všechny activity.
Activity onCreate.

Zápasím s tím, že mi aplikace nejde spustit a Eclipse vypisuje

[2013-07-01 11:59:29 - Zdrojak2] Failed to install Zdrojak2.apk on device 'emulator-5554': timeout
[2013-07-01 11:59:29 - Zdrojak2] Launch canceled!
, než přestanu hledat chybu a zrestartuju AVD.
Opakuje se v dalších dnech vždycky zhruba po dvou hodinách práce.
A užitečný nástroj: Log.d na vypisování kontrolních tisků do okna LogCat.

Třetí lekce, Suroviny, Intenty a jednotky.

Líbí se mi "suroviny" jako překlad anglického resources! Poznávám strukturu adresáře /res, v budoucnu mockrát použiju.

A vysvětleny qualifiers pro různé jazyky, velikosti, rozlišení cílového zařízení.

Další ukázková aplikace vychází z minulé, můžu zkopírovat adresář a otevřít? Zkopírováno, přejmenováno, trocha zápasení s Eclipse – a asi ne.
Zkouším vytvořit nový projekt, smazat, stejně si pamatuje, že to jméno už je, v tomhletom nemám jasno a za pár dní se mi to moc vymstí, ale nepředbíhejme.

Nový projekt nakonec pojmenován Zdrojak3a, kopie projektu Zdrojak2 a pokračuju v tutoriálu.
Přesouvám stringy do surovin a mám radost, že to funguje. Líbí se mi to, jak Eclipse dogenerovává identifikátory i to, jak nabízí opravy v případě chyb. Moc příjemné!

1.7.2013 12:53:21
celkem 180'

Navečer pokračuju v třetí lekci, poznávám intenty a jak pomocí intentu spustit jinou aktivitu.

Pořád padá, než přijdu na to, že s přejmenováním aktivity musím taky změnit Manifest. A autor tutoriálu (Matěj Konečný) na to v textu upozorňoval!

"Unfortunatelly, application Zdojak3a has stopped..."
– AHA, u Activity v manifestu mám chybný package, je potřeba si na to dávat pozor.

Jak můžu zastavit běžící aplikaci? Udělám opravu, chci spustit, ale Eclipse mi pořád říká, že ta aplikace už běží. Vyhledávám na webu a nacházím perspektivu (pojmenované rozložení oken v Eclipse) DDMS, která zobrazuje seznam běžících procesů a tam ji můžu zastavit. Funguje!

1.7.2013 18:42:40
==75'
celkem 255'

Končí první den, mám za sebou 255 minut, poznal jsem Activity, resources, lokalizace, intent, trochu ovládání Eclipse a AVD.

Druhý den

Lekce 4.: Vyvíjíme pro Android: Bližší pohled na pohledy – 1. díl.

Objevuju chybu v článku, "half_opaque_dark_red...#80000080" by mělo být #80800000, tamto je poloprůsvitná tmavá modrá, nijak to nesnižuje jeho užitečnost.

V Emulation options objevuju nastavení Snapshot, prý by to mělo zrychlit start. Zatím nepozoruju zrychlení, ale dochází místo na disku C:, takže uklízím.
Ano, ukládá tam snímek virtuálního stroje a pomáhá to, protože se při dalším spuštění nečeká, až nastartuje Android. Ale v průběhu dalších dnů to zabírané místo roste a roste (jednotky gigabajtů), tak nakonec opouštím (i když kdoví, tak jistý si v nastavování Eclipse nejsem).

Poznávám, jak udělat funkci pro obsluhu události a s překvapením zjišťuju, že Android dokáže zarotovat View o 30 stupňů (v AVD, virtuální Android verse 4, později zjišťuju, že má verse 2 na ZTE Blade to nedovede).

Daří se mi reagovat na klik a zjišťuju, že dosazení int-u do stringu syntakticky projde, ale aplikace padá, musím dosazovat String.valueOf( int ).

Poznávám ImageView, to je to, co budu potřebovat pro svou hru a dovídám se, že /res má podadresáře pro různá rozlišení. Časem se dozvím, že alespoň u ikony aplikace Eclipse (nebo kdo vlastně) dovede jeden obrázek rozgenerovat do všech potřebných rozlišení, teď si jen říkám, že by se to hodilo.

Vlákna a pravidla ohledně UI vlákna, zatím nepotřebuju.

Pokouším se poprvé přenášet aplikaci do telefonu, zatím ještě po nainstalování zase zakazuju instalaci softwaru z neznámých zdrojů, až to budu dělat podesáté, už to nechám povolené – a zjišťuju, že to (po)otáčení obrázku nefunguje.

==135'
celkem 390'
Lekce 5.: Vyvíjíme pro Android: Bližší pohled na pohledy – 2. díl Různé druhy layoutů (to budu potřebovat, moje hra bude matice obrázků) a nakonec Adapter. Přečtu si to, ale vyzkoušení odkládám na zítřek.
==55'
celkem 445'

Třetí den

Chci dokončit včerejší lekci – z několka dílčích projektů poskládat jeden. Doposud jsem si všechny ukázané příklady zkoušel a hrál si s jejich obměňováním, tady prvně váhám, protože jednotlivé ukázané Aktivity jsem vytvářel jako samostatné projekty a všechny se jmenovaly stejně MainActivity. Nakonec aktivity do nového projektu kopíruju a přejmenovávám.

- PrvniActivity, prvni_layout
- DruhaActivity, druhy_layout
- TretiActivity, treti_layout
- CtvrtaActivity, ctvrty_layout

Zapsat do manifestu, nevím, co s <intent-filter> a tak to vynechávám a nic se nestane.
Pak přidávám kód hlavní aktivity, copy-paste, upravuju pole tříd a funguje!

Další lekce Lekce 6: Vyvíjíme pro Android: Fragmenty a SQLite databáze je o ukládání, což budu potřebovat, protože chci ukládat nejlepší skóre.

Ale odkazuje na článek http://www.zdrojak.cz/clanky/dej-androidu-tablety/ a vybízí k jeho přečtení, tak čtu. U toho poctivě vyrábím "Aniččinu aplikaci", trvá mi to 140 minut.

Odpoledne se vracím k začátku lekce 6, čtu o Fragmentech a zkouším rozbíhat příklad. Narážím na problém, který řeší Errata na konci seriálu a u rozbíhání zkouším debugger a vypadá použitelně (vyzkoušeny breakpointy, krokování, hodnoty proměnných).

Dnešní výsledek Fragmenty, aplikace na ně, nepatrně SQLite (spíš ty fragmenty) a naklikaná aplikace s Notýskem. Vyzkoušen debugger a funguje. To celé za 275 minut.

== 275'
celkem 720'

Čtvrtý den

Sedmá lekce: Lekce 7: Vyvíjíme pro Android: Preference, menu a vlastní Adapter.

Přichází zlom a místo oklikávání aplikace z tutoriálu se rozhoduju vyzkoušet si Preference sám.

Vytvářím Preference v XML, dokážu z nich číst, dokážu zobrazit jejich editor, ale ať změním cokoliv, ten editor vždycky vychází z původních hodnot.

Hledám a zkouším, jak počkat na výsledek aktivity a dozvídám se, že s preferencemi se to takhle nedělá, že pokud někoho zajímá změna preferencí, má si na to zaregistrovat listener.

Po dvou hodinách další zlom, opouštím tutorial a zkouším si vyrobit vlastní jednoduchou aplikaci na hádání čísel.

4.7.2013 11:30:41
==135'

Myslím na svou hru a zkouším vytvářet View i celý layout ve zdrojovém kódu.

==35'

Navečer potom zkoumám, jak reagovat na dotek, je to jednoduché: onTouch a getAction():

0 = ACTION_DOWN
1 = ACTION_UP
2 = ACTION_MOVE

==30'

Zkouším vyrobit aplikaci, kde je obrázek, který se na dotek změní na jiný obrázek.

==15'

Takže jsem opustil náruč tutoriálu, a mám vlastní aplikaci, s obrázkem, který se kliknutím změní na jiný obrázek. Funguje i na telefonu.

==215'
celkem 935'

O hře, kterou chci naprogramovat

Tuhle hru jsem naprogramoval z nudy v Basicu v osmdesátých letech na jednom obskurním počítači – a byla docela úspěšná mezi uživateli.
Pak jsem ji naprogramoval znovu v osmdesátých letech v Pascalu na PC jako postcard-ware, kdy asi po hodině hraní vyskočila hláška ve stylu Už hraješ hodinu, kolik je tvá hodinová mzda? A co kdybys mi poslal pohlednici? Tehdy měl sotva kdo PC doma, tak hádám, že to lidi hráli v práci, ještě mám schovanou pohlednici "I like your snake very much" někde zdaleka. Jo je to had.

A pak jsem ji naprogramoval dotřetice, když už jsem měl svou firmu. Když člověk uhrál určité skóre, vyskočil mu kód na slevu při nákupu hardwaru.

Ta hra vypadá takhle: plocha, dva hadi, jednoho řídí hráč, druhého počítač.
Hadi se rovnoměrně prodlužují, když nemůže táhnout počítačový had, chcípne, ale zůstane ležet a objeví se nový had. Cílem je svým hadem "ulovit" co nejvíc hadů. Hraje se na tahy, takže se dá nad každým tahem v klidu přemýšlet.

Je to blbina a hraje tam roli náhoda, ale stejně je ta hra docela chytlavá, tak uvidíme, jestli bude mít nějaký ohlas na telefonech.

Napadla mě jedna drobnost:
Na počítačích se ta hra ovládala směrovými šipkami, jak ji ovládat na telefonu? Naklánění jsem zavrhl, neměla by to být hra na šikovost, ale na přemýšlení. A řešení je šmidlat po displeji. Přejet prstem zleva doprava znamena pohyb doprava. A podobně pro ostatní směry.

Takže na ovládání budu potřebovat umět rozpoznávat takovéhle pohyby – a po čtvrtém dni už to umím, při ACTION_DOWN si zapamatuju polohu, při ACTION_UP se podívám na rozdíl a z toho určím směr. Příliš krátké pohyby nebo ty, kde nebude jasně patrné, jestli je to spíš doleva nebo spíš nahoru, budu ignorovat.

Potřebuju rozmyslet obchodní model – pokud na tom chci zbohatnout (jeden z cílů), potřebuju vědět, za co mi lidi budou platit.

A taky budu potřebovat grafiku a zvuky a texty – viz Mind Mapa z prvního dne.

Pátý den

5.7.2013 9:39:38 Jdu řešit otázky, které potřebuju zodpovědět pro svůj program:
  1. jestli můžu obsahovat obrázky a přitom reagovat na události Touch od celeho zabalujiciho layoutu
  2. zkusit pomocí down a up detekovat směr šmouhnutí
  3. ...a podle něj natahovat hada

Ad 1) – ano, jde to.

Ad 2) – naprogramováno, funguje.
V Javě jsem nikdy neprogramoval, ale je to skoro jako C# a stejně nic neprogramuju od začátku, jen kopíruju a upravuju.

Ad 3) ...a podle nej natahovat hada:
Tak na to už bych si měl vytvořit novou třídu:

  • pole, odpovídající ikonkám na obrazovce
  • had-fronta
  • pozice hlavy
  • pohyb – tj. překreslit stávající políčko (dosavadní pozice hlavy)
    • pamatovat si ještě minulý pohyb a podle toho vybírat ikonku
    • nakreslit hlavu na novou pozici
  • asi funkce, které předám směr a ona:
    • zkontroluje přípustnost pohybu, když nejde (překážka), vrátí NEJDE
    • (kdyz nemůže táhnout) někdy může vrátit i KONEC_HRY
    • když pohyb je přípustný, vrátí
      • souřadnice minulé hlavy
      • index ikonky na tyto souřadnice
      • souřadnice současné hlavy
      • index ikonky pro tuto hlavu

Jak ta funkce bude vracet parametry?
Var-parametry nebo výsledek funkce nebo zapisovat do (svých) proměnných?

Hledání na webu ukazuje, že parametry předávané odkazem v Javě nejsou. A dále že struct jako v C# v Javě taky není a class požívat nechci, abych moc nezatěžoval garbage-collector.
Takže nakonec vybráno zapisovat výsledky do svých členských proměnných, není to moc hezké, ale lépe to neumím.

Activity by měla mít pole těch ImageView, aby na ně mohla snadno sahat:

OK, dvourozměrné pole je [][], [,] asi neumí.

Had má svou velikost a taky konstruktor, který (koho/co) volá Activity v onCreate.

Ta proměnná had by mohla být static a volat konstruktor jen když null.

Stejně je divné, že může být enum Smer a funkce Smer (která vrací ten enum, ale snad to není konstruktor).

Na disku C: dochází místo... něco odsunuto.

OK, funguje! Už bude čas nakreslit obrázky!
5.7.2013 11:32:50

==110'

Jdu kreslit obrázky, zatím jen ošklivé na ladění a jen pro jednoho hada (jen jedna barva).

Nejdřív ujasnit pojmenovávání souborů:

  • prazdne
  • hlava_<smer>
  • <smer>_<smer> a to tak, ze v pořadí UP-RIGHT-DOWN-LEFT (tj. bude UP-DOWN a nebude DOWN-UP. Mohl bych mít dvě ikonky podle směru pohybu hada, ale nebudu.

Rozměr ikonek: (zatím) jen v Malování, třeba 20x20

  • nakresleny
  • přidat do projektu:
    – Hmm, když je přetáhnu, tak se zobrazí ve stromě pod /res, ale vygenerované identifikátory pro ně nejsou. Jak se správně přidávají suroviny/obrázky? Podívat se na web...
    • Project/Clean... nepomohlo, ale chybová hláška – jenom MALÁ PÍSMENKA!!
    • nějak jsem si umazal R.java...?
    • nový projekt Pokus3
  • když Copy jeden soubor a Paste do drawable-mdpi, tak to jde!
  • když více souboru...: Hmm, jde to taky!

Mám Pokus3, obrázky pro směr hlavy...
Kreslí to nesmyslné obrázky, ale obecně to reaguje, OK!
5.7.2013 12:54:32

==195'
celkem 1130'

Pokračuju, pokud jde o směry – ikony byly špatně, předěláno.

Teď je na řadě logika hry – třida Had: fronta pozic, ocásek... ještě nainstalovat do telefonu:
OK, funguje, i když se občas ještě ztratí políčko (asi po startu, kdyz neni nastaven minulý směr?)

Další kroky:

  • hlidat ocas, překážky, okraje
  • další had/-i?
  • zvuky? (při každém pohybu)
5.7.2013 17:37:56

==38'
celkem 1170'
sobota 6.7. sabat
neděle 7.7. rodinná neděle

V sobotu nezapínám počítač, v neděli jsem se svými bližními, takže končí první týden: mám trochu ponětí o tom, jak vypadá aplikace v Androidu, co jsou aktivity, layouty, suroviny a mám aplikaci, která reaguje na šmatlání po obrazovce a posouvá hada, zatím s ošklivými prozatímními obrázky a ta aplikace běží i na telefonu. Pět dní, 1170 minut, tj. necelých 20 hodin.

Šestý den

V pondělí pokračuju.
Plán:

  1. vyčlenit mapu do samostatné třídy, aby ji mohlo používat víc hadů
  2. kontrolovat obsazená políčka na mapě a okraje hřiště
  3. fronta, aby had umázaval konec
  4. aby ikony/resourcy vracel přímo Had a neřešila to Activity
  5. druhý had
  6. zabránit otáčení obrazovky
  7. roztáhnout obrázky na celou plochu – pomocí weight?

Místo toho, abych upravoval ve stávajícím, zakládám nový projekt.

Ad 1) vyčlenit mapu do samostatné třídy, aby ji mohlo používat víc hadů:

Zakládám třídu Mapa, ujasňuju si, jakou souřadnicí indexuju jako první v dvourozměrném poli – [y][x], nezáleží na tom, ale je to (moje) vcelku častá chyba.

A přeruchání alias refaktorizace:

  • z Mapy dělám samostatnou třídu
  • vytvářím novou třídu Hra, která bude spravovat společné údaje
  • zkouším, pořád funguje.

Ad 3) fronta, aby had umazával konec:

Abych mohl odmazávat konec hada, potřebuju frontu.
Začal jsem psát pole a indexy začátku a konce přímo do třídy Had, ale během pár sekund jsem si uvědomil, že bude lépe (překonat lenost a) udělat třídu.
Teda, ještě jsem hledal standardní třídy, ale když jsem viděl, co všechno umějí a usoudil, že bych měl šetřit pamětí, rozhodl jsem se udělat vlastní.
A zase problém s navracením hodnot – do fronty chci ukládat souřadnice x,y, funkce ale může vracet jenom jednoduchou hodnotu nebo (ukazatel na) třídu, což nechci kvůli šetření pamětí. Ukládat výsledek funkce do proměnných (fuj!) se mi tentokrát nechce, tak volím jiné fuj – dvě malá čísla sbalím do jednoho int-u.

Ještě je chyba, když jde na pozici zmizelého ocasu – vyplývající z toho, co kreslím dřív, jestli přibývající hlavu nebo mizející ocas. Opravuju.

Bude ještě potřeba rozpoznat konec hry!

Shrnutí:

  • částečně zrefaktorováno, nové třídy Hra a Mapa, přeskupeni proměnných (rozměry patří hře a ne hadovi etc.),
  • zapisování a respektování obsazených políček, opraveno hlídání okrajů
  • ještě by to chtělo, aby ikony/resourcy vracel přímo Had a neřešila to Activity

8.7.2013 10:48:23
==90'
celkem 1260'

Ad 4) aby ikony/resourcy vracel přímo Had a neřešila to Activity:

Ten ocas teď nastavuju špatně, dávám tam pokaždé prázdné políčko. Návrh řešení:
  • Hadhlava_x/y, min_x/y a ocas_x/y
  • bude mit i hlava_resource, krk_resource, ocas_resource
  • ...a vlastně v ocas_x by mělo byt políčko, kde BYL! (ne kde JE) ocas
  • OK, tak to je, ale ocas by se měl měnit jen někdy, protože na to políčko může vlézt (jiný) had
    = ošetřeno, ocas se překresluje jen když had umazal ocas.
  • refaktorováno, ale rozechruto, kreslí nesmysly!
    – OK, používal jsem pohyb a min_pohyb dříve, než jsem do nich dosadil.
  • = hotovo, had nastavuje ikony/resourcy.

Ad 5) druhý had:

Nejdřív počáteční pozici hada nastavovat náhodně.

Kolikrát budu zkoušet hledat volné políčko?
Volím počet políček *4 a když se nepodaří, projedu dvěma for-cykly celé pole.

Co kdyz nenajde volné pole?
Tak či tak je to konec hry (a nejspíš nenašel volné pole pro soupeřova hada, protože pro hada hráče hledá jenom jednou na začátku, když je prázdno).
Co pak? Zatím rozhodnutí odkládám.

Dále odvodit novou třídu (a vytvořit nové resourcy), hotovo. Chodí!

Ještě (oba) hady hned na začátku zobrazit – hotovo.

Algoritmus pohybu počítačového hada – použiju stejný algoritmus, jakým se řídil v předchozích versích hry, tady ho nebudu prozrazovat.

Shrnutí:

  • mám dva hady
  • počítačovy had se řídí Algoritmem
  • na začátku se hadi zobrazí
  • mám funkci, která pozná, že počítačový had nemůže táhnout, ale zatím to nijak neřeším
  • stejnou funkcí by se dalo poznat, že nemůže táhnout hráčův had (i když zbytečně velkolepé)
  • bude čas přemýšlet nad strukturou hry, nakreslit si obrazovky etc.

Ještě zkusit nahrát do telefonu – funguje!

Bug: v určitou chvíli po zahubení počítačového hada se přestal umazávat konec (a nakreslil se umazaný obrázek doprostřed těla na [0,0]).

8.7.2013 13:50:21
==150'
celkem 1410'

Ad 6) rozpoznávat konec hry
Ad 7) ošetřit konec hry, ať ten, že nejde vyrobit had, nebo ten, když nemůže táhnout

Konce: Po chycení jednoho hada vytvořit nového, na to potřebuju ikonku: chcipla_hlava.png Dále počítat ulovené hady a nakonec kontrolovat, jestli může táhnout hráč a když ne, tak konec hry. Uděláno, funguje!

Ještě zkusit nastavit weight, aby se roztahovaly obrázky?
Weight není. Zkouším setMinimumWidth, funguje ale dělá mezery. Něco jako Scale()? Škáluje obrázek, ale nezvětší rozměry. Odkládám, až budu umět počítat rozměry okna.

Zkouším na telefonu, funguje.
Občas zmizí kostka a posune se řada, občas zmizí hlava.
GAME OVER zobrazuje počet chycených hadů zvětšený o 1 (zobrazuje počet inicializovaných hadů).

==45'
celkem 1455'

Sedmý den

Aktualizuju seznam úkolů:

  1. bug v prvním kroku (umaže se kus obrázku)
  2. bug zobrazovaný počet polapených hadů zmenšit o 1
  3. přečíst si, jak pracovat s grafikou
  4. ...a nastavovat velikosti ImageView
  5. ...) zabránit otáčení obrazovky
  6. workflow hry – sled obrazovek
  7. zvuky
  8. obrázky pro soupeřova hada
  9. grafika – hezké obrázky via Inkscape
  10. bug: při GAME OVER ještě překreslit hlavy

Ad 1) bug v prvním kroku (umaže se kus obrázku):

Projevuje se, když startuje na kraji; vypadá to, jako by umazal ocas.
Tip: nejspíš tím, že nemá minulý směr a tak vrátí resource 0?
Mohl bych testovat a nahradit v ResourceTeloSmerSmer – OK, vypadá opraveno.

Ad 2) bug zobrazovany pocet polapenych hadu zmensit o 1: OK, opraveno

Ad 3) přečíst si, jak pracovat s grafikou: Tutoriál na zdrojak.cz odkazoval na http://www.higherpass.com/Android/Tutorials/Working-With-Images-In-Andro...

==20'

Hmm... přečteno, ale je tam jen nastavení obrázku do ImageView, načteni bitmapy ze souboru a škálování a pootočení bitmapy, ale já asi nechci škálovat bitmapy (i když bych mohl, mohl bych si z resourcu ty bitmapy načíst do pole bitmap a tam je oškálovat a pak místo int resourcu používat int index do pole bitmap... chci to?)

Zkusit vyhledat nastavení velikosti ImageView: Nacházím

ImageView:ScaleType = FIT_END
zkouším to – a ne.

Asi by pomohl GridLayout, ale na to si udělám jiný projekt:
Kopíruju projekt Pokus5, potom Undo – a Eclipse mi smazal projekty Pokus5 i Pokus4!! Ve windowsím koši – nic! Dva dny práce v tahu!

Koukám do Hg – správce versí – nebylo mi moc jasné, co z té struktury adresářů mám přidat do projektu, nicméně ze včerejšího večerního commitu zachraňuju všechny zdrojové texty v Javě a všechny obrázky kromě chcipla_hlava.png. Přijatelná cena za tak veliké poučení, od té chvíle po každém větším kusu práce balím celou složku a ještě zálohuju na USB FLASH disk.

Zakládám nový projekt a zkouším ho rozchodit alespoň tak, jak chodil včera. Daří se a tak znovu provádím dnešní opravy. Oceňuju svůj pracovní deník (podle kterého ostatně i teď píšu tyto zápisky).

Po obnovení projektu do fáze před Undo se vracím ke GridLayoutu, ale zjišťuju, že vyžaduje API level 14. Tím bych vyloučil všechny starší telefony, včetně svého, takže zavrhuju.
Další tip = GridView? Od které verse je? Tomu verse 8 nevadí!

==110'
celkem 1585'

A co RelativeLayout? Jak se používá? A co TableLayout? A View má metodu .layout(), view.setLeft() nedělá nic, view.layout taky nedělá nic.

Zkusit programově vytvořit TableLayout?
Zkouším na obrázku, rozšiřuje ViewGroup a prvkům nastavuje layout: to funguje! Nemůžu instancovat ViewGroup, tak si musim vytvořit odvozený typ MujGrid (ale nic neměním) – zvětšuje obrázky!

Jak zjistím velikost obrazovky? Na kolik mám zvětšovat? Bude to zvětšovat i na mém telefonu?

==25'
celkem 1610'

Na vyzkoušení vytvářím nový projekt-pokus, tentokrát zkracuju z Pokus# na PK7 a u toho názvu už zůstanu.
Zjišťuju, jak zjistit velikost obrazovky (za čas uvidím, že to nestačí), zatím ale funguje, zkouším na telefonu, tam taky.

==55'
celkem 1665'

Zkouším opravovat bug s mazáním ocasu, po 15 minutách opouštím zatím nevyřešený.

==15'
celkem 1680'

Večer v Inkscape kreslím obrázky jednotlivých částí hada, u některých je špatně výška, takže je had zubatý, ale vypadá to docela roztomile, možná to nechám.

==80'
celkem 1745'

Osmý den

Prázdninový den, ráno konzultace ve škole a zbytek dne u vody, jen večer 90 minut na novém projektu PK8 zkouším přehrávat zvuky, nahrál jsem si je pomocí telefonu, z formátu .amr do potřebného .ogg zkonvertoval online konvertorem - a někde je chyba a nepřehrávají se.

==90'
celkem 1835'

Devátý den

Rekapitulace, co všechno potřebuju udělat a z toho pořadí, co dnes:

  • zabránit otáčení obrazovky
  • workflow hry – sled obrazovek
  • zvuky
  • obrázky pro soupeřova hada
  • bug: při GAME OVER ještě překreslit hlavy
  • bug: maže ocas v prvním kroku
  • bug: občas umaže prostředek (vždycky na [0,0]? problém fronty?)
  • grafika – opravit left_right (snížit)
  • grafika – koncový obrázek soupeře
  • okno s návodem před hrou
  • okno About s počtem her, tahů, času(?) a reklamou na PRO versi
  • stats – počítat hry, tahy, (čas), ukládat (jak ukládat?)
  • žebříček (jak ukládat?)
  • screenshot (jak?)
  • menu
  • co dělat po ukončení hry (- viz workflow)
  • zabránit otáčení obrazovky
    (vnutit landscape layout)

Tak a ted pořadí:

  1. bug: občas umaže prostředek (vždycky na [0,0]? problém fronty?)
  2. bug: maže ocas v prvním kroku:
  3. grafika – opravit left_right (snížit)
  4. grafika – koncový obrázek soupeře
  5. workflow hry – sled obrazovek
  6. úvodní okno
  7. vyzkoušet (na jiné aplikaci) přechody mezi okny/workflow
  8. menu
  9. okno About
  10. rozchodit zvuky

Bug umazávání kusu hada je hloupá chyba – maximální velikost fronty nastavuju na počet políček krát dva plus malá rezerva – a ty velikosti x a y jsem sčítal místo násobil. Tím se vyřešil i druhý bug.

Opravuju výšku obrázků a kreslím chcíplou hlavu soupeřova hada.

Píšu si seznam obrazovek a přechody mezi nimi:

  • UVOD: úvodní obrazovka:
    • Název (Snake vs. snake, Hadí lov, Hadí doupě, Snake hunt, Snake pit...)
    • (obrázek)
    • návod:
      Taháním prstu posouváte svého hada.
      Cíl je uzavřít co nejvíce soupeřových hadů.
      Šťastný lov!
    • tlačítko start (zahájí hru v posledním nastaveném rozlišení)
  • HRA: okno hra
    • funguje menu, tim lze restart
  • menu:
    • Screenshot [disabled]
    • New game:
      • 8x8
      • 10x10
      • 8x12
      • 12x20 [disabled]
      • 18x30 [disabled]
    • Best results: (asi ne top-x, protože bude všechno stejné, málo hodnot),
      jen pro každé rozlišení kolik a datum-čas
    • Reset (vymazat rekord)
    • About
    • Exit
  • ABOUT: About
    • (C)
    • počet odehraných her, (tahy), (čas)
    • odkaz na PRO versi. "Why not try the PRO-version/SnakePit Pro?"

==95'
celkem 1930'

Na pokusné aplikaci zkouším přechody mezi okny/aktivitami a zkoumám, jak se dělá menu a podmenu a jak se obsluhují události. Objevuji nastavení

android:showAsAction="ifRoom"
, které položky z menu vyhodí do obrazovky... pokud je tam místo.

Ještě otázky:

  • Q1) neměla by úvodní ubrazovka být totéž co About? (až na tlačítko START?)
  • Q2) pokud ne, jak zobrazím úvodní obrazovku,
    abych z ní přešel do MainActivity a už se nikdy nevrátil?
  • Q3) jak se vůbec dělají přechody mezi aktivitami (vím jen intent)?
a odpovídám si na Q1, že ne.

Přenáším menu z pokusné aplikace do PK7.

11.7.2013 10:41:23
==95'
celkem 2025'

Vytvářím úvodní aktivitu a z ní přechod na hru. Funguje.

==50'
celkem 2075'

Večer zkouším znovu rozchodit zvuky a daří se, pomocí MAGIX Music Maker z nich ořezávám prázdné místo na začátku, přidávám nastavování hlasitosti podle nastavené hlasitosti telefonu.

==90'
celkem 2165'

Desátý den

12.7.2013 16:31:16

Začínám až odpoledne.

Vytvářím třídu Stats na statistiky.
Zkoumám možnosti ukládání Androida a vybírám si SharedPreference – dvojice key-value. Programuju zápis a čtení, zobrazování Top scores a nulování (nulování přesouvám z menu do okna Top scores).

==110'
celkem 2275'

Doplňuju překreslení Top scores po vynulování a kreslím chcíplou hlavu s krkem do čtyř stran (doteď byla jen jedna, bez krku).

Objevuju bug, po vytvoření nového hada soupeře je had hráče bez krku. Podezřívám funkci, která vykresluje hlavy.

==25'
celkem 2300'

V sobotu nezapínám počítač.

Jedenáctý den

Řeším bug s hlavou bez krku.

Rekapituluju úkoly a vybírám, co dál:

  1. EditText v About změnit na TextView
  2. ikonka
  3. zabránit otáčení obrazovky (vnutit landscape nebo portrait layout)
  4. obrázek v Info, About

Změna v About je jednoduchá, zabránění otáčení řeší jeden řádek do AndroidManifest.xml.

Kreslím v Inkscapu ikonku, kterou jsem si v pátek v metru nakreslil do sešitu (metro je moje studovna) a přemýšlím nad názvem.
Nakonec vytvářím dvě aplikace se dvěma ikonkami a ptám se na názory svých spolubydlících.

A hraju si s layoutem oken Intro, About a Top.

==185'
celkem 2485'

Dvanáctý den

Nastavuju svislou orientaci i ostatním aktivitám.

Měním výpočet výsledného hodnocení – kromě počtu se tam započítává i délka hada, takže je větší prostor výsledků než jen 1, 2, 3, 4...

==40'
celkem 2525'

Programuju Screenshot.
Zkoumám možnost uložit screenshot aktuální obrazovky a rozhoduju se kreslit ho sám.
K tomu potřebuju umět vytvořit bitmapu, doplnit informaci, jaký obrázek je na jaké pozici hry (od teď při změně zapisuju index do Tagu), získat obrázek z resourců odpovídající určitému id, výslednou bitmapu uložit a kam (a permission, aby aplikace mohla zapisovat).
A nakonec pomocí intentu zavolat něco, co ten screenshot zobrazí.

==230'
celkem 2755'

Odpoledne si vytvářím vývojářský účet na Google Play;
abych mohl zaplatit požadovaných 20 dolarů, musím si vytvořit účet na Google Wallet a protože chci vyzkoušet i placené aplikace, zakládám si "obchodnický" účet.

Protože obchodník musí mít web, zakládám web softh.geometry.cz, zatím s jedinou stránkou.

Dávám taky vyzkoušet program kamarádovi, zjišťuje problém – nastavuju obsah podle velikosti obrazovky, ale tu nemám k dispozici celou, část zabírá nadpis se jménem aplikace. Přidávám do ToDo listu.

==55'
celkem 2810'

Večer doplňuju detailní informace o svém účtu, zřejmě si online ověřuje, protože s tím dost dlouho zápasím, nakonec prošlo, jméno majitele účtu to chce bez diakritiky.

Google slibuje, že mi pošle pár korun a že až dojdou, tak napsáním kolik mi přišlo, potvrdím, že to poslali na správný účet.

==50'
celkem 2860'

Hledám, jak řešit problém s rozměry, čtu rady a experimentuju.

==75'
celkem 2935'

Přidávám nové rozměry hry – 15x20 a 15x20spec (s překážkami).

Přemýšlím nad problémem s rozměry, nakonec využívám aktivitu Intro, která se zobrazuje po startu, na ní si můžu oměřit dostupnou velikost a později ji použít při vytváření aktivity okna hry.
Zkouším i na telefonu a funguje.

==40'

Třináctý den

Aktualizuju seznam úkolů a plán:
Aktualizovaný seznam úkolů (některe nové):

  • bug velikost obrazovky (na kamarádově telefonu chyběl spodek, nejspíš proto, ze nepočítám výšku horní lišty se jménem aplikace)
  • softh.geometry.cz – změnit adresu v účtu Google Play
  • softh.geometry.cz – vytvořit obsah (nejspíš nainstalovat drupal)
  • Zdroják tutoriál – jak vyrobit ikonu ve všech rozlišeních (z velikosti 512x512px) – prečíst a udělat podle toho
  • PRO příznak nastavovat visible u Screenshotu a dalších typů nové hry
  • další typy nové hry – menu a realizovat
  • Top scores i pro nové rozměry – ukládat, porovnávat
  • bug – název souboru screenshotu asi je nějak zkomolený
  • název – nový nápad SSSnakes
  • tam, kde se vyskytuje název aplikace (přinejmenším ještě jméno adresáře pro screenshoty), používat proměnnou/resource, aby se měnilo jen na jednom místě
  • About: moje jméno v copyrightu změnit na SOFTH software
  • zformátovat stránku Top scores
  • ikona Snakes vs PK12 (PK12 má lepší) odloženo až za ikonu podle tutoriálu (512x512px)
  • telefon po screenshotu otevírá Gallery dvakrát za sebou!
Plán:
  1. About: moje jméno v copyrightu změnit na SOFTH software
  2. bug – název souboru screenshotu asi je nějak zkomolený
  3. telefon po screenshotu otevírá Gallery dvakrát za sebou!
  4. Top scores i pro nové rozměry – ukládat, porovnávat
  5. zformátovat stránku Top scores
  6. tam, kde se vyskytuje název aplikace (přinejmenším ještě jméno adresáře pro screenshoty), používat proměnnou/resource, aby se měnilo jen na jednom místě

Opravuju jméno v About.

Opravuju jméno souboru se screenshotem a zjišťuju, jak správně určit datum a čas.

Opravuju násobné otevírání Gallery po screenshotu.

Přidávám ukládání Top scores i pro nové rozměry.

Výskyty názvu aplikace (třeba cesta pro ukládání screenshotu) předělávám na odkaz do resources.

Pokud jde o název, asi zůstanu u SSSnakes, jako hadí zvuk i jako SOFTH software i jako odlišení od milionu ostatních hadů, co jsou na Google Play.

Zkouším na telefonu a funguje.

==90'
celkem 3025'

Postřeh: když ukončím program klávesou Zpět, příště startuje od začátku. Neměl bych to ukládat? Deset minut zkoumám a docházím k závěru, že neměl.

Změna layoutu aktivity s Top scores – hraju si s tím na novém projektu, zápasím s XML a layout_weight a dalšími, nakonec objevuju chybu v tom, že jeden z layoutů měl nastavenu velikost wrap_content, po změně na match_parent už vypadá dobře.
Přenáším do hlavního projektu PK7 a ověřuju na telefonu.

==130'
celkem 3155'

Odpoledne na softh.geometry.cz instaluju Drupal.

==40'
celkem 3195'

Pozdě večer opravuju bug, že nulování rekordů nenulovalo ty nově přidané. Upravuju layout About.

Chci mít dvě verse programu – Free a PRO.
Nechci udržovat dvě verse zdrojového textu, nebo, pokud nebude vyhnutí, s tím chci alespoň mít co nejméně práce.
Takže všechno programuju jako PRO a jen některé funkce ve versi Free nebudou přístupné.
Zakládám class Version s proměnnou, která říká, jestli je tahle verse Free nebo PRO.

Nakonec na novém projektu PK14 zkouším, jestli Eclipse opravdu umí z jedné bitmapy vygenerovat ikonky aplikace v různých rozlišeních – umí!

==70'
celkem 3265'

Čtrnáctý den

Při inicializaci menu podle verse programu měním nastavování Enabled na Visible ("bude vidět a nepůjde použít" na "nebude vidět").

Nastavuju viditelnost i v Top results, aby se nezobrazovaly výsledky her, jaké v téhle versi nejsou.

Vyhazuju nadbytečné ladicí hlášky.

Procházím checklist z tutoriálu, vytvářím podepsanou aplikaci a uploaduju na Google Play.

Zádrhele – nejdříve podepsaná aplikace.
Pak ikona 512x512px; moje ikona není přesně čtvercová, a i když je to průhledný PNG, Google Play trvá na 512x512px.
Plus vyplnit řadu údajů, nadělat screenshoty a tak.

Bude zveřejněno časem...

==160'
celkem 3425'

Večer vytvářím nový projekt PK7PRO, jako kopii z PK7. Měním ikonu, versi, strings.xml, AndroidManifest.xml.

Podepisuju, publikuju, instaluju na telefon – hlásí, že nahradí jinou aplikaci. Zjišťuju, že aplikace v Androidu je identifikovaná jménem package.

Objeven bug: Gallery padá, když má zobrazit uložený screenshot, ale ten screenshot na SD-kartě uložený je.
Problém zřejmě galerii dělá adresář "SSSnakes PRO", tedy ta mezera ve jméně.

==80'
celkem 3505'

Patnáctý den

Jméno SSSnakes se mi v noci přestalo líbit.
Uvažuju o přejmenování, ale nevím, jestli to jde a nevím, co na to řeknou (četní) uživatelé. Navíc kdo ví, co se lidem líbí...

Přidávám konstantu se jménem adresáře pro screenshoty, bez mezery.

Přejmenovávám package u PK7PRO.

==60'
celkem 3565'

Podepisuju, zkouším na telefonu a publikuju PK7PRO na Google Play jako placenou aplikaci.

Nastavuju cenu na 1 dolar resp. 19,70 korun. Napsal a publikoval jsem aplikaci na Google Play, mise splněna.

==75'
celkem 3640'

Čas: 3640 minut, tj. 60 hodin, během 15 prázdninových dnů. Bylo to prima.

3180 řádek deníku
2320 řádek zdrojových kódů v Javě.

con icon

Epilog

V dalších dnech, netrpělivě sleduji vývojářskou konzoli, opravuji bugy, přejmenovávám na Brain Snakes, přidávám českou lokalizaci popisu i programu a 25.7.2013 21:03:51 zaznamenávám první stažení. Nevidím údaje o jednotlivých uživatelích, na druhou stranu, když je ten uživatel jen jeden, tak jako bych viděl:
  • země: Pákistán
  • zařízení: Sony Ericson LE26i
  • Android: 4.1

Post scriptum

Zhruba po roce Google změnil podmínky pro vývojáře publikující programy v Google Play.
Ty změny zněly rozumně, ale protože vývoj mobilních aplikací není to hlavní, co chci dělat, nepotvrdil jsem souhlas se změněnými podmínkami, takže se už nedostanu do vývojářské konzole a po čase i ty aplikace zmizely z obchodu. Kdyby je někdo chtěl, jsou tady:

icon



Průměr: 4.8 (4 votes)