Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

3. diel - Hracia kocka vo VBA - Zapuzdrenie, konštruktor a Random

V minulej lekcii, Prvá objektová aplikácia vo VBA - Hello object world , sme si vytvorili svoju prvú objektovú aplikáciu pre VBA - Hello object world. Naučili sme sa tvoriť triedy (class), atribúty a metódy s parametrami.

Dnes vo VBA tutoriáli začneme pracovať na sľúbenej aréne, v ktorej budú proti sebe bojovať dvaja bojovníci. Boj bude ťahový (na preskáčku) a bojovník vždy druhému uberie život na základe sily jeho útoku a obrany druhého bojovníka. Simulujeme v podstate stolnú hru, a preto budeme simulovať aj hraciu kocku, ktorá dodá hre prvok náhodnosti. Začneme zvoľna a vytvoríme si najskôr túto hraciu kocku. Zároveň sa dnes naučíme, ako sa definuje vlastný konštruktor.

Vytvorenie projektu

Vytvorme si nový excelovský súbor a pomenujme si ho ako Arena. K projektu si pridajme novú triedu (triedny modul Class Module) s názvom Kostka. Rovnako si pridajme nový modul (bežný modul Module), ktorý si pomenujeme Hlavni.

Zamyslime sa nad atribútmi, ktoré kocke dáme. Iste by sa hodilo, keby sme si mohli zvoliť počet stien kocky (klasicky 6 alebo 10 stien, ako je zvykom pri tomto type hier). Ďalej bude kocka potrebovať generátor náhodných čísel. Naša trieda bude mať teraz 1 atribút:

  • pocetSten typu Long.

Zapuzdrenie

Minule sme kvôli jednoduchosti nastavovali všetky atribúty našej triedy ako Public, teda ako verejne prístupné. Väčšinou sa však skôr nechce, aby sa dali zvonku modifikovať, a používa sa modifikátor Private. Atribút je potom viditeľný len vo vnútri triedy a zvonku sa VBA tvári, že vôbec neexistuje. Pri návrhu triedy teda nastavíme všetko na Private av prípade, že niečo bude naozaj potrebné vystaviť, použijeme Public. Naša trieda teraz môže vyzerať nejako takto:

' Třída reprezentuje hrací kostku.
Option Explicit
' Počet stěn kostky
Private pocetSten As Long

Konštruktory

Až doposiaľ sme nevedeli zvonku nastaviť iné atribúty ako Public, pretože napr. Private nie sú zvonku viditeľné. Moderné programovacie jazyky nám preto ponúkajú inú lepšiu možnosť, ktorou je konštruktor. Konštruktor je vlastne metóda, ktorá sa zavolá vo chvíli vytvorenia inštancie objektu. Slúži samozrejme na nastavenie vnútorného stavu objektu a na vykonanie prípadnej inicializácie. Kocku by sme teraz v module Hlavni vytvorili takto:

Dim Kostka As Kostka
Set Kostka = New Kostka

Ak sme si kocku pomenovali s malým písmenom „k“ na začiatku, automaticky sa nám zmení aj názov triedy, ktorý bol doteraz písaný veľkým písmenom „K“. Je to iba estetický problém nášho IDE

Na rozdiel od modernejších jazykov vrátane príbuzného jazyka VB.NET, umožňuje jazyk VBA vytvoriť iba jeden konštruktor. Ten si teraz do našej triedy Kostka pridáme. Ide vlastne o metódu s názvom Class_Initialize(). Naša trieda Kostka teda bude teraz vyzerať takto:

' Třída reprezentuje hrací kostku.
Option Explicit
' Počet stěn kostky
Private pocetSten As Long

Private Sub Class_Initialize()

End Sub

Deklaruje sa ako súkromná metóda bez návratového typu.
V konštruktore si ešte nastavíme počet stien na pevnú hodnotu a vložíme metódu na inicializáciu generátora náhodných čísel Randomize(). Generátor sa nám neskôr bude hodiť pri generovaní náhodných čísel.

