C# 如何制作简单的XNA按钮?

C# 如何制作简单的XNA按钮?,c#,button,xna,C#,Button,Xna,我想知道是否有人能给我展示一种在XNA中创建按钮的简单方法 最好是一种在单击时添加函数的方法,以及一种轻松添加和删除函数的方法。我建议使用用于解决GUI相关问题的方法-它有按钮,以及其他有用的GUI控件,包括弹出窗口、列表视图、组合框等 如果您正在为学习体验编写一个按钮类。。。那么,在寻求帮助之前,试着自己通过谷歌了解更多 附录 这是我为按钮编写的一些代码。也许它可以作为一个起点。我在我的2D游戏引擎中使用它,所以它已经过调试和测试 // ///一个控件,当它悬停在上面时会改变外观,单击时会触

我想知道是否有人能给我展示一种在XNA中创建按钮的简单方法

最好是一种在单击时添加函数的方法,以及一种轻松添加和删除函数的方法。

我建议使用用于解决GUI相关问题的方法-它有按钮,以及其他有用的GUI控件,包括弹出窗口、列表视图、组合框等

如果您正在为学习体验编写一个按钮类。。。那么,在寻求帮助之前,试着自己通过谷歌了解更多

附录

这是我为按钮编写的一些代码。也许它可以作为一个起点。我在我的2D游戏引擎中使用它,所以它已经过调试和测试

