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
typuLong
.
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(potrebnyPocetSten). 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