Konštruktor bude teda vyzerať nasledovne:

Private Sub Class_Initialize()
    Randomize ' Inicializace generátoru náhodných čísel
    pocetSten = 6
End Sub

Ak teraz vytvoríme objekt triedy Kostka, bude mať atribút pocetSten tohto objektu hodnotu 6. Skúsme si teda vypísať počet stien do konzoly, nech vidíme, že tam hodnota naozaj je.

Nie je dobré atribút nastaviť na Public, pretože nebudeme chcieť, aby nám niekto mohol už pri vytvorenej kocke meniť počet stien. Preto sme koniec koncov aj pre tento atribút použili modifikátor prístupu Private.

Pridáme teda do triedy metódu VratPocetSten(), ktorá nám vráti hodnotu atribútu pocetSten, čím v podstate docielime to, že môžeme atribút používať na čítanie. Nie je teda viditeľný, jeho hodnotu je možné iba čítať a zmeniť ju nie je možné. VBA má na tento účel ešte ďalšie konštrukcie, ale tým sa zatiaľ nebudeme zaoberať.

Nová metóda bude vyzerať nejako takto:

Public Function VratPocetSten() As Long ' Vrátí počet stěn kostky
    VratPocetSten = pocetSten
End Function

Presuňme sa do modulu Hlavni, vytvorme si metódu Arena() av nej si skúsme vytvoriť kocku a vypísať počet jej stien:

Private Sub Arena()
    Dim Kostka As Kostka
    Set Kostka = New Kostka
    Debug.Print Kostka.VratPocetSten
End Sub

Výstup:

Konzolová aplikácia
6

Vidíme, že sa konštruktor naozaj zavolal. My by sme ale chceli, aby sme mohli pri každej kocke pri jej vytváraní špecifikovať, koľko stien budeme potrebovať. V modernejších jazykoch vrátane príbuzného VB.NET by sme to docielili pridaním parametra do konštruktora a pri vytváraní objektu by sme potrebný počet strán špecifikovali nejako takto: Set Kocka = New Kocka(potrebny­PocetSten). To ale bohužiaľ VBA neumožňuje.

Riešenie tohto problému je niekoľko, ale ani jedno nie je ideálne. Atribút pocetSten môžeme nastaviť späť ako verejný, alebo si môžeme vytvoriť verejnú metódu na nastavenie tohto atribútu. O trošku lepšie riešenie, aj keď tiež nie je optimálne, je vytvoriť si verejnú metódu, ktorú budeme dôsledne používať iba pri vytváraní nového objektu. Nesmieme ale zabudnúť ju zavolať:

Public Sub Konstruktor(aPocetSten As Long) ' Pseudokonstruktor pro inicializaci vnitřního stavu třídy
    pocetSten = aPocetSten
End Sub

Všimnime si, že sme pred názov parametra metódy pridali znak "a", pretože inak by mal rovnaký názov ako atribút a VBA by to zmiatlo. Vráťme sa k modulu Hlavni a skúsme si teraz vytvoriť ešte kocku s 10 stenami. Pre názornosť som doterajšiu kocku premenoval na kostka6 a novú kocku s 10 stenami som pomenoval ako kostka10:

Private Sub Arena()
    Dim kostka6 As Kostka
    Set kostka6 = New Kostka

    Dim kostka10 As Kostka
    Set kostka10 = New Kostka
    kostka10.Konstruktor (10)

    Debug.Print kostka6.VratPocetSten
    Debug.Print kostka10.VratPocetSten
End Sub

Výstup:

Konzolová aplikácia
6
10

Pri kocke s 10 stranami nám síce VBA vytvorí kocku so 6 stranami, ktoré ale následne v pseudokonštruktore zmeníme na 10. Je to trošku krkolomné a nám nezostáva, než dúfať, že niekto v budúcnosti VBA zmodernizuje.