//
///一个控件,当它悬停在上面时会改变外观,单击时会触发一些效果
/// 
公共类谜按钮
{
/// 
///单击按钮时通知的方法签名
/// 
///单击的“谜”按钮
公共委托无效OnClickEvent(EnigmaButton发送者);
/// 
///用于Enigma按钮的纹理类型
/// 
公共枚举TextureType{Normal,Over,Press}
#区域变量
受保护的用户界面;
保护矩形m_界;
IInputExposer m_输入;
bool m_over=false,m_press=false,m_wasppress=false;
字典m_纹理;
字符串m_text,m_name;
Enigmam_字体;
int m_minTextShadow,m_maxTextShadow;
彩色m_文本色调;
公共事件OnClick事件OnClick;
#端区
/// 
///一个控件,当它悬停在上面时会改变外观,单击时会触发一些效果
/// 
///图形资产
///用于鼠标输入和XBox控制器输入的输入曝光器
///用于控制器定义的XMLReader
///控制器的界
公共EnigmaButton(IVisualExposer ui、IInputExposer输入、XmlReader阅读器、矩形pos)
{
m_ui=ui;
m_界限=位置;
m_纹理=新字典();
m_输入=输入;
启用=真;
#区域读数
字符串名;
bool start=false,insideText=false;
while(reader.Read())
{
if(reader.MoveToContent()==XmlNodeType.Element)
{
name=reader.name.ToLower();
如果(名称=“按钮”)
{
如果(启动)
抛出新异常(“已启动”);
开始=真;
m_name=reader.GetAttribute(“name”)??string.Empty;
}
否则,如果(!已启动)
抛出新异常(“未启动”);
else if(名称=“文本”)
{
m_font=新谜资源();
m_font.Filepath=reader.GetAttribute(“font”);
字符串minShadow=reader.GetAttribute(“minShadow”),maxShadow=reader.GetAttribute(“maxShadow”);
m_minTextShadow=minShadow!=null?int.Parse(minShadow):0;
m_maxTextShadow=maxShadow!=null?int.Parse(maxShadow):2;
m_text=reader.GetAttribute(“text”)??string.Empty;
insideText=true;
m_textint=颜色。白色;
}
else if(name==“bounds”)
{
insideText=false;
m_bounds=新矩形(int.Parse(reader.GetAttribute(“x”)),int.Parse(reader.GetAttribute(“y”)),
int.Parse(reader.GetAttribute(“宽度”)),int.Parse(reader.GetAttribute(“高度”));
}
else if(名称==“纹理”)
{
insideText=false;
TextureType textType=(TextureType)Enum.Parse(typeof(TextureType),reader.GetAttribute(“type”);
if(m_textures.ContainsKey(texType))
抛出新异常(“类型为“”+TextType.ToString()+“'的纹理不能注册两次”);
EnigmaResource res=新EnigmaResource();
res.Filepath=reader.ReadString();
添加(texType,res);
}
否则如果(名称==“色调”)
{
如果(!insideText)
抛出新异常(“色调只能用于文本”);
浮子a、r、g、b;
string[]split=reader.ReadString().split(',');
如果(拆分长度!=4)
抛出新异常(“颜色必须是RGBA”);
r=float.Parse(拆分[0].Trim());
g=float.Parse(split[1].Trim());
b=float.Parse(split[2].Trim());
a=float.Parse(split[3].Trim());
m_textint=新颜色(r、g、b、a);
}
}
}
#端区
如果(!m_textures.ContainsKey(TextureType.Normal))
抛出新异常(“按钮必须至少有一个''+TextureType.Normal.ToString()+“'texture”);
}
#区域方法
公共无效初始化()
{
}
公共void LoadContent()
{
谜团;
对于(int i=0;i/// <summary>
/// A control that changes appearance when it is hovered over and triggers some effect when it is clicked
/// </summary>
public class EnigmaButton
{
    /// <summary>
    /// The method signature for notification when a button is clicked
    /// </summary>
    /// <param name="sender">EnigmaButton that was clicked</param>
    public delegate void OnClickEvent(EnigmaButton sender);

    /// <summary>
    /// Types of textures used for Enigma Buttons
    /// </summary>
    public enum TextureType { Normal, Over, Press }

    #region Variables
protected IVisualExposer m_ui;
protected Rectangle m_bounds;
    IInputExposer m_input;
    bool m_over = false, m_press = false, m_wasPressed = false;

    Dictionary<TextureType, EnigmaResource<Texture2D>> m_textures;
    string m_text, m_name;
    EnigmaResource<SpriteFont> m_font;
    int m_minTextShadow, m_maxTextShadow;
    Color m_textTint;

    public event OnClickEvent OnClick;
    #endregion

    /// <summary>
    /// A control that changes appearance when it is hovered over and triggers some effect when it is clicked
    /// </summary>
    /// <param name="ui">Graphical assets</param>
    /// <param name="input">Input exposer for mouse input and XBox controller input</param>
    /// <param name="reader">XMLReader for the definition of the controller</param>
    /// <param name="pos">Bounds of the controller</param>
    public EnigmaButton(IVisualExposer ui, IInputExposer input, XmlReader reader, Rectangle pos)
    {
    m_ui = ui;
    m_bounds = pos;
        m_textures = new Dictionary<TextureType, EnigmaResource<Texture2D>>();
        m_input = input;
        Enabled = true;

        #region Reading
        string name;
        bool started = false, insideText = false;

        while (reader.Read())
        {
            if (reader.MoveToContent() == XmlNodeType.Element)
            {
                name = reader.Name.ToLower();
                if (name == "button")
                {
                    if (started)
                        throw new Exception("Already started.");
                    started = true;

                    m_name = reader.GetAttribute("name") ?? string.Empty;
                }
                else if (!started)
                    throw new Exception("Not started");
                else if (name == "text")
                {
                    m_font = new EnigmaResource<SpriteFont>();
                    m_font.Filepath = reader.GetAttribute("font");

                    string minShadow = reader.GetAttribute("minShadow"), maxShadow = reader.GetAttribute("maxShadow");
                    m_minTextShadow = minShadow != null ? int.Parse(minShadow) : 0;
                    m_maxTextShadow = maxShadow != null ? int.Parse(maxShadow) : 2;

                    m_text = reader.GetAttribute("text") ?? string.Empty;
                    insideText = true;
                    m_textTint = Color.White;
                }
                else if (name == "bounds")
                {
                    insideText = false;
                    m_bounds = new Rectangle(int.Parse(reader.GetAttribute("x")), int.Parse(reader.GetAttribute("y")),
                        int.Parse(reader.GetAttribute("width")), int.Parse(reader.GetAttribute("height")));
                }
                else if (name == "texture")
                {
                    insideText = false;
                    TextureType texType = (TextureType)Enum.Parse(typeof(TextureType), reader.GetAttribute("type"));
                    if (m_textures.ContainsKey(texType))
                        throw new Exception("A texture of type '" + texType.ToString() + "' cannot  be registered twice");
                    EnigmaResource<Texture2D> res = new EnigmaResource<Texture2D>();
                    res.Filepath = reader.ReadString();
                    m_textures.Add(texType, res);
                }
                else if (name == "tint")
                {
                    if (!insideText)
                        throw new Exception("Tints can only be for text");

                    float a, r, g, b;
                    string[] split = reader.ReadString().Split(',');
                    if (split.Length != 4)
                        throw new Exception("Colors must be RGBA");
                    r = float.Parse(split[0].Trim());
                    g = float.Parse(split[1].Trim());
                    b = float.Parse(split[2].Trim());
                    a = float.Parse(split[3].Trim());

                    m_textTint = new Color(r, g, b, a);
                }
            }
        }
        #endregion

        if (!m_textures.ContainsKey(TextureType.Normal))
            throw new Exception("A button must have at least a '" + TextureType.Normal.ToString() + "' texture");
    }

    #region Methods
    public void Initialize()
    {
    }

    public void LoadContent()
    {
        EnigmaResource<Texture2D> res;
        for (int i = 0; i < m_textures.Count; i++)
        {
            res = m_textures[m_textures.ElementAt(i).Key];
            res.Resource = m_ui.Content.Load<Texture2D>(res.Filepath);
            m_textures[m_textures.ElementAt(i).Key] = res;
        }

        if (m_font.Filepath != null)
            m_font.Resource = m_ui.Content.Load<SpriteFont>(m_font.Filepath);
    }

    public void Update(GameTime gameTime)
    {
        m_wasPressed = m_press;
        m_over = m_bounds.Contains(m_input.MouseX, m_input.MouseY);
        m_press = m_over ? m_wasPressed ? m_input.IsMouseLeftPressed || m_input.IsButtonPressed(Buttons.A) : m_input.IsMouseLeftTriggered || m_input.IsButtonTriggered(Buttons.A) : false;
        if (!m_wasPressed && m_press && OnClick != null)
            OnClick(this);
    }

    public void Draw(GameTime gameTime)
    {
        Texture2D toDraw = m_textures[TextureType.Normal].Resource;
        if (Enabled)
        {
            if (m_press && m_textures.ContainsKey(TextureType.Press))
                toDraw = m_textures[TextureType.Press].Resource;
            else if (m_over && m_textures.ContainsKey(TextureType.Over))
                toDraw = m_textures[TextureType.Over].Resource;
        }
        m_ui.SpriteBatch.Draw(toDraw, m_bounds, Enabled ? Color.White : Color.Gray);

        if (m_font.Resource != null)
        {
            Vector2 pos = new Vector2(m_bounds.X, m_bounds.Y);
            Vector2 size = m_font.Resource.MeasureString(m_text);
            pos.X += (m_bounds.Width - size.X) / 2;
            pos.Y += (m_bounds.Height - size.Y) / 2;
            UIHelper.DrawShadowedString(m_ui, m_font.Resource, m_text, pos, m_textTint, m_minTextShadow, m_maxTextShadow);
        }
    }
    #endregion

    #region Properties
    /// <summary>
    /// Gets or sets the name of the button
    /// </summary>
    public string Name
    {
        get { return m_name; }
        set { m_name = value ?? m_name; }
    }

    /// <summary>
    /// Gets or sets the text drawn in the button.
    /// WARNING: Will overflow if the text does not normally fit.
    /// </summary>
    public string Text
    {
        get { return m_text; }
        set { m_text = value ?? string.Empty; }
    }

    /// <summary>
    /// Gets or sets the bounds of the button
    /// </summary>
    public Rectangle Bounds
    {
        get { return m_bounds; }
        set { m_bounds = value; }
    }

    /// <summary>
    /// Whether or not the control is enabled
    /// </summary>
public bool Enabled { get; set; }
    #endregion
}