16. diel - Hra tetris v MonoGame: Dokončenie
V minulej lekcii, Hra tetris v MonoGame: Skóre , sme si vytvorili komponent skóre a ukázali si ako uviesť komponent do východiskového stavu pri zobrazení. V dnešnom MonoGame tutoriálu naprogramujeme ukladanie a načítanie výsledkov a všetko pekne prepojíme. Tým uzavrieme náš on-line kurz a budete mať hru hotovú so všetkým. On-line skóre si necháme do bonusovej lekcie, pretože budeme potrebovať použiť ďalšie technológie a bolo by fajn najprv dokonči hru v C# za použitia ukladania skóre do XML.
Komponent skóre využíva triedu SkoreKlient
, v ktorej máme
pripravené metódy pre ukladanie a načítanie.
Ukladanie
Budeme ukladať do súboru XML s názvom skore.xml
. Ale vôbec
nič vám nebráni, aby ste ukladali skóre podľa ľubovôle kamkoľvek inam,
aj na server, ako si ukážeme ďalej.
Štruktúra XML súboru bude vyzerať nasledovne
<?xml version="1.0" encoding="utf-8"?> <hraci> <hrac> <prezdivka><!-- Sem přijde přezdívka --></prezdivka> <body><!-- Sem přijdou dosažené body --></body> </hrac> </hraci>
V tomto formáte teda jednotlivé inštancie triedy Hrac
uložíme. Zdrojový kód metódy Uloz()
bude teraz vyzerať
takto:
public void Uloz(Hrac hrac) { if (!File.Exists(soubor)) { XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); xmlWriterSettings.Indent = true; xmlWriterSettings.NewLineOnAttributes = true; using (XmlWriter xmlWriter = XmlWriter.Create(soubor, xmlWriterSettings)) { xmlWriter.WriteStartDocument(); xmlWriter.WriteStartElement("hraci"); xmlWriter.WriteStartElement("hrac"); xmlWriter.WriteElementString("prezdivka", hrac.prezdivka); xmlWriter.WriteElementString("body", hrac.body.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteEndDocument(); xmlWriter.Flush(); xmlWriter.Close(); } } else { XDocument xDocument = XDocument.Load(soubor); XElement koren = xDocument.Element("hraci"); IEnumerable<XElement> polozky = koren.Descendants("hrac"); XElement polozka = polozky.First(); polozka.AddBeforeSelf( new XElement("hrac", new XElement("prezdivka", hrac.prezdivka), new XElement("body", hrac.body))); xDocument.Save(soubor); } }
Ak súbor neexistuje, tak ho vytvoríme a uložíme do neho prvý výsledok.
Ak už existuje, vyhľadáme element s hráčmi a pred posledného (prvého
zapísaného) pridáme novo pridávaného. Tým budeme mať výsledky zoradené
podľa posledného pridaného. Ak budeme chcieť radiť inak, vyriešime to v
komponente KomponentaSkoreTabulka
. Premenná soubor
je
reťazec obsahujúci názov súboru s príponou .xml
, ako sme si ju
minule nachystali.
Načítanie
Načítanie hráčov môže vyzerať napr. Nasledovne:
public List<Hrac> Nacti() { string element = ""; var hrac = new Hrac(); var hraci = new List<Hrac>(); using (var xr = XmlReader.Create(soubor)) { while (xr.Read()) { if (xr.NodeType == XmlNodeType.Element) element = xr.Name; else if (xr.NodeType == XmlNodeType.Text) { switch (element) { case "prezdivka": hrac.prezdivka = xr.Value; break; case "body": hrac.body = long.Parse(xr.Value); break; } } else if ((xr.NodeType == XmlNodeType.EndElement) && (xr.Name == "hrac")) { hraci.Add(hrac); hrac = new Hrac(); } } } return hraci; }
Postupne načítame zo súboru a ukladáme do zoznamu, ktorý potom vraciame.
Do toho ako pracuje XmlReader
, XmlWriter
a
XDocument
zabiehať nebudem, pretože sú detailne popísané v Práca so súbormi v C# .NET.
Pridanie hernej obrazovky
Zostáva upraviť triedu Hra
a pridať jej herné obrazovku
obrazovkaSkore
. V komponente menu navyše upravíme čo sa má
stať ak užívateľ bude na položke Skore a stlačí Enter. Kód
bude vyzerať nasledovne:
Hra.cs
public HerniObrazovka obrazovkaMenu, obrazovkaLevel, obrazovkaAutori, obrazovkaSkore; // přidáno /* Ostatní kód */ protected override void Initialize() { KomponentaMraky mraky = new KomponentaMraky(this); KomponentaLevel level = new KomponentaLevel(this); KomponentaAutori autori = new KomponentaAutori(this); KomponentaSkoreTabulka skoreTabulka = new KomponentaSkoreTabulka(this); // přidáno KomponentaPolozkyMenu polozkyMenu = new KomponentaPolozkyMenu(this, new Vector2(700, 250), Color.Red, Color.Yellow, 80); polozkyMenu.PridejPolozku("StArT"); polozkyMenu.PridejPolozku("SkOrE"); polozkyMenu.PridejPolozku("AuToRi"); polozkyMenu.PridejPolozku("KoNeC"); KomponentaMenu menu = new KomponentaMenu(this, polozkyMenu); obrazovkaMenu = new HerniObrazovka(this, mraky, menu); obrazovkaLevel = new HerniObrazovka(this, mraky, level); obrazovkaMenu = new HerniObrazovka(this, mraky, menu, polozkyMenu); obrazovkaAutori = new HerniObrazovka(this, mraky, autori); obrazovkaSkore = new HerniObrazovka(this, mraky, skoreTabulka); // přidáno foreach (GameComponent komponenta in Components) { PrepniKomponentu(komponenta, false); } graphics.PreferredBackBufferWidth = sirkaOkna; graphics.PreferredBackBufferHeight = vyskaOkna; graphics.IsFullScreen = false; graphics.ApplyChanges(); base.Initialize(); }
KomponentaMenu.cs
public override void Update(GameTime gameTime) { // enter - akce podle vybrané položky if (hra.NovaKlavesa(Keys.Enter)) { switch (polozkyMenu.vybranaPolozka.text) { case "StArT": hra.PrepniObrazovku(hra.obrazovkaLevel); hra.PrepniHudbu(hra.hudba_zardax); break; case "SkOrE": hra.PrepniObrazovku(hra.obrazovkaSkore); break; case "AuToRi": hra.PrepniObrazovku(hra.obrazovkaAutori); break; case "KoNeC": hra.Exit(); break; } } base.Update(gameTime); }
KomponentaLevel.cs
/* Update skce pro vytvoření nové kostky */ if (hraciPlocha.Kolize(kostka, kostka.pozice)) hra.PrepniObrazovku(hra.obrazovkaSkore);
Po týchto úpravách už bude možné uloženie skóre po skončení hry.
Určite si ale všimnete malé nedokonalosti a to že ak chceme z menu zobraziť
tabuľku skóre, tak sa nám zobrazí otázka, či chceme uložiť skóre. To je
samozrejme zle, pretože sme hru doteraz nehrali a súčasne by sa nám uložil
zakaždým hráč, ktorý nemá žiadne body. Oprava nezaberie veľa času ani
úsilia. Upravíme komponent skóre, aby keď hráč nebude mať body, tak rovno
nastavíme stav na výpis a nie na otázku. To všetko obstará jedna podmienka
v try
bloku v metóde OnEnabledChanged()
. Bude
vyzerať takto:
if (hra.hrac != null && hra.hrac.body > 0) stav = eStav.Otazka; else stav = eStav.Vypis;
Toto bola malá úprava, aby sme odchytili posledný nedostatok, ktorý rušil inak pekný zážitok z hry.
Kompletné kódy sú priložené ako vždy. Hru máme kompletný so všetkými funkcionalitami, ktoré sme chceli Nabudúce, v lekcii Hra tetris v MonoGame: Webový server , na vás čaká on-line skóre tabuľka.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkamiStiahnuté 539x (13.23 MB)