XNA – Herné Menu

xna_logo

XNA – Vytvárame herné menu

V tomto tutoriále si ukážeme ako ľahko sa dá vytvoriť herné menu.  Toto herné menu si neskôr môžete začleniť do hernej knižnice alebo si ho implementujete do nejakej hry.  Herné menu si taktiež môžete pozmeniť podľa vlastných potrieb.

Herne menu sa zvyčajne nachádza na úvodnej obrazovke,  je sprevádzane pozadím a ma svoje prvky, ktoré sú popísané špecifickými hodnotami.

Takže na začiatok si vytvoríme dve triedy (Menu a  MenuItem):

// Menu.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace GameFramework.Graphics
{
public class Menu
          {
          }
}

// MenuItem.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace GameFramework.Graphics
{
          public class MenuItem
          {
          }
}

Po vytvorení tried by ste mali vidieť vyššie popísaný kód, len bez Xna direktív, ktoré si samozrejme doplňte. Ako prvé začneme s menu položkou.

Pridáme si súkromné položky:

#region Private Field

private Texture2D activeTexture;
private Texture2D inactiveTexture;
private String text;
private Rectangle position;
private bool active;
private bool visible;

#endregion

Prvé dve premenné sú aktívna a neaktívna textúra. Neaktívna textúra je zvolená v neaktívnom stave položky a aktívna v aktívnom stave položky. Položka prechádza do aktívneho stavu, ak kurzor myši vstúpi na položku, inak je neaktívne.  Tretia premenná nám uchováva text, ktorý sa nachádza v strede položky. Štvrtá premenná nám určuje pozíciu položky. Posledné dve logické premenné nám udávajú a sledujú stav položky t.j.  či je položka aktívna, a či je viditeľná. Nasledujú konštruktory triedy:

#region Constructors

public MenuItem(Texture2D active, Texture2D inactive, String text)
{
          this.active = false;
          this.visible = true;
          this.text = text;
          this.activeTexture = active;
          this.inactiveTexture = inactive;
          this.position = new Rectangle();
}
public MenuItem(Texture2D active, Texture2D inactive, String text, bool visible)
{
          this.active = false;
          this.text = text;
          this.activeTexture = active;
          this.inactiveTexture = inactive;
          this.position = new Rectangle();
          this.visible = visible;
}

#endregion

Konštruktory nám nastavujú hodnoty. V druhom konštruktéri nastavujeme aj viditeľnosť položky.

Ďalej nasledujú vlastnosti triedy:

#region Read-Only Properties

public Texture2D ActiveTexture
{
          get
          {
                    return this.activeTexture
          }
}
public Texture2D InactiveTexture
{
          get
          {
                    return this.inactiveTexture;
          }
}
public Rectangle Position
{
          get
          {
                    return this.position;
          }
}
public Boolean Active
{
          get
          {
                    return this.active;
          }
}
public String Text
{
          get
          {
                    return this.text;
          }
}

#endregion

#region Public Properties

public int X
{
          get
          {
                    return this.position.X;
          }
          set
          {
                    this.position.X = value;
          }
}
public int Y
{
          get
          {
                    return this.position.Y;
          }
          set
          {
                    this.position.Y = value;
          }
}
public int Width
{
          get
          {
                    return this.position.Width;
          }
          set
          {
                    this.position.Width = value;
          }
}
public int Height
{
          get
          {
                    return this.position.Height;
          }
          set
          {
                    this.position.Height = value;
          }
}

public Boolean Visible
{
          get
          {
                    return this.visible;
          }
          set
          {
                    this.visible = value;
          }
}

#endregion

Tak na prvý pohľad sa zdá, že ich je nejako veľa, ale to sa časom zmení J. Myslím si, že vlastnosti netreba vysvetľovať. Mali by byť jednoznačné pre každého. Len pripomeniem, že vo väčšine prípadov používam regióny, ktoré rozdeľujú dáta triedy podľa ich použitia, ako vidíte vyššie (Read-Only Properties a Public Properties).  Ako posledné nám ostali metódy:

#region Methods

public void Update()
{
          MouseState ms = Mouse.GetState();
          if (Visible)
          {
          if (ms.X > X && ms.X < (X + Width) && ms.Y > Y && ms.Y < (Y +                     Height))
                    active = true;
          else
                    active = false;
          }
}
public void Draw(SpriteBatch spriteBatch, SpriteFont font)
{
          if (Visible)
          {
                    if (Active)
                              spriteBatch.Draw(ActiveTexture, Position,                                                                       Color.White);
                    else
                              spriteBatch.Draw(InactiveTexture, Position,                                                                       Color.White);
                              Vector2 fontSize = font.MeasureString(Text);
                              Vector2 textPosition = new Vector2(
                                        X + (Width / 2) – (fontSize.X / 2),
                                        Y + (Height / 2) – (fontSize.Y / 2));
                              spriteBatch.DrawString(font, Text, textPosition,                                                   Color.White);
          }
}

#endregion