Pre tých z vás, ktorí majú skúsenosť z jazykov, ako je Java, VB.NET a pod., by som rád ešte dodal, že VBA neumožňuje ani preťažovanie (overload) konštruktorov či metód.

Opustíme problematiku konštruktorov a zameriame sa na hlavnú funkciu kocky, ktorou je poskytovať hráčovi náhodné čísla.

Náhodné čísla

Definujme na kocke metódu Hod(), ktorá nám vráti náhodné číslo od 1 do počtu stien. Je to veľmi jednoduché. Metóda bude Public (pôjde volať zvonku) a nebude mať žiadny parameter. Návratová hodnota bude typu Long.

Náhodné číslo získame tak, že zavoláme funkciu Rnd(), ktorá vracia náhodné hodnoty v intervale od 0 vrátane do menej ako 1. Zároveň použijeme aj funkciu Int() vracajúcu celé číslo (bez desatinnej hodnoty). Aby sme mohli funkciu Rnd() používať, inicializovali sme si už skôr generátor náhodných čísel.

Metóda bude vyzerať takto:

Public Function Hod() As Long ' Vykoná hod kostkou
Hod = Int((pocetSten * rnd) + 1)
End Function

Kocka je takmer hotová.

Ešte si ale vytvoríme v našej triede jednu užitočnú metódu, ktorú môžeme hojne používať aj vo väčšine našich ďalších objektov, a ktorá nám bude naša inštancia textovo prezentovať. Ja som si ju pomenoval ako Nazev(). V prípade kocky nám kocku predstaví a povie nám o nej nejaké užitočné informácie. V tomto prípade ma napadá iba údaj o počte strán:

Public Function Nazev()
Nazev = "Kostka s " & pocetSten & " stranami"
End Function

Nakoniec si naše kocky vyskúšame a využijeme pri tom aj predchádzajúcu metódu Nazev(). Skúsime si s nimi v cykloch hádzať a pozrieme sa, či fungujú tak, ako sa očakáva:

Private Sub Arena()
    Dim kostka6 As Kostka
    Set kostka6 = New Kostka

    Dim kostka10 As Kostka
    Set kostka10 = New Kostka
    kostka10.Konstruktor (10)

    Dim i As Long

    Debug.Print kostka6.Nazev
    For i = 1 To 10
        Debug.Print kostka6.Hod
    Next i

    Debug.Print kostka10.Nazev
    For i = 1 To 10
        Debug.Print kostka10.Hod
    Next i

End Sub

Výstup môže vyzerať nejako takto:

Konzolová aplikácia
Kostka s 6 stranami
 5
 6
 5
 3
 4
 2
 6
 4
 3
 6
Kostka s 10 stranami
 1
 10
 6
 8
 5
 2
 3
 7
 3
 7

Máme hotovú celkom peknú a nastaviteľnú triedu, ktorá reprezentuje hraciu kocku. Bude sa nám hodiť v našej aréne, ale môžeme ju použiť aj kdekoľvek inde. Vidíme, ako OOP umožňuje znovu používať komponenty.

V budúcej lekcii, Bojovník do arény vo VBA - Výpis bojovníka , začneme pracovať na objekte bojovníka. Môžeme sa tešiť na výpis jeho života v grafickej podobe.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 10x (15.27 kB)
Aplikácia je vrátane zdrojových kódov

 

Predchádzajúci článok
Prvá objektová aplikácia vo VBA - Hello object world
Všetky články v sekcii
Objektovo orientované programovanie (OOP) vo VBA
Preskočiť článok
(neodporúčame)
Bojovník do arény vo VBA - Výpis bojovníka
Článok pre vás napísal Michal D.
Avatar
Užívateľské hodnotenie:
1 hlasov
Autor se věnuje tvorbě mobilních aplikací.
Aktivity