5. díl - Hra JellyBox v MonoGame - Toxic a poslední želé

C# .NET XNA game studio Hra JellyBox Hra JellyBox v MonoGame - Toxic a poslední želé

V minulém tutoriálu o MonoGame jsme si do hry doimplementovali třídu Logic, přidali generování želé a vytvořili nový typ Toxic. V dnešním díle doděláme Toxic a jeho generování. Také si vytvoříme nový a poslední typ želé jménem Sugar, které nám bude zvyšovat ScoreMultiply.

Textury

Jak bylo napovězeno v úvodním textu, tak dnes budeme potřebovat pouze texturu pro Sugar. Texturu si nahrajeme do složky Content.

Sugar

Dokončení Toxic Boxu

Nejprve se podíváme do třídy Logic a zde přidáme a upravíme vše co je potřeba. Přidáme si novou Texture2D pro toxic box a také jsi přidáme do konstruktoru třídy.

private Texture2D toxicBox;

Tím bycgom měli texturu připravenou a nyní si vytvoříme novou metodu jménem SpawnToxicBox, která nám bude řídit generování toxic boxů.

public void SpawnToxicBox()
{
        Box box = new ToxicBox(toxicBox, Vector2.Zero, 100);
        int x = random.Next(0, (int)game.GetScreenSize().X - (int)(box.GetSize().X));
        ((ToxicBox)box).SetPosition(x, -100);

        boxes.Add(box);
}

V metodě nejprve vytvoříme novou instanci boxu, přiřadíme mu texturu, vektor pozice nastavíme prozatím na nulu a nastavíme rozmezí pro "skoky". Dále vygenerujeme náhodnou X-ovou pozici pro náš box a díky metodě SetPosition, kterou toxic box obsahuje, mu nastavíme polohu. A nakonec box přidáme do listu.

Poslední úpravu ve třídě Logic uděláme v metodě Update. Zde změníme cyklus pro updatování a kontrolu kolizí boxů. Cyklus nyní bude vypadat takto.

foreach (Box b in boxes)
{
        b.Update(game, gameTime);
        b.Collision(game.GetGroundRect(), game, player);
}

Jakmile je zde box typu ToxicBox, tak se v instanci boxu b objeví typ ToxicBox a podmínka dále provede metody Update a Collision, které náleží třídě ToxicBox. Jinak instance boxu b zůstává typu Box a provede metody Update a Collision, které náleží této třídě.

Teď se přesuneme do třídy Player a upravíme zde metodu Collision, kterou jsme vytvořili.

public void Collision(Box obj)
{
        if (GetRectangle().Intersects(obj.GetRectangle()))
        {
                if (obj is ToxicBox)
                {
                        obj.Delete = true;
                        Lives--;
                        game.ScoreMultiply = 1;
                }
                else
                {
                        obj.Delete = true;
                        EatedJellies++;
                        game.AddScore(5, obj.GetCenterPosition());
                }
        }
}

Opět jsme si zde přidali podmínku, která zjistí zda je objekt typu ToxicBox a pokud ano, tak provede vymazání objektu, ubere hráči život a ScoreMultiply nastavi na 1. Jinak se hráč srazil s normální boxem (želé) a dostane +score, atd...

A finální upravy uděláme ve třídě Game1. Zde si vytvoříme novou proměnnou typu float, která bude zaznamenávat časový interval pro vygenerování toxic boxu.

private float toxicBoxSpawnTime;

V metodě Initialize tuto proměnnou nastavíme na 0.

toxicBoxSpawnTime = 0;

V metodě LoadContent upravíme inicializaci třídy Logic a načteme zde naši texturu pro toxic box.

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

Nyní v metodě Update přidáme generování toxic boxu.

toxicBoxSpawnTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (toxicBoxSpawnTime > 10)
{
        toxicBoxSpawnTime = 0;
        logic.SpawnToxicBox(level.Number);
}

