Online Android szakkör (DKRMG)
Az első két lecke elvégzése után (telepítés és Hello World) végre belevághatunk az Android programozásba! A Hello World alkalmazásunk az előző alkalommal ugyan fontos lépésnek számít, komoly applikációnak mégis csak jóindulattal lehet nevezni.
Ma ehhez képest megírjuk az első androidos játékunkat!
Nem, repkedő mérges madarakat ma még nem fogtok látni a képernyőn. Ehhez képest kihívhatjuk a telefonunkat egy olyan küzdelemre, ami próbára teszi az agyunkat és a kitartásunkat: következzen a számkitalálós játék.
A számítógép/telefon gondol egy számra 1 és 100 között. A mi feladatunk kitalálni, hogy a gép melyik számra gondolhatott! Ehhez:
A programozás szépsége, hogy ezt az egyszerű játékot is rengeteg különböző módon lehetne elkészíteni. Mivel ez az első komolyabb programunk, mi most maradjunk a felhasználói felület legegyszerűbb elemeinél:
A kész alkalmazás képe már látható is a szöveg mellett.
A lecke folyamán…
Az egyszerűség kedvéért előkészítettünk nektek egy projektet (GuessGame), ami nagyon hasonló a 2. leckében létrehozott Hello World projekthez, csak pár szükségtelen dolgot kiszedtünk belőle, illetve a Java kódba segítségként némi útmutatást helyeztünk el.
Ahhoz, hogy a projektet használni tudjuk, importálni kell az Android Studio-ba:
File -> Close
project menüponttal.
Import project
sort.
Mielőtt belekezdünk a fejlesztésbe, érdemes a File -> Settings
menüben beállítani pár dolgot,
ami megkönnyíti majd a munkát.
Editor -> General -> Appearance
oldalon a Show line numbers
legyen kipipálva. Így sokkal könnyebb lesz hivatkozni
a kód egyes részeire.Editor -> General-> Code completion
oldalon a Case sensitive completion
értéke legyen None. Így kis- és
nagybetűvel is elkezdheted majd írni a metódus és objektumneveket, a fejlesztőkörnyezet mindenképp tud
majd segíteni.Editor -> General-> Auto import
oldalon az Optimize imports on the fly
és az Add unambigous imports on the fly
is legyen kipipálva.A végén a beállításokat az OK gomb megnyomásával mentsd el!
Első lépésként most megtanuljuk, hogy miként lehet könnyedén és gyorsan felhasználói felületet építeni. Ha programozás szakkörön találkoztál már a Lazarus-szal, némi előnnyel indulhatsz neki ennek a fejezetnek. Ha nem, akkor se csüggedj, ez az applikáció készítés egyik legegyszerűbb része!
Nézd meg, hogy az ablak bal oldalán megjelenik-e a projekted tartalma az alábbi módon:
Ha nem, akkor:
View -> Tool
Buttons legyen pipálva)
Project
gombra a bal
szélen megjelent sávon.
app -> res -> layout -> activity_main.xml
fájlt.
Design
fül van az ablak alján kiválasztva. Ilyekor mefjelenik a layout szerkesztő
összetett, ám igen hasznos ablaka.Miért van egy szinte üres projektben ennyi mappa és fájl? Ezt a kérdést most nem is fogjuk megválaszolni, nem akarunk senkit oldalakon keresztül az Android azon részével untatni, amit „mezei” programozóknak ismernie sem kell. A hasznos dolgokkal a szakkör folyamán meg fogunk ismerkedni, egyelőre el kell fogadni, hogy ez így van!
Egy fontos dolgot azonban még most tisztáznunk kell. Amikor az alkalmazásunkat készítjük, két különböző ablakban, két különböző felülettel fogunk találkozni:
Ha eddig pontosan követtük az utasításokat, akkor megjelent a Design ablak egy okostelefon képével, ami megmutatja nekünk: mi is fogadna bennünket, ha az alkalmazásunkat most egy igazi készüléken/emulátorban elindítanánk.
Amikor a layout üres, a telefon képernyője is üres marad. Ebből bizonyára rájöttél, hogy máris van egy
komponensünk, egy úgynevezett TextView
, amelyen az általunk begépelt szellemes szöveg látható.
A komponenseinknek vannak tulajdonságai is, mivel mégsem nézhet ki minden felirat ugyanúgy! Jobb oldalt a
Properties
részen találjátok az épp kijelölt komponens összes tulajdonságát.
Próbaként kattints rá egyszer a TextView
komponensünkre (Ez itt egy szöveg!
), és nézd meg a tulajdonságait.
text
(szöveg) tulajdonságot, kattints a mezőre, amely a jelenlegi szöveget tartalmazza
és írd át valami másra! Az Enter leütése után a képernyőn is változik a felirat!
Próbálj meg ne a mező jobb szélén lévő […] gombra kattintani. Ha a Resources
ablak mégis véletlenül
felugrik, zárd nyugodtan be.
textAppearance/textSize
(szöveg méret). Itt megadhatod, hogy a felirat milyen méretben jelenjen meg a
kijelzőn. Próbának írd be az 50sp
értéket. Természetesen minél nagyobb számot adsz meg, a szöveg annál
nagyobb lesz, nyugodtan kísérletezhetsz kedvedre! Az sp utótagot (mértékegységet) azért kell beírnunk,
hogy különböző telefonokon is nagyjából hasonló látványt nyújtson az alkalmazásunk.
textAppearance/textColor
tulajdonságot is, ahol a megjelenített szöveg színét tudjuk
meghatározni. A mezőbe beírhatjuk közvetlenül az általunk választott szín kódját (#RRGGBB
) kettőskereszt
után tizenhatos számrendszerben (pl. #ff0000
piros, #00ff00
zöld, #0000ff
kék, #00ffff
türkiz stb.)
Nem igazodsz ki a színkódokon? Ne aggódj, az Android Studio nem is várja el ezt tőled. Ha a sor végén
található [...] gombra kattintasz id
tulajdonságot. Ez az érték segít a komponensünk megtalálásában, ez a
komponensünk neve, azonosítója. Ezt a feliratot leiras
-nak neveztük el, ékezetek nélkül.
Ezen kívül kipróbálhatod még óvatosan a textStyle
tulajdonságot is.
A bátrabbak megnézhetik a View all properties nyilak lenyomása után a Background tulajdonságot is
Ha minden igaz, akkor jelenleg van egy tetszőlegesen átszínezhető és méretezhető feliratunk. A feliratok nagyon
hasznosak, de térjünk át egy kicsit izgalmasabb komponensre: a gombokra (Button
).
Helyezzünk el egy gombot a felirat alá!
Baloldalt a Widget
kategóriában megtaláljuk a Button
komponenst.
Kattintsunk rá, majd az egérgombot lenyomva tartva húzzuk át a telefon kijelzőjére. Ahogy a kijelző különböző pontjaira mozgatjuk a gombot, láthatjuk, hogy a tervező megpróbálja a gombot a létező komponensekhez illetve a képernyő széleihez igazítani.
Tegyük le a gombot pontosan középre, valahol a képernyő alsó felén. Ekkor felengedhetjük az egér bal gombját.
Az új komponensünk hasonló tulajdonságokkal rendelkezik, mint a felirat.
Írjuk át a megjelenő szöveget (text) erre: "kattints rám!
"
nézzük meg a gomb id
tulajdonságát, mert később szükségünk lesz még rá! Ez nem más, mint button
.
Próbáljuk ki, hogy amit eddig csináltunk, hogy néz ki igazi telefonon/emulátoron! Futtassuk a projektet!
Van egy csinosan kinéző alkalmazásunk, csak sajnos még nem használható semmire. Nem reagál a gombnyomásra, nem gondol semmilyen számra. Leheljünk életet bele!
Eddig az activity_main.xml
fájlban dolgoztunk, ami azt tartalmazta, hogy hogy nézzen ki az alkalmazásunk. Azt, hogy
mit csináljon, Java nyelven kell megírnunk, az app -> java -> hu.dkrmg.android.guessgame -> MainActivity
fájlban.
Nyissuk is meg és próbáljunk meg egy pillanatig megbarátkozni a kóddal.
Ha eddig nem találkoztál még a Java nyelvvel, elsőre talán kissé sokkoló lehet a látvány. Ne félj, a többnyire angol szavakból, rövidítésekből és szimbólumokból álló kavalkád szépen lassan értelmet nyer! Mielőtt elkezdenéd az első feladatot, szeretnénk csak egy-két dolgot elmagyarázni.
Bizonyára látod, hogy a sorok nem mindig egy vonalban kezdődnek. Ennek fontos szerepe van, hogy programozóként könnyen tudjuk felismerni a program szerkezetét. Azok a sorok, amik egy vonalba vannak behúzva, azonos szinten helyezkednek el a programban. Ennek segítségével könnyen azonosíthatjuk a függvényeket, illetve az egyes függvényekben lakó kódot.
A programban elég sokszor találkozol // kezdetű sorokkal (szürke sorok a képen). Ezek a sorok kommentek, melyeket a számítógép figyelmen kívül hagy. Csak azért vannak a programban, hogy ti (és mi is) jobban átlássuk azt.
A kommentek egy speciális típusa a TODO
, ami a feladatok helyét jelöli (kék betűvel).
onClick
tulajdonságával, hogy ez a függvény fusson le amikor
megnyomjuk a gombot.
Először keressük meg az első feladatot [TODO 1] (44.sor)
, és hozzunk létre ezen a helyen egy új függvényt! Ehhez
másoljuk be a TODO sor helyére az alábbi sorokat:
public void buttonClicked(View v) {
Toast.makeText(this, "Megnyomtad a gombot!", Toast.LENGTH_SHORT).show();
}
Fontos, hogy mindent pontosan írj be! A kis-/nagybetűk, vesszők, zárójelek, idézőjelek és a sorvégi pontosvessző – mind számít!
Az 1. sor jelöli a függvényünk kezdetét: public void buttonClicked(View v) {
Amit érdemes tudni, hogy a „buttonClicked” a függvényünk neve, amit akár másra is megváltoztathatnánk.
A két kapcsos zárójel közötti rész írja le a függvény viselkedését, azaz mi történjen, ha ezt a függvényt elindítja valaki. Ez a függvény törzse. Android programozás során többnyire a függvények törzsében fogunk dolgozni.
Esetünkben ez egy felbukkanó üzenetet (Toast
) jelenít meg a telefon képernyőjén,
a "Megnyomtad a gombot!"
" felirattal, majd pár másodperc után el is tünteti.
Tehát például ez is egy helyes függvény lenne:
public void enEgyFuggvenyVagyok(View v) {
// bla-bla
// bla-bla
// és most jöjjön egy Toast
Toast.makeText(this, "Szia!", Toast.LENGTH_SHORT).show();
}
Próbáljuk is ki ()! Mi történik, ha megnyomjuk a telefonon a gombot? Ha pontosan követted a leírást,
akkor az a jó működés, hogy nem történik semmi :-) ! Ugyanis mi csak megírtuk a függvényünket, de nem kötöttük
össze a gombot a kóddal.
A gomb onClick
tulajdonságban megadhatjuk, hogy a gomb megnyomásakor melyik függvény fusson le.
activity_main.xml
fájlt. (layout)Properties
ablakban keressük meg az onClick
sort.buttonClicked
), ahova kódot írtuk. Válasszuk ki!
A layout nézetben egyszerűen ki tudunk választani egy gombot, csak rá kell kattintanunk! Mi a helyzet, ha a Java
programunkból szeretnénk hivatkozni egy komponensre? Nincs más dolgunk mint létrehozni egy változót, elnevezni
mondjuk gomb1
-nek és közölni a számítógéppel, hogy mostantól a "gomb1" változó nem más, mint az általunk
meghatározott gomb a layout szerkesztőben. De mi is az a változó?
A változó a programozásban egy tároló, aminek van:
Például létrehozhatunk egy-egy változót (a
és b
), amiben egy téglalap oldalainak hosszát tároljuk
int a; // az a oldal. int: egész szám pl. 0,1,2,3
int b; // a b oldal. int
a = 10; // az a oldal hossza legyen 10 (pl. cm)
b = 15; // a b oldal hossza legyen 15 (pl. cm)
Az első két sor a változók deklarációja (létrehozása, bemutatása), az alsó két sor pedig bemutatja, hogy miként tárolhatunk el új értéket a változóinkban.
int x;
x = 5; // x értéke legyen 5
Az értékadás (=
) után a régi érték elveszik.
x = 6; // x értéke mostantól 6!
Miért is jó, hogy vannak változóink? Például most könnyedén kiszámíthatjuk a téglalapunk területét
int terulet;
terulet = a * b; // téglalap területe: T=a*b
Más típusú változó kell, ha egy számot szeretnénk eltárolni benne, megint más, ha szöveget, vagy ha mondjuk egy gombot.
szam
nevű, egész számot tároló változót így deklarálhatunk: int szam;
szoveg
nevű, szöveget tárolót így: String szoveg;
leiras
nevű, TextView-ra hivatkozó változót pedig így: TextView leiras;
Figyelni kell, hogy az, amit bele szeretnénk rakni a változóba, belepasszoljon, azaz ugyan olyan típusú legyen, mint a változó.
szam
változóba rakjuk bele a 42 értéket: szam = 42;
szoveg
változóba rakjuk bele a "Halihó!" értéket: szoveg = "Halihó!"
leiras
rakjuk bele a leírást megjelenítő komponenst: leiras = (TextView) findViewById(R.id.leiras);
Hohó! Ez az utolsó kicsit más, mint az előzőek! Nézzük meg közelebbről. Nagyjából stimmel, van baloldalt egy
változó (leiras), utána az =
. De ami utána következik, az egy kicsit más.
A findViewById
egy beépített függvény, ami meg tudja keresni a kért komponenst,
és a fenti módszerrel el tudjuk
azt menteni egy változóba. Azt, hogy melyik komponenst kérjük, a második pár zárójel között kell megadni.
Emlékeztek? Az Új komponens hozzáadása rész előtt közvetlenül megnéztük, hogy a leírást tartalmazó szöveg-
komponensnek mi az azonosítója. Ugyan az, mint ami itt az R.id.
után szerepel. Ezt majd később megnézzük, hogy
miért van így, most fogadjuk el, hogy komponenst megkeresni így lehet:
findViewById(R.id.≤komponens azonosítója>);
Már csak egy dologról nem tudjuk, hogy micsoda: a "(TextView)
” rész. Mivel komponensből
nagyon sok féle lehet, meg kell mondanunk, hogy a változóba milyen típus passzol. Mivel a változónk típusa
TextView
, így ilyen típusú komponenst kérünk.
Pascalban / Lazarusban a változók nagyon hasonlóak.
var
a : integer; // int a; Pascalban "név : típus", nem "típus név"
...
a := 10; // a = 10; Pascalban ":=", nem "=".
A következő feladat legyen az, hogy gombnyomásra változzon meg a gomb feliratának színe!
Készíts egy új változót a gombodnak [TODO 2.1 helyére, 2x szerepel!] (Segítség: a gomb változójának típusa Button legyen!)!
Keresd meg a gomb komponensedet, és tárold el az új változódban!
Segítségként nézd meg, hogy mi hogyan csináltuk ugyanezt a "leiras
" nevű TextView
típusú változóval.
A layout komponenst az azonosítója alapján (id
) a
(<típus>) findViewById(R.id.
függvény segítségével találjuk meg!
Most egészítsük ki a gombunk buttonCliked függvényét azzal a paranccsal, ami átállítja a gombunk színét!
A gomb változónk rengeteg hasznos belső függvénnyel rendelkezik, amihez a következőképp férünk hozzá:
változóNeve.függvényNeve(...);
Amikor leütjük a pontot, az Android Studio elkezd javaslatokat tenni, hogy melyik függvényt használjuk. Írjuk be a következőt, és figyeljük, hogy a számítógép hogyan próbál nekünk segíteni!
gomb1.setTextColor(Color.GREEN);
A fenti sor azt mondja a gombnak, hogy állítsa át a szöveg színét zöld színűre. A kód talán kissé kaotikusan fest, de ez alapján remélhetőleg nem nagy feladat, ha mondjuk pirosra kéne állítani a szöveg színét!
Ellenőrizzük le, hogy tényleg az történik-e, mint amit szeretnénk, futtassunk egyet!
TextView leiras;
”
sor alá írd be ezt: Button gomb1;
. Ezzel készítettünk egy új változót.leiras = (TextView) findViewById(R.id.leiras);
sor alá írd be ezt:
gomb1 = (Button) findViewById(R.id.button);
. Most értéket adtunk a változónak.gomb1.setTextColor(color.GREEN);
. Ezzel pedig a gomb szövegének színét állítottuk be.Szuper, már nagyon szép színes szövegeket és gombokat tudunk csinálni, de elég unalmasak,
mert a szövegük nem változik. Ha figyelmesen dolgoztál, akkor láthattad, hogy amikor a fenti
gomb1.setTextColor(Color.GREEN);
sort írtad, a pont leütése után megjelent egy
kis ablak hol mindenféle függvénynevek vannak felsorolva. A gomb1.setTextColor(Color.GREEN);
sor alá kezd el újra beírni, hogy gomb1.set
, és a felbukkanó függvények közül próbáld
meg kitalálni, hogy melyik lehet az, amelyik a gomb szövegét módosítja!
Csak a függvény nevét figyeld egyelőre! A zárójelben lévő dolgokkal még ne foglalkozz!
Reméljük, te is a „setText
” nevű függvényre gondoltál. Ezzel a függvénnyel lehet módosítani minden olyan
komponens feliratát/szövegét, amin van valami szöveg. A gombnak például így módosíthatjuk a feliratát:
„gomb1.setText("Új felirat");
”. Fontos, hogy a szövegeket " "
(kettős idézőjelek, Shift+2) közé kell tenni, és a
sorvégi pontosvessző se maradjon le!
Ezt az új működést is ellenőrizzük egy futtatással!
Az előzőekben mindent megtanultunk, ami ahhoz kell, hogy eltudjuk készíteni az alkalmazást! Lássunk hozzá!
Először készítsük el a terven szereplő layout-ot: Nyissuk meg újra az activity_main.xml
fájlt, figyeljünk rá, hogy alul a Design
fül legyen aktív, és a fent
megtanult módszerrel
töltsük fel a képernyőt a szükséges komponensekkel.
Text Fields
kategóriában találjuk, innen a Number
komponenst válasszuk ki, amelyik
csak
számokat enged beírni.
layout:width
tulajdonságát átállítod match_parent
-re.
Ez
meghatározza, hogy a komponens ne a beírt szöveghez méretezze
magát, hanem töltse ki a rendelkezésére álló helyet
hint
tulajdonságba megadhatjuk, hogy milyen szöveg jelenjen
meg mielőtt a felhasználó elkezd
gépelni. pl. "ide írd a számot!"
, vagy "(szám 1 és 100 között)"
text
tulajdonságát!
TextView
, a
Widget
kategóriában találod). Itt fog megjelenni a
tipp eredménye.
A komponensek egyéb tulajdonságait (szöveg mérete, színe stb.) ezek után formázd kedved és ízlésed szerint :-)
Ha sikerült a layout szerkesztőben létrehozni a kívánt felületet, akkor eljött az ideje a
Java kód befejezésének
(bal oldalt app -> java -> hu.dkrmg.android.guessgame -> MainActivity
fájlban).
Először is gondoljuk végig, hogy milyen eseményekre kell reagálnia a telefonnak:
Felhasználó megnyomja az újrakezdés gombot
Felhasználó tippel egyet
Az újrakezdés gombhoz elvileg még megvan az eseménykezelőnk (2. feladatból a buttonClicked
függvény, ami a Toast
üzenetet dobta).
Ezt alakítsuk át, hogy a függvény belsejében csak az alábbi sor legyen:
gondoltSzam = randomGenerator.nextInt(100) + 1;
Ez garantálja, hogy a gondoltSzam
változóban egy véletlen szám legyen. A
randomGenerator
nextInt(100)
függvénye egy véletlen számot ad vissza a (0, 1, 2, 3, ...,
99) számok
közül. Figyelj, 100 nem lehet, 0 viszont igen! Ezért kell a végén egy +1, hogy
mindenképpen az 1, 2, 3, …, 99, 100 számok valamelyikére gondoljon a telefon.
A felhasználó visszajelzése egy picit hosszabb lesz ennél!
Ahhoz, hogy megtudjuk, hogy mit tippelt a játékos, először szükségünk lesz két változóra.
tippDoboz
-nak)
eredmenyFelirat
-nak)
(Segítség: a szövegdobozt tartalmazó változó típusa EditText
, az
eredményjelzőé pedig TextView
).
Ha megvannak a változóink, adjunk nekik értéket is. Ehhez meg kell keresni a belevaló
komponenst. Ilyet is csináltunk már, szintén a 2.1. feladatban. (nézd meg a komponenseid
azonosítóját – id
– azután használd a findViewById
függvényt) [TODO 4.2 helyére. 4x!]
Most, hogy megfelelően elő vannak készítve a komponenseink, már ki tudjuk olvasni a
felhasználó által beírt számot. Ez egy kicsit bonyolultabb (hiszen az EdtiText
szöveget
tartalmaz, nekünk pedig int típusú változóra van szükségünk), ezért megadjuk a kódot,
csak be kell másolni a megfelelő helyre [TODO 4.3]:
// A szövegdoboz nem tudja, hogy a felhasználó számot írt be,
// mindenképp szövegként adja vissza a tartalmát.
String szovegesTipp = VÁLTOZÓ_NEVE.getText().toString();
// Ahhoz, hogy a gondolt számot össze tudjuk hasonlítani a tippel,
// a tippet előbb számmá kell konvertálni.
int tipp = Integer.parseInt(szovegesTipp);
Ha bemásoltad, láthatod, hogy a „VÁLTOZÓ_NEVE” részt az Android Studio csúnya pirossal írja. Ez azért van, mert nem ismeri ezt a változót, mivel az nincs deklarálva. Annak a helyére kell nektek beírnotok a ti változótok nevét, amiben a szövegdobozt tároljátok (kicsit feljebb csináltuk meg).
Ezek után a felhasználó tippje a tipp
nevű, egész szám (int
)
típusú változóban lesz benne, készen a további felhasználásra.
A programunk sokszor egy feltételtől függően több féleképpen is viselkedhet.
Esetünkben például:
HA a gondoltSzam
változó értéke egyenlő a
tipp
változó értékével, AKKOR írd át a megfelelő
TextView
szövegét!
Pascal-ban találkozhattál esetleg a következővel:
if (gondoltSzam=tipp) then
begin
// valami kód
end;
A Java nyelvben is hasonlóan módunkban áll feltételeket szabni a programban.
if (feltétel)
{
// valami kód
}
Ha a zárójelben lévő feltétel igaz, akkor a kapcsos zárójelek közötti rész futtatásra kerül. Utána a program fut tovább.
Tehát pl.
// a feltétel előtti kód mindig lefut
if (gondoltSzam == tipp)
{
// ez a sor beljebb kezdődik
// Ami itt van, az csak akkor fut le, ha a gondoltSzam változó értéke egyenlő a tipp értékével
}
// vége a feltételnek. Ami itt van, az mindig le fog futni
Vizsgáljuk meg, hogy a gondoltSzam
változó (gép által gondolt szám) és a tipp változó
értéke hogyan viszonyul egymáshoz!
Írj három if
-elágazást [TODO 4.4 helyére], ami megvizsgálja
gondoltSzam
és tipp
egyenlő?gondoltSzam
kisebb, mint tipp
?gondoltSzam
nagyobb, mint tipp
?Ha nagyon elakadtál, akkor .
A feltételeknél a következő legyen a kód. A feltételeket te írd meg!
if (...egyenlő…)
{
// valami.setText("dsaad");
}
if (...tipp kevesebb mint gondoltSzam...)
{
// valami.setText("dsaad");
}
if (... tipp nagyobb mint gondoltSzam...)
{
// valami.setText("dsaad");
}
Ha nem tudod hogyan hasonlíthatod össze a változóidat, akkor kattints
Az összehasonlításnál használd:
a == b
egyenlőek?
a < b
a kisebb, mint b?
a > b
a nagyobb, mint b?
A feltételek belsejében pedig írd át a felirat (eredményjelző) szövegét, illetve állítsd át a színét (pl. pirossal: „kisebbet”, zölddel: „nyertél!”)! Hasonló feladatok már előfordultak korábban :-)
Ha ezt sikerült megírni, próbáljuk ki újra a programot. Immár lényegében kész van, egy
dologra kell odafigyelni: Mielőtt elkezdhetnénk az első játékot, meg kell nyomni az
Újrakezdés
gombot. A későbbiekben megnézzük majd, hogy hogy lehetne ezt megkerülni, de
egyelőre nézzük el ezt a kis kellemetlenséget.
Előfordulhat, hogy amikor elindítod a programot, és megnyomod a „Tippelek” gombot, nem történik semmi. Gondolkodj el azon, hogy melyik lépés maradhatott ki! Nézd vissza, hogy az első gombnál miket kellett megcsinálni!
Az elkészült programokat küldjétek el nekünk tömörítve a szakkör feltöltő lapján keresztül!
A következő feladatokat is érdemes megnézni! Ne felejtsétek, programozni gyakorlással lehet megtanulni!
A leckéhez tartozó szorgalmi feladatok ezen a lapon érthetőek el.