Guida [XNA] ProgressBar e classe astratta Control

Stato
Discussione chiusa ad ulteriori risposte.

ManHunter

Utente Jade
14 Settembre 2009
985
111
780
818
Ultima modifica:
Salve a tutti,

proprio ieri ero alle prese con la realizzazione dei controlli per il mio videogame.
Uno di essi, la ProgressBar, lo porto come argomento di discussione qui.


Ma bando alle ciance, iniziamo.
Innanzitutto, occorre creare una generica classe "Control", che ci permetterà di derivare da essa tutti i controlli di cui abbiamo bisogno.


Quindi, creiamo una nostra classe chiamata "Control.cs":

[
C#:
]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;


namespace YourLibrary.Controls
{
    public abstract class Control
    {
        #region Campi


        protected string name;
        protected string text;
        protected Vector2 size;
        protected Vector2 position;
        protected object value;
        protected bool hasFocus;
        protected bool enabled;
        protected bool visible;
        protected bool tabStop;
        protected SpriteFont spriteFont;
        protected Color color;
        protected string type;


        #endregion


        #region Eventi


        public event EventHandler Selected;
        public event EventHandler Clicked;


        #endregion


        #region Proprietà


        public string Name
        {
            get { return name; }
            set { name = value; }
        }


        public string Text
        {
            get { return text; }
            set { text = value; }
        }


        public Vector2 Size
        {
            get { return size; }
            set { size = value; }
        }


        public Vector2 Position
        {
            get { return position; }
            set
            {
                position = value;
                position.Y = (int)position.Y;
            }
        }
        public object Value
        {
            get { return value; }
            set { this.value = value; }
        }
        public bool HasFocus
        {
            get { return hasFocus; }
            set { hasFocus = value; }
        }
        public bool Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }
        public bool Visible
        {
            get { return visible; }
            set { visible = value; }
        }
        public bool TabStop
        {
            get { return tabStop; }
            set { tabStop = value; }
        }
        public SpriteFont SpriteFont
        {
            get { return spriteFont; }
            set { spriteFont = value; }
        }
        public Color Color
        {
            get { return color; }
            set { color = value; }
        }
        public string Type
        {
            get { return type; }
            set { type = value; }
        }


        #endregion


        #region Costruttori


        public Control()
        {
            Color = Color.White;
            Enabled = true;
            Visible = true;
            SpriteFont = ControlManager.SpriteFont;
        }


        #endregion


        #region Metodi Astratti


        public abstract void Update(GameTime gameTime);
        public abstract void Draw(SpriteBatch spriteBatch);
        public abstract void Draw(SpriteBatch spriteBatch, float opacity);
        public abstract void HandleInput(PlayerIndex playerIndex);


        #endregion


        #region Metodi Virtuali


        protected virtual void OnSelected(EventArgs e)
        {
            if (Selected != null)
            {
                Selected(this, e);
            }
        }


        protected virtual void OnClick(EventArgs e)
        {
            if (Clicked != null)
            {
                Clicked(this, e);
            }
        }


        #endregion
    }
}