Do proměnné toxicBoxSpawnTime ukládáme aktuální čas od zapnutí hry. Jakmile je čas 10s, tak ho vynulujeme a skrze metodu SpawnToxicBox vygenerujeme nový toxic box.

Tímto bychom měli mít hotový ToxicBox, který nám teď bude vesele poletovat ve hře. Teď se můžeme vrhnout na poslední typ a tím je SugarBox.

Sugar Jelly

Přidáme si novou třídu jménem SugarBox. Náš SugarBox bude mít velice zvláštní pohyb, kterým bude harmonické kmitání, tak jeho pohyb si můžeme přectavit jako sinusovku.

Harmonické kmitání

Budeme zde potřebovat nějaký ten vzoreček, ale nebojte, na následujicích řádcích se ho pokusím vysvětlit. Bude to vzorec pro výpočet okamžité výchylky harmonického kmitání, čili díky tomuto vzorci zjistíme, kde se daný předmět při kmitání nachází v danou dobu.

Y = Ym * sin(ω*t + φ0)
  • Ym je amplituda výchilky (maximální "bod" kam až se předmět při kmitání dostane).
  • ω je úhlová frekvence (rychlost kmitání) a počítá se úhel / čas, tedy 2Pí / T. T je doba pro 1 otočení.
  • t je čas, čili zde budeme dosazovat čas hry a tím zajistíme průběh kmitání. Zde se např. ptáme t = 5s, takže kde se nachází předmět v čase 5s.
  • φ0 je počáteční úhel. Zde můžeme zadat, že kmítání předmětu bude např. začínat v úhlu 120°, ale to zde nepoužijeme, takže tato složka bude v našem případě 0.

Snad jste z mého výkladu alespoň trochu pochopili jak bude harmonické kmitání fungovat a můžeme se pustit do tvorby třídy.

Třída bude jako obvykle dědit ze třídy Box.

class SugarBox : Box

Vytvoříme si veřejnou vlastnost Scale, která bude reprezentovat přáve Ym, což je maximální výchylka. Také proměnnou typu float time, která bude obsahovat nynější čas hry, což použijeme jako t v našem vzorci.

public int Scale { get; private set; }
private float time;

V konstruktoru nastavíme time na 0 a Scale jsem nastavil na 50, což je příznivá výchylka.

public SugarBox(Texture2D texture, Vector2 position)
        : base(texture, position)
{
        time = 0;
        Scale = 50;
}

Nyní si přepíšeme metodu Update, kterou jsem oddědili od třídy Box. Zde budeme aplikovat vzorec, který jsme si vysvětlovali výše.

public override void Update(Game1 game, GameTime gameTime)
{
        // harmonické kmytání kostky
        time += (float)gameTime.ElapsedGameTime.TotalSeconds;
        position.X += (Scale / 10) * (float)Math.Sin((2 * Math.PI / 1) * time);

        position.Y += 1;
}

Do proměnné time uložíme aktuální čas hry. U vektoru position budeme k X-ové souřadnici přičítat hodnotu našeho vzorce. Jak je vidět, tak hodnotu pro dobu otáčky jsem zvolil 1s, taže kmitání nebude chaotické. Scale ve vzorci vydělíme 10, aby jsme kompenzovali měřítko. To protože jakmile počítáte okamžitou výchylku kmitání, tak Ym se převádí na mm, ačkoliv většinou se udává v cm. My zde pracujeme s pixely, takže dělíme 10. Na konci opět přičteme k hodnotě Y +1, aby nám objekt padal směrem dolů.

Aby někoho nemátlo, že k ose X pouze přičítáme, tak se nebojte, protože Y nám vychází vždy pouze v rozmezí amplitudy, takže (-Ym až Ym), Tím pádem vždy dostaneme aktuální pozici + (0 - Ym), nebo - (Ym - 0).

Nakonec si zde opět nadefinujeme metodu SetPosition, kterou pravděpodobně využijeme u generování boxu.