Metóda Update začína zistením stavu myši a pokračuje príkazom „if“, či je položka viditeľná. Ak je položka viditeľná, tak sledujeme, či sa kurzor myši nachádza na položke. Ak sa nachádza nastavíme položku ako aktívnu, inak na neaktívnu. Metóda Draw preberá kresliaci objekt a štýl textu , ktoré sú potrebné na vykreslenie položky. Metóda Draw taktiež sleduje, či je položka viditeľná a ďalej sleduje, či je položka aktívna. Ak je položka aktívna, tak vykreslíme aktívnu textúru, inak vykreslíme neaktívnu textúru. Nasledujú dve premenné, ktoré uchovávajú veľkosť textu a pozíciu textu. Posledný riadok vykreslí text na položke.

Tak to by bolo všetko k položke herného menu a teraz si napíšeme kód pre celkové herné menu.
Začneme súkromnými položkami:

#region Private Field

private List<MenuItem> item;
private int borderSize;
private int blankSize;
private bool visible;
private int leftSize;

#endregion

Prvá premenná nám ukladá položky menu do zoznamu. Druhá premenná nám určuje veľkosť okraju od vrchu. Tretia premenná určuje veľkosť medzi prvkami menu. Štvrtá premenná sleduje, či je menu viditeľné a piata premenná určuje vzdialenosť od ľavého okraju. V tomto menu určujem pozíciu menu podľa vzdialenosti od vrchu, zľava a medzerou medzi položkami. Neje to ten najlepší systém, ale pre začiatok postačí. Ja momentálne používam systém, ktorý vypočíta pozíciu podľa veľkosti obrazovky a počtu prvkov, ale ten si ukážeme niekedy inokedy. Kto pozná iný systém, ktorý sa mu hodí lepšie, tak si môže zvoliť vlastný systém. Teraz sa pozrime na konštruktory:

#region Constructors

public Menu(int count, int border, int blank, int left)
{
          this.item = new List<MenuItem>(count);
          this.borderSize = border;
          this.blankSize = blank;
          this.leftSize = left;
}

public Menu(int count, int border, int blank, int left, bool visible)
{
          this.item = new List<MenuItem>(count);
          this.borderSize = border;
          this.blankSize = blank;
          this.visible = visible;
          this.leftSize = left;
}

#endregion

Konštruktory netreba nejako popisovať, mali by byť každému jasné. Napíšeme si vlastnosti menu:

#region Read-Only Properties

public List<MenuItem> Item
{
          get
          {
                    return this.item;
          }
}
public Int32 BorderSize
{
          get
          {
                    return this.borderSize;
          }
}
public Int32 BlankSize
{
          get
          {
                    return this.blankSize;
          }
}
public Boolean Visible
{
          get
          {
                    return this.visible;
          }
}

#endregion

Máme tu vlastnosti iba na čítanie, ktoré nie sú n ničím zvláštne. Takže si napíšeme metódy:

#region Public Methods

public void HideMenu()
{
          this.visible = false;
}
public void Update()
{
          if (Visible)
          {
                    for (int i = 0; i < item.Count; i++)
                    {
                              item[i].Update();
                    }
          }
}
public void AddItem(MenuItem item)
{
          this.item.Add(item);
          InitializePosition();
}

public void Draw(SpriteBatch spriteBatch, SpriteFont spriteFont)
{
          if (Visible)
          {
                    for (int i = 0; i < item.Count; i++)
                    {
                              item[i].Draw(spriteBatch, spriteFont);
                    }
          }
}

#endregion

#region Private Methods

private void InitializePosition()
{
          for (int i = 0; i < item.Count; i++)
          {
                    item[i].Width = item[i].ActiveTexture.Width;
                    item[i].Height = item[i].ActiveTexture.Height;
                    item[i].X = leftSize;
                    item[i].Y = borderSize + (item[i].Width * i) + (blankSize * i);
          }
}

#endregion

Takže prvá metóda nám slúži na skrytie menu. Metóda Update sleduje, či je menu viditeľné. Ak je viditeľné, tak sa spustí cyklus, ktorý spustí Update metódu každej položky. Metóda Draw takisto sleduje viditeľnosť menu, ak je viditeľné, tak spustí metódu Draw každej položky, čím sa menu vykreslí.  Preskočili sme metódu AddItem, ktorá slúži na pridanie položky do menu. Nakoniec metóda InitializePosition, ktorá je volaná po každom pridaní položky, slúži na vypočítanie pozícií každého prvku, čo nám zabezpečí cyklus.

Tak a týmto by sme mali hotové herné menu, ktoré si samozrejme môžete meniť podľa seba.  Teraz už len stačí v hre vytvoriť premennú typu „Menu“,  nahrať textúry, pridať položky a zavolať metódy Update a Draw. To by bolo asi tak všetko k tomuto tutoriálu.

Prajem vám prijemnú zábavu pri tvorbe menu.

Na záver:
Ak by ste si nevedeli s niečím rady, tak napíšte na e-mailovú adresu alebo na našej stránke v sekcií tutoriálov. Taktiež všetky nezhody, nedostatky alebo návrhy, ohľadom tohto tutoriálu píšte na e-mail. Nezabudnite uviesť, ako predmet názov tutoriálu.

Vypracoval: Miloš Tutko

E-mail: kqm4st3r@gmail.com

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Můžete používat následující HTML značky a atributy: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>