Lekce 16 - Hra tetris v MonoGame: Dokončení
V minulé lekci, Hra tetris v MonoGame: Skóre, jsme si vytvořili komponentu skóre a ukázali si jak uvést komponentu do výchozího stavu při zobrazení.
V dnešním MonoGame tutoriálu naprogramujeme ukládání a načítání výsledků a všechno hezky propojíme. Tím uzavřeme náš on-line kurz a budete mít hru hotovou se vším všudy. On-line skóre si necháme do bonusové lekce, jelikož budeme potřebovat použít další technologie a bylo by fajn nejprve dokonči hru v C# za použití ukládání skóre do XML.
Komponenta skóre využívá třídu SkoreKlient
, ve které
máme připravené metody pro ukládání a načítání.
Ukládání
Budeme ukládat do souboru XML s názvem skore.xml
. Ale vůbec
nic vám nebrání, abyste ukládali skóre dle libosti kamkoli jinam, i na
server, jak si ukážeme dále.
Struktura XML souboru bude vypadat následovně
<?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átu tedy jednotlivé instance třídy Hrac
uložíme. Zdrojový kód metody Uloz()
bude nyní vypadat
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); } }
Pokud soubor neexistuje, tak jej vytvoříme a uložíme do něj první
výsledek. Pokud již existuje, vyhledáme element s hráči a před posledního
(prvního zapsaného) přidáme nově přidávaného. Tím budeme mít výsledky
řazené podle posledního přidaného. Pokud budeme chtít řadit jinak,
vyřešíme to v komponentě KomponentaSkoreTabulka
. Proměnná
soubor
je řetězec obsahující název souboru s příponou
.xml
, jak jsme si ji minule nachystali.
Načítání
Načítání hráčů může vypadat např. takto:
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; }
Postupně načítáme ze souboru a ukládáme do seznamu, který poté
vracíme. Do toho jak pracuje XmlReader
, XmlWriter
a
XDocument
zabíhat nebudu, protože jsou detailně popsané v Práce se soubory v C# .NET.
Přidání herní obrazovky
Zbývá upravit třídu Hra
a přidat jí herní obrazovku
obrazovkaSkore
. V komponentě menu navíc upravíme co se má stát
pokud uživatel bude na položce Skore a zmáčkne Enter. Kód bude
vypadat následovně:
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 již bude možné uložení skóre po skončení hry.
Určitě si ale povšimnete malé nedokonalosti a to že pokud chceme z menu
zobrazit tabulku skóre, tak se nám zobrazí otázka, zda chceme uložit
skóre. To je samozřejmě špatně, protože jsme hru dosud nehráli a
současně by se nám uložil pokaždé hráč, který nemá žádné body.
Oprava nezabere moc času ani úsilí. Upravíme komponentu skóre, aby když
hráč nebude mít body, tak rovnou nastavíme stav na výpis a nikoli na
otázku. To vše obstará jedna podmínka v try
bloku v metodě
OnEnabledChanged()
. Bude vypadat takto:
if (hra.hrac != null && hra.hrac.body > 0) stav = eStav.Otazka; else stav = eStav.Vypis;
Toto byla malá úprava, abychom odchytili poslední nedostatek, který rušil jinak pěkný zážitek ze hry.
Kompletní kódy jsou přiloženy jako vždy. Hru máme kompletní se všemi
funkcionalitami, které jsme chtěli .
Příště, v lekci Hra tetris v MonoGame: Webový server, na vás čeká on-line skóre tabulka.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkamiStaženo 584x (13.23 MB)