public void SetPosition(int x, int y)
{
        position = new Vector2(x, y);
}

Tím máme třídu SugarBox kompletní a připravenou k použití.

Opět se řádky krátí, tak aby jsme neskončili uprostřed rozepsaného kódu si SugarBox doimplenetujeme přístě a už se pomalu dostaneme na věci jako je animace či menu. Těším se opět u dalšího dílu ze série tutoriálů o MonoGame a doufám, že se ten dnešní líbil.


 

Stáhnout

Staženo 166x (1.87 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


 


Miniatura
Všechny články v sekci
Hra JellyBox v MonoGame
Miniatura
Následující článek
Hra JellyBox v MonoGame - Sugar a Menu

 

 

Komentáře
Zobrazit starší komentáře (8)

Avatar
Kit
Redaktor
Avatar
Kit:

O důvod víc, proč používat v programu místo fixních čísel bez komentářů raději pojmenované konstanty.

Odpovědět 9.11.2013 12:54
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovídá na Kit
Jakub Lásko[Saarix]:

Pravda např. ta hodnota -100 je konstanta, tak přístě se polepším :)

Odpovědět 9.11.2013 13:04
Časem je vše možné.
Avatar
Kit
Redaktor
Avatar
Odpovídá na Jakub Lásko[Saarix]
Kit:

Pojmenované konstanty jsou jednou z možností. Druhou je psaní komentářů typu "Tahle 100 znamená, že kostka vznikne 100 px nad horním okrajem".

Běžně se však v aplikacích setkávám hlavně s nesmyslnými komentáři, které raději mažu. Pojmenované konstanty jsou podle mne mnohem výhodnější.

Odpovědět 9.11.2013 13:10
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovídá na Kit
Jakub Lásko[Saarix]:

Ok díky za radu příště to vylepším.

Odpovědět 9.11.2013 14:11
Časem je vše možné.
Avatar
Veganekk
Člen
Avatar
Veganekk:

Nejde to spustit... Chce to nejake SDL.dll ... Nejaky navod jak to zprovoznit?
Diky

Odpovědět 14.11.2013 20:35
Rád se učím novým věcem. A věci co nechápu rád pochopím a naučím.
Avatar
Odpovídá na Veganekk
Jakub Lásko[Saarix]:

Máš v PC nainstalované MonoGame?

Odpovědět 14.11.2013 21:47
Časem je vše možné.
Avatar
Veganekk
Člen
Avatar
Veganekk:

K cemu je ten Monogame :) ? slysim to prvne u XNA :/ Dik odpoved

Odpovědět  -1 14.11.2013 23:25
Rád se učím novým věcem. A věci co nechápu rád pochopím a naučím.
Avatar
Odpovídá na Veganekk
Jakub Lásko[Saarix]:

XNA už je mrtvé (jeho vývoj skončil), ale nahradilo ho MonoGame, které je vlastně tvořeno programátorskou komunitou, která byla na XNA. A zároveň MonoGame podporuje vývoj i na WP a Android ;) Je to super věc. http://monogame.codeplex.com/

Odpovědět 15.11.2013 6:20
Časem je vše možné.
Avatar
Veganekk
Člen
Avatar
Veganekk:

No to je super :D... To by mě zajímalo proč se ve škole učíme XNA když je to k prdu :D... Hustý... MOhl by někdo hodit nějaký zajímavý navody na XNA zde ci mimo tento web do POSTY. Dekuji

Odpovědět 18.11.2013 20:15
Rád se učím novým věcem. A věci co nechápu rád pochopím a naučím.
Avatar
Odpovídá na Veganekk
Michael Olšavský:

Monogame je spíše portace XNA, tzn. funkce a možnosti jsou téměř identické. Monogame má mírné rozdíly v pokročilejším 3D, ale už XNA dohání. Je zde také velká výhoda multiplatformnosti.

 
Odpovědět 18.11.2013 20:23
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.

Zobrazeno 10 zpráv z 18. Zobrazit vše