2. diel - Hra JellyBox v MonoGame - Želé a Score
V minulom dieli sme si vytvorili projekt a pridali do neho vykreslenie pozadia, krajina a hráča. V dnešnom diele si do hry pridáme padajúce kocky želé, ktoré budete musieť zbierať, score + triedu FadeEffect, ktorá nám doplní grafické vykreslenie score.
Textúry
V dnešnom diele budeme potrebovať 2 textúry. 2 rôzne textúry pre naše padajúcich želé. Textúry opäť nahráme do zložky Content.
Tiež budeme v dnešnom diele potrebovať SpriteFont, takže ak si nestiahnete mnou vytvorený projekt a bude robiť svoj vlastný, tak si nezabudnite vygenerovať pekný SpriteFont, ktorý budeme používať ku grafickému znázornenie score.
Textúry by sme týmto mali všetky a môžeme pristúpiť ku kódu samotnému.
Box (Želé)
Teraz si vytvoríme objekty (želé), ktoré bude mať hráč za úlohu zbierať, aby získal skóre. Vytvoríme si novú triedu s názvom Box. Keďže sa jedná o "pevný" objekt, tak trieda bude dediť z triedy GameObject.
class Box : GameObject
Vytvoríme si tu iba bool Delete, ktorý bude ako verejná vlastnosť. Potom vytvoríme konštruktor triedy, na základe toho, že dedíme z triedy GameObject, ale zároveň nastavíme bool Delete na false. Trieda bude obsahovať 3 metódy. Prvá metóda je Update, v ktorej realizujeme padanie objektu smerom k zemi. Druhou metódou je Draw, ktorá vykreslí naše želé. Tretia metódou je Collision, ktorá bude zisťovať, či sa želé nezrazilo so zemou.
public bool Delete { get; set; } public Box(Texture2D texture, Vector2 position) : base(texture, position) { Delete = false; } public virtual void Update(Game1 game, GameTime gameTime) { position.Y += 3; } public virtual void Draw(SpriteBatch spriteBatch) { spriteBatch.Draw(texture, position, Color.White); } public virtual void Collision(Rectangle ground, Game1 game, Player player) { if (GetRectangle().Intersects(ground)) Delete = true; }
Ako môžete vidieť, tak metódy Update, Draw a Collision sú nastavené ako virtual a to preto, že budeme v neskoršej fáze pridávať nové typy boxov (želé), ktoré budú mať inú logiku a preto je potrebné mať tieto metódy virtual, aby sme ich v iných triedach mohli prepísať.
Ak by niekto chcel, tak tu možno tiež pridať vlastnoti Speed a v metóde Update, kde zvyšujeme Y o 3 a iba prepísať hodnotu na Speed. Potom pri vytváraní nových boxov (želé) môžete používať random číslo na rýchlosť a docielite pekného efektu, ale ja som ho tu nerobil.
Príprava score
Keďže už máme hotové želé, ktoré máme za úlohu zbierať, tak by bolo dobré pripraviť si score, aby sme zaznamenali naše úspechy.
Grafický priebeh
Naše score trochu okoreníme a nebudeme ho mať ako obyčajné inkrementování čísla. Pridáme si grafické zobrazenie score. Vytvoríme si novú triedu FadeEffect, ktorá nám toto bude ovládať. Trieda bude obsahovať premennú string text, ktorú budeme vykresľovať. Vector2 position, ktorý bude určovať miesto vykreslenie. SpriteFont font, ktorý určuje štýl, veľkosť a všetky ostatné parametre textu. Color color, ktorá určí farbu textu, ale zároveň cez ňu budeme ovládať priehľadnosť textu. Potom premenné float time a count, ktoré slúžia na ovládanie logiky. Ako posledný bool Faded s privátnym Setter, ktorá indukuje, či už text nie je vidieť.
Premennú time nastavíme v konstruktoru na 0, count na 1 a Faded nastavíme na false. Trieda bude obsahovať 2 metódy. Prvá metóda je Update, kde sa ako vždy odohráva logika. Druhou metódou je Draw, kde na základe predchádzajúcich parametrov vykreslíme text za použitia metódy Drawstring.
private string text; private Vector2 position; private SpriteFont font; private Color color; private float time, count; public bool Faded { get; private set; } public FadeEffect(string text, Vector2 position, SpriteFont font) { this.text = text; this.position = position; this.font = font; color = Color.Purple; time = 0; count = 1; Faded = false; } public void Update(GameTime gameTime) { time += (float)gameTime.ElapsedGameTime.TotalSeconds; if (time > 0.5 && count < 9) { color = color * (0.9f - (count / 10)); count++; time = 0; } if (count == 9) Faded = true; } public void Draw(SpriteBatch spriteBatch) { spriteBatch.DrawString(font, text, position, color); }
Metóda Update pracuje tak, že do premennej time sa ukladá aktuálny končiaci k uvedenému dátumu čas. Akonáhle ubehne 0.5s zároveň je count menšie ako 9, tak sa premenná color zmenší o count / 10. To nám dá desatinné číslo transparentnosti. Potom inkrementuje count a time nastavíme opäť na 0. Akonáhle sa count = 9, tak sa nastaví Faded na true. Je to z toho dôvodu, pretože text už je prakticky priehľadný a nie je vidieť. Možno si to overiť podľa vzorca čo používame vyššie.
(color * (0.9f - (8 / 10))) -> color * 0.1f;
Score
Keďže riešime už score ako také, presunieme sa do triedy Game1. Tu si vytvoríme novú inštanciu triedy SpriteFont a List <FadeEffect>. Pomenujeme si ich font a fades. Tiež si pridáme int score a vlastnosť int ScoreMultiply. Score nám jednoducho predstavuje hodnotu score, ktorú máme a vlastnosť ScoreMultiply budeme využívať pri pridávaní score, takže ak bude multiply = 5 a score čo máte dostať 10, tak dostanete 50 score. Veľmi to spríjemní hru a pridá spústy ďalšie editáciou.
private SpriteFont font; private List<FadeEffect> fades; private int score; public int ScoreMultiply { get; set; }
V metóde Initialize si inicializujeme náš List fades a tiež nastavíme premenné score a ScoreMultiply.
fades = new List<FadeEffect>(); score = 0; ScoreMultiply = 1;
Score sme logicky nastavili na 0 a ScoreMultiply na 1.
V metóde LoadContent ešte incializujeme font a nehráme ho z priečinka Content.
font = Content.Load<SpriteFont>("Font");
Teraz ale k hlavnému kúzlu. Rovnako ako sme si pripravili pomocné metódy tu v triede Game1 si teraz vytvoríme metódu AddScore, ktorá nám to bude riadiť. Ako vstupné parametre nastavíme int value a Vector2 position. Value reprezentuje hodnotu, ktorú má hráč obdržať a position reprezentuje miesto, kde sa má grafické znázornenie vykresliť.
public void AddScore(int value, Vector2 position) { int addScore; if (value > 0) addScore = value * ScoreMultiply; else addScore = value; // grafické zobrazení přidání/odebrání score fades.Add(new FadeEffect(Convert.ToString(addScore), position, font)); this.score += addScore; }
Vnútri metódy si vytvoríme premennú addScore, ktorá bude obsahovať konečné číslo, ktoré pripočítame či odpočítame. Ak je hodnota vstupného value vyššia ako 0, tak uplatníme ScoreMultiply, ale akonáhle je value <0, čiže odčítame, tak už ScoreMultiply neuplatňujeme. Ďalej pridáme nový fade effect, kde addScore slúži ako vstupná hodnota, ktorú vykreslíme, ale musíme ju previesť na string, pretože vykresľujú text. Nakoniec k nášmu score pripočítame hodnotu addScore.
Úprava triedy GameObject
Ešte zostáva maličkosť v triede GameObject. Tu je potrebné vytvoriť si novú metódu, ktorá nám bude vracať stred objektu pre ľahké vykreslenie score na stredu. Ušetrí nám to počítanie stredu objektu a možno to použitý a v monoho ďalšie prípadoch.
Vytvoríme si novú metódu s názvom GetCenterPosition a v nej jednoducho vypočítame stred objektu ako Vector2.
public Vector2 GetCenterPosition() { return new Vector2(position.X + texture.Width / 2, position.Y + texture.Height / 2); }
Toto by bolo pre dnešok všetko. Teraz máme pripravené score, jeho vykresľovanie a padajúce boxy (želé). Boužiaľ už nezostáva miesta, takže nabudúce dokončíme želé, pridáme strely, kolízie objektov a pridávanie score. Snáď sa opäť tento diel bude páčiť a budem sa tešiť u ďalšieho, kde nám opäť vznikne krásny kus projektu.
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é 161x (1.83 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#