2. díl - Hra JellyBox v MonoGame - Želé a Score

C# .NET XNA game studio Hra JellyBox Hra JellyBox v MonoGame - Želé a Score

V minulém díle 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é
Textura želé

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, takže příště dokončíme želé, přidáme střely, kolize objektů a přidávání score. Snad se opět tento díl bude líbit a budu se tešit u dalšího, kde nám opět vznikne krásný kus projektu.


 

Stáhnout

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

 

  Aktivity (1)

Článek pro vás napsal Jakub Lásko[Saarix]
Avatar
Věnuji se programování v C#, MonoGame a Unity.

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 



 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!