Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 2 - Hra JellyBox v MonoGame - Želé a Score

V minulém díle, Hra JellyBox v MonoGame - Vykreslení hrací plochy a hráče, jsme si vytvořili projekt a přidali do něj vykreslení pozadí, země a hráče.

V dnešním díle si do hry přidáme padající kostky želé, které budete muset sbírat, score + třídu FadeEffect, která nám doplní grafické vykreslení score.

Textury

V dnešním díle budeme potřebovat 2 textury. 2 různé textury pro naše padajicí želé. Textury opět nahrajeme do složky Content.

Textura želé - Hra JellyBox v MonoGame
Textura želé - Hra JellyBox v MonoGame

Také budeme v dnešním díle potřebovat SpriteFont, takže pokud si nestáhnete mnou vytvořený projekt a bude dělat svůj vlastní, tak si nezapomeňte vygenerovat pěkný SpriteFont, který budeme používat ke grafickému znázornění score.

Textury by jsme tímto měli všechny a můžeme přistoupit ke kódu samotnému.

Box (Želé)

Nyní si vytvoříme objekty (želé), které bude mít hráč za úkol sbírat, aby získal skóre. Vytvoříme si novou třídu s názvem Box. Jelikož se jedná o "pevný" objekt, tak třída bude dědit ze třídy GameObject.

class Box : GameObject

Vytvoříme si zde pouze bool Delete, který bude jako veřejná vlastnost. Poté vytvoříme konstruktor třídy, na základě toho, že dědíme ze třídy GameObject, ale zároveň nastavíme bool Delete na false. Třída bude obsahovat 3 metody. První metodou je Update, ve které realizujeme padaní objektu směrem k zemi. Druhou metodou je Draw, která vykreslí naše želé. Třetí metodou je Collision, která bude zjišťovat, zda se želé nesrazilo se zemí.

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;
}

Jak můžete vidět, tak metody Update, Draw a Collision jsou nastaveny jako virtual a to proto, že budeme v pozdější fázi přidávat nové typy boxů (želé), které budou mít jinou logiku a proto je potřeba mít tyto metody virtual, abychom je v jiných třídách mohli přepsat.

Pokud by někdo chtěl, tak zde lze také přidat vlastnot Speed a v metodě Update, kde zvyšujeme Y o 3 a pouze přepsat hodnotu na Speed. Poté při vytváření nových boxů (želé) můžete používat random číslo na rychlost a docílíte pěkného efektu, ale já jsem ho zde nedělal.

Příprava score

Jelikož už máme hotové želé, které máme za úkol sbírat, tak by bylo dobré připravit si score, abychom zaznamenali naše úspěchy.

Grafický průběh

Naše score trochu okořeníme a nebudeme ho mít jakožto pouhé inkrementování čísla. Přidáme si grafické zobrazení score. Vytvoříme si novou třídu FadeEffect, která nám toto bude ovládat. Třída bude obsahovat proměnnou string text, kterou budeme vykreslovat. Vector2 position, který bude určovat místo vykreslení. SpriteFont font, který určuje styl, velikost a všechny ostatní parametry textu. Color color, která určí barvu textu, ale zároveň přez ni budeme ovládat průhlednost textu. Poté proměnné float time a count, které slouží k ovládání logiky. Jako poslední bool Faded s privátním setterem, která indukuje, zda už text není vidět.

Proměnnou time nastavíme v konstruktoru na 0, count na 1 a Faded nastavíme na false. Třída bude obsahovat 2 metody. První metodou je Update, kde se jako vždy odehrává logika. Druhou metodou je Draw, kde na základě předchozích parametrů vykreslíme text za použití metody 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);
}

Metoda Update pracuje tak, že do proměnné time se ukládá aktuální uběhlý čas. Jakmile uběhne 0.5s a zároveň je count menší než 9, tak se proměnná color zmenší o count / 10. To nám dá desetinné číslo transparentnosti. Potom inkrementujeme count a time nastavíme opět na 0. Jakmile se count = 9, tak se nastaví Faded na true. Je to z toho důvodu, protože text už je prakticky průhledný a není vidět. Lze si to ověřit podle vzorce co používáme výše.

(color * (0.9f - (8 / 10))) -> color * 0.1f;

Score

Jelikož řešíme již score jako takové, přesuneme se do třídy Game1. Zde si vytvoříme novou instanci třídy SpriteFont a List<FadeEffect>. Pojmenujeme si je font a fades. Také si přidáme int score a vlastnost int ScoreMultiply. Score nám jednoduše představuje hodnotu score, kterou máme a vlastnost ScoreMultiply budeme využívat při přidávání score, takže pokud bude multiply = 5 a score co máte dostat 10, tak dostanete 50 score. Velice to zpříjemní hru a přidá spousty další editací.

private SpriteFont font;
private List<FadeEffect> fades;

private int score;
public int ScoreMultiply { get; set; }

V metodě Initialize si inicializujeme náš List fades a také nastavíme proměnné score a ScoreMultiply.

fades = new List<FadeEffect>();
score = 0;
ScoreMultiply = 1;

Score jsme logicky nastavili na 0 a ScoreMultiply na 1.

V metodě LoadContent ještě incializujeme font a nehrajeme ho ze složky Content.

font = Content.Load<SpriteFont>("Font");

Teď ale k hlavnímu kouzlu. Stejně jako jsme si připravili pomocné metody zde ve třídě Game1 si teď vytvoříme metodu AddScore, která nám to bude řídit. Jako vstupní parametry nastavíme int value a Vector2 position. Value reprezentuje hodnotu, kterou má hráč obdržet a position reprezentuje místo, kde se má grafické znázornění vykreslit.

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;
}

Uvnitř metody si vytvoříme proměnnou addScore, která bude obsahovat konečné číslo, které přičteme či odečteme. Pokud je hodnota vstupního value vyšší než 0, tak uplatníme ScoreMultiply, ale jakmile je value < 0, čili odečítáme, tak již ScoreMultiply neuplatňujeme. Dále přidáme nový fade effect, kde addScore slouží jako vstupní hodnota, kterou vykreslíme, ale musíme ji převést na string, protože vykreslujeme text. Nakonec k našemu score přičteme hodnotu addScore.

Úprava třídy GameObject

Ještě zbývá maličkost ve třídě GameObject. Zde je třeba vytvořit si novou metodu, která nám bude vracet střed objektu pro snadné vykreslení score na středu. Ušetří nám to počítání středu objektu a lze to použit a v monoha další případech.

Vytvoříme si novou metodu s názvem GetCenterPosition a v ní jednoduše vypočítáme střed objektu jako Vector2.

public Vector2 GetCenterPosition()
{
    return new Vector2(position.X + texture.Width / 2,
                position.Y + texture.Height / 2);
}

Toto by bylo pro dnešek vše. Nyní máme připravené score, jeho vykreslování a padající boxy (želé). Boužel už nezbývá místa. Snad se opět tento díl bude líbit a budu se těšit u dalšího, kde nám opět vznikne krásný kus projektu.

Příště, Hra JellyBox v MonoGame - Střely a Logika, tedy dokončíme želé, přidáme střely, kolize objektů a přidávání score.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 161x (1.83 MB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Hra JellyBox v MonoGame - Vykreslení hrací plochy a hráče
Všechny články v sekci
Hra JellyBox v MonoGame
Přeskočit článek
(nedoporučujeme)
Hra JellyBox v MonoGame - Střely a Logika
Článek pro vás napsal Jakub Lásko[Saarix]
Avatar
Uživatelské hodnocení:
3 hlasů
Věnuji se programování v C#, MonoGame a Unity.
Aktivity