13. diel - MonoGame: Herné menu
V minulej lekcii, MonoGame: Správa herných obrazoviek , sme si naprogramovali správu herných obrazoviek a pripravili komponent pre herné menu. Nič nám nebráni v tom, aby sme sa do neho dnes pustili
Menu budeme chcieť samozrejme pekné as nejakými efekty. Najprv si do
našej komponenty KomponentaMenu
pridáme pozadia. Tu si ho
stiahnite:
a pridajte do zložky Sprity/
v hre. Pridáme príslušný
atribút:
private Texture2D pozadi;
Načítanie do LoadContent()
:
pozadi = hra.Content.Load<Texture2D>(@"Sprity\pozadi_menu");
A vykreslenie do Draw()
:
hra.spriteBatch.Begin(); hra.spriteBatch.Draw(pozadi, new Vector2(0, 0), Color.White); hra.spriteBatch.End();
Menu si rozdelíme do dvoch komponentov, aby sme ho mali znovu použiteľné
a dalo sa použiť bez veľkých zmien aj v inej hre alebo obrazovke.
KomponentaMenu
sa bude starať o vykreslenie tých častí menu,
ktoré sú špecifické pre hru Robotris. Pridajme si ešte jednu univerzálnu
komponent, ktorá bude spravovať jednotlivé položky menu. Komponent bude
vykreslitelná a bude sa volať KomponentaPolozkyMenu
. Opäť pre
úplnosť uvediem jej prázdny zdrojový kód (nezabudnite, že namespace má
byť opäť len Robotris
, aj keď je v priečinku
Komponenty/
):
namespace Robotris { public class KomponentaPolozkyMenu : Microsoft.Xna.Framework.DrawableGameComponent { private Hra hra; public KomponentaPolozkyMenu(Hra hra) : base(hra) { this.hra = hra; } public override void Initialize() { base.Initialize(); } protected override void LoadContent() { base.LoadContent(); } public override void Update(GameTime gameTime) { base.Update(gameTime); } public override void Draw(GameTime gameTime) { base.Draw(gameTime); } } }
Zatiaľ ju ponecháme prázdnu a pridáme ďalšiu triedu, ktorej inštancia
bude reprezentovať jednu položku menu. Triedu pridáme medzi ďalšie triedy
priamo v projekte Robotris
.
Položka menu
Trieda sa bude volať PolozkaMenu
. Bude obsahovať údaje o
svojej pozícii (súradniciach na obrazovke), veľkosti a textu. Veľkosti
preto, že vybranú položku budeme škálovať a to vrátane animácie. Trieda
je veľmi jednoduchá, uveďme si rovno jej zdrojový kód:
public class PolozkaMenu { public string text; public Vector2 pozice; public float velikost; public PolozkaMenu(string text, Vector2 pozice) { this.text = text; this.pozice = pozice; velikost = 0.6f; } }
Kvôli použitie štruktúry Vector2
dodáme using na XNA
framework:
using Microsoft.Xna.Framework;
Presuňme sa do KomponentaPolozkyMenu
. Tento komponent bude
správca položiek menu, bude ich uchovávať, prepínať a vykresľovať.
Konkrétne udalosti (čo ktorá položka po stlačení vykoná) vložíme
neskôr do KomponentaMenu
, pretože to je závislé na konkrétnej
hre.
Pridáme list položiek ako atribút, ďalej aktuálne vybratú položku a pozíciu menu:
private List<PolozkaMenu> polozky; public PolozkaMenu vybranaPolozka; private Vector2 pozice;
Komponent sa pokúsime urobiť čo najviac prispôsobiteľný, preto pridáme ešte farbu vybrané a nevybrané položky a výšku položky (tam potom uložíme výšku písma):
private Color nevybranaBarva; private Color vybranaBarva; private int vyska;
Presunieme sa do konstruktoru, ktorému pridáme ďalšie parametre a kde inicializujeme atribúty:
public KomponentaPolozkyMenu(Hra hra, Vector2 pozice, Color nevybranaBarva, Color vybranaBarva, int vyska): base(hra) { this.pozice = pozice; this.hra = hra; this.nevybranaBarva = nevybranaBarva; this.vybranaBarva = vybranaBarva; this.vyska = vyska; polozky = new List<PolozkaMenu>(); vybranaPolozka = null; }
Správa položiek menu
Pridajme niekoľko metód pre prácu s kolekciou položiek menu. Začnite pridaním nové položky. Metóda bude brať v parametri text položky. Vnútri vytvorí novú položku, tej nastaví pozíciu pod už existujúce položky v menu, podľa ich výšky. Položku následne pridá do internej kolekcie a pokiaľ nie je žiadna vybraná, vyberie práve ju (vybraná teda bude vždy 1. položka v menu). Metóda by mohla vyzerať takto:
public void PridejPolozku(string text) { // nastavení pozice podle pořadí položky Vector2 p = new Vector2(pozice.X, pozice.Y + polozky.Count * vyska); PolozkaMenu polozka = new PolozkaMenu(text, p); polozky.Add(polozka); // výběr první položky if (vybranaPolozka == null) vybranaPolozka = polozka; }
Po pridaní položiek bude treba vyberať ďalšie a predchádzajúcu položku. V metóde pre vybranie ďalšie položky nebude mimo prechodu z poslednej späť na prvú nič zaujímavé. Pretože si neudržujeme pozíciu aktuálnej položky, ale len jej inštanciu, musíme jej index vždy znovu zistiť, ale to nás v našom prípade nijako netrápi.
public void VyberDalsi() { int index = polozky.IndexOf(vybranaPolozka); if (index < polozky.Count - 1) vybranaPolozka = polozky[index + 1]; else vybranaPolozka = polozky[0]; }
Metóda pre výber predchádzajúcej položky bude podobná:
public void VyberPredchozi() { int index = polozky.IndexOf(vybranaPolozka); if (index > 0) vybranaPolozka = polozky[index - 1]; else vybranaPolozka = polozky[polozky.Count - 1]; }
Obsluha položiek
Obsluhu položiek nastavíme na klávesy nadol a nahor. Budeme tak prepínať
ďalšie a predchádzajúcu položku. Presuňme sa do Update()
a
dodajme reakcii na tieto klávesy:
// reakce na klávesy if (hra.NovaKlavesa(Keys.Up)) VyberPredchozi(); if (hra.NovaKlavesa(Keys.Down)) VyberDalsi();
Vykreslenie položiek
Pretože u položiek budeme potrebovať špecifikovať aj veľkosť,
nevystačíme si s našou metódou TextSeStinem()
. Preto si triedu
LepsiSpriteBatch
obohatíme o ďalšiu metódu, ktorá vykreslí
škálovanie text s tieňom pomocou ďalšieho preťaženie metódy
DrawString()
:
public void TextSeStinemSkalovany(SpriteFont spriteFont, string text, Vector2 position, Color color, float size) { DrawString(spriteFont, text, new Vector2(position.X + 2, position.Y + 2), Color.Black * 0.8f, 0.0f, new Vector2(0, 0), size, SpriteEffects.None, 0); DrawString(spriteFont, text, position, color, 0.0f, new Vector2(0, 0), size, SpriteEffects.None, 0); }
Teraz už je pre nás hračka vykresliť v Draw()
položky
menu:
hra.spriteBatch.Begin(); foreach (PolozkaMenu polozka in polozky) { Color barva = nevybranaBarva; if (polozka == vybranaPolozka) barva = vybranaBarva; hra.spriteBatch.TextSeStinemSkalovany(hra.fontBlox, polozka.text, polozka.pozice, barva, polozka.velikost); } hra.spriteBatch.End();
(Tu je závislosť na font fontBlox
z hry. Ideálne by sme
mali umožniť font odovzdať, ale kvôli tomu, že font existuje až po volaní
LoadContent()
by sa nám práca skomplikovala a preto toto
zanedbáme).
Vloženie komponentov do seba
Komponent KomponentaPolozkyMenu
teraz vložíme do komponenty
KomponentaMenu
. Takto sme do seba komponenty ešte nevkladali,
poďme si to vyskúšať. Presuňme sa do KomponentaMenu.cs
, kde
pridajme atribút s inštanciou komponentmi
KomponentaPolozkyMenu
:
private KomponentaPolozkyMenu polozkyMenu;
Samotnú inštanciu si však vytvoríme v Hra.cs
(pretože tu
potrebujeme komponent pridať do obrazovky). Išlo by to samozrejme navrhnúť
aj inak, ale preferujte jednoduchosť. Do KomponentaMenu
inštanciu
dostaneme konstruktoru, ktorý modifikujeme:
public KomponentaMenu(Hra hra, KomponentaPolozkyMenu polozkyMenu) : base(hra) { this.hra = hra; this.polozkyMenu = polozkyMenu; }
Presuňme sa do Hra.cs
a v Initialize()
a pridajme
vytvorenie inštancie komponenty KomponentaPolozkyMenu
:
KomponentaPolozkyMenu polozkyMenu = new KomponentaPolozkyMenu(this, new Vector2(700, 250), Color.Red, Color.Yellow, 80);
A za ňou rovno pridanie njěkolika položiek do menu:
polozkyMenu.PridejPolozku("StArT"); polozkyMenu.PridejPolozku("SkOrE"); polozkyMenu.PridejPolozku("AuToRi"); polozkyMenu.PridejPolozku("KoNeC");
Striedam v názve položiek veľké a malé písmená, pretože to s fontom Blox vyzerá dobre
Do volanie konstruktoru KomponentaMenu
doplníme inštanciu
polozkyMenu
.
KomponentaMenu menu = new KomponentaMenu(this, polozkyMenu);
A rovnako tak ju dodáme aj do vytvárania obrazovky
obrazovkaMenu
:
obrazovkaMenu = new HerniObrazovka(this, mraky, menu, polozkyMenu);
Otvorte si font_blox.spritefont
v priečinku Fonty/
a zmeňte Style z Regular na Bold. Projekt spustíme, mali by ste dospieť
takéhoto výsledku:
Vidíme, že aj prepínanie položiek funguje dobre. Nabudúce, v lekcii MonoGame: Skrolující text (autori hry) , sprevádzkujeme klikanie na položky a vytvoríme si obrazovku autori sa skrolujícím textom.
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é 332x (13.21 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#