(P.S.: Tale classe potete trovarla seguendo la serie di tutorial di xnagpa.net, dei quali ho davvero apprezzato l'approccio)


Come potete notare, essa espone quattro metodi astratti che dovranno essere implementati da qualunque classe erediti da essa.
Abbiamo ora la nostra classe base dalla quale potremo creare qualsiasi controllo ci occorra nel nostro gioco/applicativo.


Il controllo che voglio implementare è, come già detto, la ProgressBar.
Creiamo, quindi, la nostra classe "ProgressBar.cs".
Ecco il codice:

C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;


namespace YourLibrary.Controls
{
    public class ProgressBar : Control
    {
        #region Campi


        Texture2D externBar;
        Texture2D internBar;
        Vector2 position;
        int maxBarValue;        //Rappresenta il valore massimo raggiungibile dalla barra
        int barInc;             //Rappresenta la quantità da incrementare ad ogni step
        int totInc;             //Rappresenta l'incremento della barra
        float rateo;            //Rappresenta l'incremento della barra rispetto alla sua dimensione Width
        float steps;            //Rappresenta l'avanzamento totale della barra rispetto alla sua dimensione Width


        #endregion


        #region Proprietà


        public int MaxBarValue
        {
            get { return maxBarValue; }
            set { maxBarValue = value; }
        }


        public int BarInc
        {
            get { return barInc; }
            set { barInc = value; }
        }


        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }


        public float Rateo
        {
            get { return rateo; }
        }


        #endregion


        #region Costruttori


        public ProgressBar(Texture2D extBar, Texture2D intBar)
        {
            externBar = extBar;
            internBar = intBar;
            maxBarValue = 100;
            barInc = 1;
            totInc = 0;
            steps = 0f;
            position = new Vector2(0, 0);
            rateo = (float)((internBar.Width) / (maxBarValue / barInc));
        }


        public ProgressBar(Texture2D extBar, Texture2D intBar, int size, int inc)
        {
            externBar = extBar;
            internBar = intBar;
            maxBarValue = size;
            barInc = inc;
            totInc = 0;
            steps = 0f;
            position = new Vector2(0, 0);
            rateo = (float)((internBar.Width) / (maxBarValue / barInc));
        }


        public ProgressBar(Texture2D extBar, Texture2D intBar, Vector2 pos)
        {
            externBar = extBar;
            internBar = intBar;
            maxBarValue = 100;
            barInc = 1;
            totInc = 0;
            steps = 0f;
            position = pos;
            rateo = (float)((internBar.Width) / (maxBarValue / barInc));
        }


        public ProgressBar(Texture2D extBar, Texture2D intBar, int size, int inc, Vector2 pos)
        {
            externBar = extBar;
            internBar = intBar;
            maxBarValue = size;
            barInc = inc;
            totInc = 0;
            steps = 0f;
            position = pos;
            rateo = (float)((internBar.Width) / (maxBarValue / barInc));
        }


        #endregion


        #region Metodi astratti


        public override void Update(GameTime gameTime)
        {

        }


        public override void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(externBar, Position, Color.White);
            spriteBatch.Draw(internBar, new Rectangle((int)position.X, (int)position.Y, (int)steps, internBar.Height), Color.White);
        }


        public override void Draw(SpriteBatch spriteBatch, float opacity)
        {
            spriteBatch.Draw(externBar, Position, Color.White * opacity);
            spriteBatch.Draw(internBar, new Rectangle((int)position.X, (int)position.Y, (int)steps, internBar.Height), Color.White * opacity);
        }


        public override void HandleInput(PlayerIndex playerIndex)
        {

        }


        #endregion


        #region Metodi ProgressBar


        public void PerformStep()
        {
            totInc += barInc;
            steps += rateo;
            if (totInc > maxBarValue)
                totInc = maxBarValue;
            if (steps > internBar.Width)
                steps = internBar.Width;
        }


        public void ClearBar()
        {
            totInc = 0;
            steps = 0;
        }


        #endregion
    }
}


Tale classe eredita da "Control" e fa override sui metodi astratti di tale classe.
Inoltre, espone due metodi:
- PerformStep()
- ClearBar()
Come intuibile, PerformStep() esegue un "avanzamento" della barra.
La dimensione dell'avanzamento è determinato da:
- barInc, a livello logico
- rateo, a livello grafico
ClearBar(), invece, resetta la barra impostando lo stato della barra a 0.






Non mi viene in mente altro da aggiungere, per cui se ho dimenticato qualcosa vi prego di farmelo notare! Provvederò subito a chiarire o, nel caso, ad aggiungere dettagli!


Saluti! :D
 
Ottimo lavoro!!
Solo un consiglio, le properties falle utili, così come sono sono veramente inutili, per esempio controlla che i dati immessi siano validi!
 
  • Mi piace
Reazioni: ManHunter
Stato
Discussione chiusa ad ulteriori risposte.