Vianoce v ITnetwork sú tu! Dobí si teraz kredity a získaj až 80 % extra kreditov na e-learningové kurzy ZADARMO. Zisti viac.
Hľadáme nové posily do ITnetwork tímu. Pozri sa na voľné pozície a pridaj sa k najagilnejšej firme na trhu - Viac informácií.

6. diel - Hra JellyBox v MonoGame - Sugar a Menu

V minulom tutoriále o MonoGame sme si do hry dorobili veľmi pekné Toxic želé a začali sme pracovať na Sugar želé, ktoré bude naším posledným v hre, ale tiež asi s najlepším správaním. Dnes si sugar dokončíme a začneme pracovať na hernom menu, aby hra dostala určitý poriadok.

Textúry

Dnes budeme potrebovať 2 textúry, a to textúry pre 2 tlačidlá, ktoré budú zahrnuté do menu (New game, Exit). Textúry si nahráme do zložky Content.

new Game - Hra JellyBox v MonoGame
Exit - Hra JellyBox v MonoGame

Snáď ma za tieto tlačidlá nikto nepopravia, pretože som ich musel robiť sám :-) Ale pre názornosť menu nám postačí.

Sugar Box Finále

Teraz si dokončíme náš sugar box, čo bude veľmi jednoduché, pretože to bude len o tom vytvoriť si pre neho "spawn", prideliť mu textúru a v určitý čas ho generovať. Prní úpravu budeme robiť v triede Logic, tak sa do nej prepneme a môžeme začať.

Vytvoríme si novú Texture2D, ktorú nazveme sugarBox a tu budeme uchovávať textúru pre neho.

private Texture2D sugarBox;

Teraz si vytvoríme novú metódu SpawnSugarBox, ktorá nám opäť bude generovanie daného boxu riadiť.

public void SpawnSugarBox()
{
    Box box = new SugarBox(sugarBox, Vector2.Zero);
    int x = random.Next(0,
        (int)game.GetScreenSize().X - (int)box.GetSize().X - (((SugarBox)box).Scale * 2));
    ((SugarBox)box).SetPosition((int)x, -100);

    boxes.Add(box);
}

Nastavíme všetky potrebné parametre ako textúru, pozíciu, Scale a potom pridáme box do nášho listu.

Pozn. pre tých, ktorí zabudli, tak Scale tu pri generovaní pozície X znamená maximálnu výchilku pri kmitaní. Keďže kmitajú ako do + tak do -, tak musíme použiť Scale * 2. Týmto sme zamedzili, aby náš objekt vyrážal z hracej plochy.

Teraz si tu pridáme novú podmienku, ktorá nám bude zabezpečovať, aby sa pri generovaní nevygeneroval 2 boxy cez seba, ale tiež akonáhle narazí napr. Toxic box do normálneho boxu, tak ho zničia. Varujem, že je to trochu brutálnejší podmienka, ale keď sa na ňu pozriete trochu viac, tak ju určite hneď pochopíte.

for (int e = 0; e < boxes.Count; e++)
{
    for (int i = 0; i < boxes.Count; i++)
    {
        if (e != i)
        {
            if (boxes[e].GetRectangle().Intersects(boxes[i].GetRectangle()))
            {
                if (boxes[e].GetType() != typeof(SugarBox) &&
                    boxes[i].GetType() != typeof(SugarBox))
                {
                    if (boxes[e].GetType() == typeof(ToxicBox) &&
                        boxes[i].GetType() != typeof(ToxicBox))
                        boxes[i].Delete = true;
                    else if (boxes[i].GetType() != typeof(ToxicBox))
                        boxes[i].Delete = true;
                }
            }
        }
    }
}

Akonáhle v podmienke zistíme, že do seba 2 boxy "naráža", tak potom už je to len o určení jednotlivých typov boxov a ich následnom správania. Takže akonáhle sa s niečím stretne toxic box, tak ten druhý vymaže, ale u sugar boxu je kolízia ignorovaná a nice sa nedeje.

Týmto máme triedu Logic hotovú a je potrebné doupraviť triedu Game1. Ako prvý si v triede Game1 pridáme novú premennú typu float sugarBoxSpawnTime, ktorá nám bude zaznamenávať čas pre spawn (vygenerovanie) sugar boxu.

priva float sugarBoxSpawnTime;

V metóde Initialize ju nastavíme na 0.

sugarBoxSpawnTime = 0;

Teraz sa musíme mrknúť do metódy LoadContent a upraviť vytváranie inštancie triedy Logic a pridať tam textúru pre náš sugar box.

logic = new Logic(this, boxes, bullets,
Content.Load<Texture2D>("GreenJelly"),
Content.Load<Texture2D>("BrownJelly"),
Content.Load<Texture2D>("Bullet"),
Content.Load<Texture2D>("ToxicJelly"),
Content.Load<Texture2D>("Sugar"));

A finálne sa pozrieme do metódy Update a pridáme si podmienku pre spawn sugar boxu.

sugarBoxSpawnTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (sugarBoxSpawnTime > 22)
{
    sugarBoxSpawnTime = 0;
    logic.SpawnSugarBox();
}

Do premennej sugarBoxSpawnTime nastavujeme končiaci k uvedenému dátumu čas hry. Ak dosiahne 22s, tak ho vynulujeme a vygenerujeme nový sugar box.

Skoro by som zabudol, že ako to bude kompletný, tak musíme upraviť hráčovu kolízii v triede Player a zohľadniť tam kolízii so sugar boxom a nadefinovať čo sa má stať. Takže v triede Player, v metóde Collision pridáme následujúce podmienku, pod podmienku kedy sa obj = ToxicBox.

if (obj is SugarBox)
{
    obj.Delete = true;
    Lives++;
    game.score.ScoreMultiply++;
}

Teraz som nadefinovali, že pri kolízii sa sugar boxom hráč dostane jeden život a zvýši sa mu ScoreMultiply.

Menu

V projekte si vytvorme novú zložku s názvom Menu. Než sa pustíme do menu ako takého, tak by bolo dobré si vytvoriť button, ktorý v ňom budeme používať. Vytvorme novú triedu menom Button (v zložke Menu). Trieda bude obsahovať následujúce premenné.

private Texture2D texture;
private Vector2 position;
private bool isActive;

Samozrejme textúru, pozíciu, ale tiež bool isActive, ktorý nám bude hovoriť, či je button aktívny.

Vytvoríme si konštruktor triedy Button a nastavíme v ňom isActive na false;

public Button(Texture2D texture, Vector2 position)
{
    this.texture = texture;
    this.position = position;
    isActive = false;
}

Teraz si vytvoríme 2 metódy (Activate, Deactivate), ktoré budeme používať k aktivovaniu, či deaktivovanie tlačidla.

public void Activate()
{
    isActive = true;
}

public void Deactivate()
{
    isActive = false;
}

Metódy sú naozaj primitívne, prakticky zatiaľ ide len o nastavení boolean hodnoty, ale ak by niekto robil sofistikovanejšie menu, tak sa mu tu môže kód zväčšiť.

A ako posledný opäť metóda Draw vďaka ktorej budeme Button vykresľovať.

public void Draw(SpriteBatch spriteBatch)
{
    if (isActive)
        spriteBatch.Draw(texture, position, Color.White);
    else
        spriteBatch.Draw(texture, position, Color.White * 0.5f);
}

V metóde Draw rozlišujeme, či je button aktívna a pokiaľ nie je, tak mu dáme 50% priehľadnosť.

Týmto máme button pripravený a môžeme sa pustiť do tvorby menu. Ale ako tak urobíme, tak sa presunieme do triedy Game1 a urobíme malú zmenu, aby bolo všetko pripravené.

Vytvoríme si tu nový verejný enum eStavHry, ktorý nám bude hovoriť v akom je hra stave.

public enum eStavHry
{
    Hra,
    Pauza,
    GameOver,
    Menu,
}

Ako vidíte, zvolil som tu stavy (Hra, Pauza, GameOver, Menu), toto sú všetky stavy, ktorých môže naša hra nadobudnúť.

Teraz si vytvoríme novú premennú typu eStavHry, takže to bude enum a nevolaj ju stavHry.

public eStavHry stavHry;

V metóde Initialize ju priradíme hodnotu a nastávajú ju na Menu. Je tu veľmi výhodné, že enum vám ukáže všetky jeho možné hodnoty a vy jednu z nich vyberiete, takže sa nikdy nestane, že by ste napr. V podmienke zle určili názov stavu.

stavHry = eStavHry.Menu;

Teraz je všetko pripravené a vytvoríme si novú triedu menom MenuScreen v zložke Menu.

Budeme tu potrebovať 3 textúry (pre pozadie, tlačidlo nová hra a tlačidlo koniec), ďalej si vytvoríme List buttonov a rovno si vytvoríme jeho inštanciu. Budeme tiež potřbovat odovzdať skrze konštruktor inštanciu triedy Game1 Bool hodnoty, ktoré budú strážiť, aby došlo k stlačeniu (hore, dole) iba raz (press). Potom int index, ktorý nám bude určovať index buttonu, ktorý je práve aktívny. Ako posledný bool NewGame, ktorý nám bude určovať, tu bolo spustená nová hra.

private Texture2D background, newGame, exit;
private List<Button> buttons = new List<Button>();
private Game1 game;
private bool upPressed, downPressed;
private int index;
public bool NewGame { get; set; }

Zvyšok necháme na nabudúce a to dokončíme Menu, ale aj GameOver :-) V tomto stave ide hra bez problémov spustiť, takže si nový typ boxu môžete ihneď vyskúšať. Teším sa opäť u ďalšieho tutoriálu o hre v MonoGame.


 

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é 293x (1.89 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
Hra JellyBox v MonoGame - Toxic a posledná želé
Všetky články v sekcii
Hra JellyBox v MonoGame
Článok pre vás napísal Jakub Lásko[Saarix]
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Věnuji se programování v C#, MonoGame a Unity.
Aktivity