65.9K
CodeProject 正在变化。 阅读更多。
Home

如何创建带有鼠标事件的 XNA 按钮和标签

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2013 年 1 月 23 日

CPOL

2分钟阅读

viewsIcon

29195

如何创建带有鼠标事件的 XNA 按钮和标签。

引言

在 XNA 中使用按钮非常常见且重要,所以让我们创建带有 MouseOverMouseClick 事件的按钮。我使用了声音来为 MouseOverMouseDown 的结果创建一些动作。

使用代码

首先,我们应该为我们的图片按钮创建结构体

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Media;
using System.Collections;
using Language_Learning_Application;
public struct picture
{
    public string strfilename;
    public string strfilename1;
    public string strfilename2;
    //SoundFiles
    //Mousein
    public string strfilename3;
    //MouseClick
    public string strfilename4;
    public string GiveMeTheCurrentFilename(int FormNumber,string Action)
    {
        if((Action!="LabelAnimation"))
        {
            if (FormNumber == 1) return strfilename;
            if (FormNumber == 2) return strfilename1;
            if (FormNumber == 3) return strfilename2;
        }
        return strfilename;
    }
    public string GiveMeTheCurrentFilenameSound(int SoundNumber)
    {
        if (SoundNumber == 1) return strfilename3;
        if (SoundNumber == 2) return strfilename4;
        return strfilename;
    }
    // Audio objects
    public SoundEffect soundEffect;
    public int intCurrentForm;
    public int CurrentSound;
    public Rectangle rectangleDestination;
    public bool boolisLoaded;
    public string strplaceOfUse;
    public int key;
    public bool ShouldItBeShownInThisScreen;
    public Texture2D Texture;
    public string Action;
    public string MousePictureState;
    public bool PlayingSound ;
    //Animation
    public bool HasItAnimation;
    public bool IsAnimationOn;
    public int TotalAnimationFrame;
    public int CurentAnimationFrame;
    public string OriginalFilenameWithoutIndex;
    public int FramePerSecond;
}

然后我们创建一个结构体来定义我们的 MouseButton 键和功能。

public struct MouseButton
{
    public ButtonState LeftClick;
    public ButtonState RightClick;
    public ButtonState MiddleClick;
    public int ScrollWheel ;
    public bool IsThisPointInThisRectangle ;
}

现在我们从主类中获取 ContentManager

private ContentManager content;
public ContentManager PropertyContent
{
    set
    {
        content = value;
    }
}

现在我们定义我们的按钮和标签

public picture tex2dBtnAddNewWords;
public picture tex2dBtnLearn;
public picture tex2dBtnExit;
public picture tex2dBtnUpdate;
public picture lblPleaseWriteYourWordHere;
public picture txtWord;

让我们将我们的按钮和标签放在一个公共数组中,以便在我们的项目中的任何地方使用它

public picture[] mypictures=new picture[6];

现在我们初始化我们的按钮和标签

public void InitializeDefenitions()
{
    string BaseDirectory = ".";
    //tex2dBtnAddNewWords
    tex2dBtnAddNewWords.key = 1;
    tex2dBtnAddNewWords.strfilename = BaseDirectory + "\\StartPage\\Buttons\\jpgAddNewWordsForm1";
    tex2dBtnAddNewWords.strfilename1 = BaseDirectory + "\\StartPage\\Buttons\\jpgAddNewWordsForm2";
    tex2dBtnAddNewWords.strfilename2 = BaseDirectory + "\\StartPage\\Buttons\\jpgAddNewWordsForm3";
    tex2dBtnAddNewWords.strfilename3 = BaseDirectory + "\\StartPage\\Sounds\\ButtonMouseOverSound";
    tex2dBtnAddNewWords.strfilename4 = BaseDirectory + "\\StartPage\\Sounds\\ButtonClickSound";
    tex2dBtnAddNewWords.rectangleDestination = new Rectangle((WindowsScreenWidth - 778) / 2, 
           (WindowsScreenHeight - 124) / 2  - 124-124, 778, 124);
    tex2dBtnAddNewWords.boolisLoaded = false;
    tex2dBtnAddNewWords.strplaceOfUse = "StartPage";
    tex2dBtnAddNewWords.ShouldItBeShownInThisScreen = true;
    tex2dBtnAddNewWords.Texture = null;
    tex2dBtnAddNewWords.Action = "Button";
    tex2dBtnAddNewWords.intCurrentForm = 1;
    tex2dBtnAddNewWords.MousePictureState = "OutOfControl";
    tex2dBtnAddNewWords.CurrentSound = 1;
    //tex2dBtnLearn
    tex2dBtnLearn.key = 2;
    tex2dBtnLearn.strfilename = BaseDirectory + "\\StartPage\\Buttons\\jpgLearnForm1";
    tex2dBtnLearn.strfilename1 = BaseDirectory + "\\StartPage\\Buttons\\jpgLearnForm2";
    tex2dBtnLearn.strfilename2 = BaseDirectory + "\\StartPage\\Buttons\\jpgLearnForm3";
    tex2dBtnLearn.strfilename3 = BaseDirectory + "\\StartPage\\Sounds\\ButtonMouseOverSound";
    tex2dBtnLearn.strfilename4 = BaseDirectory + "\\StartPage\\Sounds\\ButtonClickSound";
    tex2dBtnLearn.rectangleDestination = new Rectangle(
      (WindowsScreenWidth - 778) / 2, (WindowsScreenHeight - 124) / 2 +20 , 778, 124);
    tex2dBtnLearn.boolisLoaded = false;
    tex2dBtnLearn.strplaceOfUse = "StartPage";
    tex2dBtnLearn.ShouldItBeShownInThisScreen = true;
    tex2dBtnLearn.Texture = null;
    tex2dBtnLearn.Action = "Button";
    tex2dBtnLearn.intCurrentForm = 1;
    tex2dBtnLearn.MousePictureState = "OutOfControl";
    tex2dBtnLearn.CurrentSound = 1;
    //tex2dBtnExit
    tex2dBtnExit.key = 3;
    tex2dBtnExit.strfilename = BaseDirectory + "\\StartPage\\Buttons\\jpgExitForm1";
    tex2dBtnExit.strfilename1 = BaseDirectory + "\\StartPage\\Buttons\\jpgExitForm2";
    tex2dBtnExit.strfilename2 = BaseDirectory + "\\StartPage\\Buttons\\jpgExitForm3";
    tex2dBtnExit.strfilename3 = BaseDirectory + "\\StartPage\\Sounds\\ButtonMouseOverSound";
    tex2dBtnExit.strfilename4 = BaseDirectory + "\\StartPage\\Sounds\\ButtonClickSound";
    tex2dBtnExit.rectangleDestination = new Rectangle((WindowsScreenWidth - 778) / 2, 
       (WindowsScreenHeight - 124) / 2+124  + 30, 778, 124);
    tex2dBtnExit.boolisLoaded = false;
    tex2dBtnExit.strplaceOfUse = "StartPage";
    tex2dBtnExit.ShouldItBeShownInThisScreen = true;
    tex2dBtnExit.Texture = null;
    tex2dBtnExit.Action = "Button";
    tex2dBtnExit.intCurrentForm = 1;
    tex2dBtnExit.MousePictureState = "OutOfControl";
    tex2dBtnExit.CurrentSound = 1;
    //
    //tex2dBtnUpdate
    tex2dBtnUpdate.key = 4;
    tex2dBtnUpdate.strfilename = BaseDirectory + "\\StartPage\\Buttons\\jpgUpdateForm1";
    tex2dBtnUpdate.strfilename1 = BaseDirectory + "\\StartPage\\Buttons\\jpgUpdateForm2";
    tex2dBtnUpdate.strfilename2 = BaseDirectory + "\\StartPage\\Buttons\\jpgUpdateForm3";
    tex2dBtnUpdate.strfilename3 = BaseDirectory + "\\StartPage\\Sounds\\ButtonMouseOverSound";
    tex2dBtnUpdate.strfilename4 = BaseDirectory + "\\StartPage\\Sounds\\ButtonClickSound";
    tex2dBtnUpdate.rectangleDestination = new Rectangle((WindowsScreenWidth - 778) / 2, 
      (WindowsScreenHeight - 124) / 2 + 10 - 124, 778, 124);
    tex2dBtnUpdate.boolisLoaded = false;
    tex2dBtnUpdate.strplaceOfUse = "StartPage";
    tex2dBtnUpdate.ShouldItBeShownInThisScreen = true;
    tex2dBtnUpdate.Texture = null;
    tex2dBtnUpdate.Action = "Button";
    tex2dBtnUpdate.intCurrentForm = 1;
    tex2dBtnUpdate.MousePictureState = "OutOfControl";
    tex2dBtnUpdate.CurrentSound = 1;
    //lblPleaseWriteYourWordHere
    lblPleaseWriteYourWordHere.key = 5;
    lblPleaseWriteYourWordHere.strfilename = BaseDirectory + 
      "\\AddNewWordsPage1\\Labels\\Please Write Your Word Here\\Please write your word Here1";
    lblPleaseWriteYourWordHere.OriginalFilenameWithoutIndex = BaseDirectory + 
      "\\AddNewWordsPage1\\Labels\\Please Write Your Word Here\\Please write your word Here";
    lblPleaseWriteYourWordHere.rectangleDestination = 
      new Rectangle((WindowsScreenWidth - 515) / 2, (WindowsScreenHeight - 63) / 2-63-63 , 515, 63);
    lblPleaseWriteYourWordHere.boolisLoaded = false;
    lblPleaseWriteYourWordHere.strplaceOfUse = "AddNewWords_Word";
    lblPleaseWriteYourWordHere.ShouldItBeShownInThisScreen = false;
    lblPleaseWriteYourWordHere.Texture = null;
    lblPleaseWriteYourWordHere.Action = "LabelAnimation";
    lblPleaseWriteYourWordHere.intCurrentForm = 1;
    lblPleaseWriteYourWordHere.MousePictureState = "OutOfControl";
    lblPleaseWriteYourWordHere.TotalAnimationFrame = 30;
    lblPleaseWriteYourWordHere.CurentAnimationFrame = 1;
    lblPleaseWriteYourWordHere.IsAnimationOn = true;
    lblPleaseWriteYourWordHere.HasItAnimation = true;
    lblPleaseWriteYourWordHere.FramePerSecond = 8;
    //txtWord
    txtWord.key = 6;
    txtWord.strfilename = BaseDirectory + "\\AddNewWordsPage1\\Labels\\TextBox\\TextBox";
    txtWord.strfilename3 = BaseDirectory + 
      "\\AddNewWordsPage1\\Labels\\Please Write Your Word Here\\Please write your word Here";
    txtWord.rectangleDestination = new Rectangle((WindowsScreenWidth - 1000) / 2, 
      (WindowsScreenHeight - 300) / 2 + 50, 1000, 300);
    txtWord.boolisLoaded = false;
    txtWord.strplaceOfUse = "AddNewWords_Word";
    txtWord.ShouldItBeShownInThisScreen = false;
    txtWord.Texture = null;
    txtWord.Action = "TextBox";
    txtWord.intCurrentForm = 1;
    txtWord.MousePictureState = "OutOfControl";
    txtWord.CurrentSound = 1;
    //ArrayList=>Mypictures
    mypictures[0] = tex2dBtnAddNewWords;
    mypictures[1] = tex2dBtnLearn;
    mypictures[2] = tex2dBtnExit;
    mypictures[3] = tex2dBtnUpdate;
    mypictures[4] = lblPleaseWriteYourWordHere;
    mypictures[5] = txtWord;
}

现在我们初始化了按钮,让我们循环遍历它们以在屏幕上显示它们

我们在这里创建一个循环引擎

public int CurrentPicture=0; 

public void fncEngineMotor()
{
    for (int i=0; i < mypictures.Length; i++)
    {
        CurrentPicture = i;
        myloadContent(ref mypictures[CurrentPicture]);
        fncCheckForMouseMoveOnButton(Mouse.GetState(), ref mypictures[CurrentPicture]);
        fncCheckForMouseEnterOnButtonSound(Mouse.GetState(), ref mypictures[CurrentPicture]);
        DoAnimationFrame(ref mypictures[CurrentPicture]);
    }
} 

在这里我们加载和卸载每张图片的资源

public void myloadContent(ref picture mypicture)
{
    if (mypicture.strplaceOfUse == strProgramState)
    {
        if (mypicture.ShouldItBeShownInThisScreen == true)
        {
                mypicture.Texture = content.Load<Texture2D>(
                  mypicture.GiveMeTheCurrentFilename(mypicture.intCurrentForm, mypicture.Action));
                if (mypicture.Action != "LabelAnimation" && mypicture.Action != "TextBox") 
            {
                    mypicture.soundEffect = content.Load<SoundEffect>(
                      mypicture.GiveMeTheCurrentFilenameSound(mypicture.CurrentSound));
            }
        }
        if (mypicture.ShouldItBeShownInThisScreen == false)
        {
            mypicture.Texture = null;
            mypicture.soundEffect = null;
        }
    }
}

让我们在鼠标悬停和鼠标点击时更改按钮的纹理,以吸引用户

public void fncCheckForMouseMoveOnButton(MouseState MyMousestate,ref picture myPicture)
{
    if (myPicture.ShouldItBeShownInThisScreen)
    {
        MouseButton result = fncIsThisPointInThisRectangle(MyMousestate.X, MyMousestate.Y, 
          MyMousestate.LeftButton, MyMousestate.RightButton, MyMousestate.MiddleButton, 
          MyMousestate.ScrollWheelValue, myPicture.rectangleDestination);
        if (result.IsThisPointInThisRectangle)
        {
            if (myPicture.Action == "Button")
            {
                myPicture.intCurrentForm = 2;
               
                if (result.LeftClick == ButtonState.Pressed)
                {
                    myPicture.intCurrentForm = 3;
                }

            }
        }
        if (!result.IsThisPointInThisRectangle)
        {
            if (myPicture.Action == "Button")
            {
                if (myPicture.intCurrentForm != 1)
                {
                    myPicture.intCurrentForm = 1;
                }
            }
        }
    }
}

鼠标是否在按钮上?

为此我们需要查看鼠标是否在按钮上?

我们在这里执行此操作

public MouseButton fncIsThisPointInThisRectangle(int MyMousestateX, int MyMousestateY, 
  Microsoft.Xna.Framework.Input.ButtonState LeftButton, 
  Microsoft.Xna.Framework.Input.ButtonState RightButton, 
  Microsoft.Xna.Framework.Input.ButtonState MiddleButton, 
  int ScrollWheelValue, Rectangle thisRectangle)
{
     MouseButton result=new MouseButton();
    if (MyMousestateX > thisRectangle.Left && MyMousestateX < 
      thisRectangle.Right && MyMousestateY < thisRectangle.Bottom && 
      MyMousestateY > thisRectangle.Top)
    {
        result.IsThisPointInThisRectangle = true;
        result.LeftClick = LeftButton;
        result.MiddleClick = MiddleButton;
        result.RightClick = RightButton;
        result.ScrollWheel = ScrollWheelValue;
    }
    return result;
} 

鼠标事件

现在我们需要一些声音,让用户在鼠标悬停和鼠标点击时感到高兴。

像这样操作

public int fncCheckForMouseEnterOnButtonSound(MouseState MyMousestate,ref picture myPicture)
{
    int myreturn = 0;
    if (myPicture.ShouldItBeShownInThisScreen)
    {
        MouseButton result = fncIsThisPointInThisRectangle(MyMousestate.X, MyMousestate.Y, 
           MyMousestate.LeftButton, MyMousestate.RightButton, MyMousestate.MiddleButton, 
           MyMousestate.ScrollWheelValue, myPicture.rectangleDestination);
        if (result.IsThisPointInThisRectangle)
        {
            if (myPicture.Action == "Button")
            {
                if (result.LeftClick ==Microsoft.Xna.Framework.Input.ButtonState.Pressed)
                {
                    if (myPicture.MousePictureState == "ControlPressed")
                    {
                        myPicture.CurrentSound = 1;
                        myPicture.MousePictureState = "ControlPressedRepetition";
                        myPicture.PlayingSound = false;
                    }
                    else if (myPicture.MousePictureState == "InControlRepetition")
                    {
                        myPicture.MousePictureState = "ControlPressed";
                    }
                }
                else if (myPicture.MousePictureState == "OutOfControl")
                {
                    myPicture.CurrentSound = 1;
                    myPicture.MousePictureState = "InControlForTheFirstTime";
                    myPicture.PlayingSound = true;
                    fncPutAWavSoundOnBuffer(1);

                }
                else if (myPicture.MousePictureState == "InControlForTheFirstTime")
                {
                    myPicture.MousePictureState = "InControlRepetition";
                    myPicture.PlayingSound = false;
                }
                //
                else if (result.LeftClick == Microsoft.Xna.Framework.Input.ButtonState.Released)
                {
                    if (myPicture.MousePictureState == "ControlPressedRepetition")
                    {
                        myPicture.MousePictureState = "InControlRepetition";
                        myPicture.CurrentSound = 2;
                        myPicture.PlayingSound = true;
                        fncPutAWavSoundOnBuffer(2);
                        OnPressButton(myPicture.key);
                        if (isarrlistMypicturesUnderConstruction)
                        {
                            isarrlistMypicturesUnderConstruction = false;
                            return 1000;
                        }
                    }
                }
            }
        }
        if (!result.IsThisPointInThisRectangle)
        {
            if (myPicture.Action == "Button")
            {
                myPicture.MousePictureState = "OutOfControl";
                myPicture.PlayingSound = false;
            }
        }
    }
    return myreturn;
}

点击了吗?

public void OnPressButton(int ButtonKey)
{
    switch (ButtonKey)
    {
        case 0:
            {
                Dosth();
                break;
            }
        case 1:
            {
                break;
            }
        case 2:
            {
                
                break;
            }
        case 3:
            {
                break;
            }
        case 4:
           {
               break;
           }
        case 5:
           {
               break;
           }
        case 6:
           {
               break;
           }
        case 7:
           {
              Dosth();
               break;
           }
        case 8:
           {
               break;
           }
        default:
           {
               break;
           }
    }
}

声音缓冲区

现在如何处理声音,我们创建一个缓冲区来处理简单的声音,每个声音都会被加载并在轮到它时播放

public bool songbuffer = false;
public bool soundbuffer = false;
public Song CurrentSong;
public SoundEffect CurrentSound; 
public void fncPutAMP3SoundOnBuffer(int code)
{
    CurrentSong = content.Load<Song>(GivemeSoundFileNameByCode(code));
    songbuffer = true;
}
public void fncPutAWavSoundOnBuffer(int code)
{
    CurrentSound = content.Load<SoundEffect>(GivemeSoundFileNameByCode(code));
    soundbuffer = true;
}

让我们查找声音文件名是否在这里

public string GivemeSoundFileNameByCode(int code)
{
    string BaseDirectory = ".";
    switch (code)
    {
        case 1:
            {
                return BaseDirectory + "\\StartPage\\Sounds\\ButtonMouseOverSound";
            }
        case 2:
            {
                return BaseDirectory + "\\StartPage\\Sounds\\ButtonClickSound";
            }
        case 3:
            {
                return BaseDirectory + "\\AddNewWordsPage1\\Sounds\\mp3PleaseWiteYourWordHere";
            }
        default:
            {
                break;
            }
    }
    return "";
}

我们的主游戏更新将如下所示

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == 
             Microsoft.Xna.Framework.Input.ButtonState.Pressed)
        this.Exit();
    clsMyDefenition.fncEngineMotor();
    clsMyDefenition.fncGenerateTime();
    PlaySound();
    base.Update(gameTime);
}

在这里播放声音

/// <summary>
/// ////////////
/// </summary>
public void PlaySound()
{
    if (clsMyDefenition.soundbuffer)
    {
        clsMyDefenition.CurrentSound.Play();
        clsMyDefenition.soundbuffer = false;
    }  
    if (clsMyDefenition.songbuffer)
    {
        MediaPlayer.Play(clsMyDefenition.CurrentSong);
        clsMyDefenition.songbuffer = false;
    }            
}

这将是我们的主要绘制

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.Black);
    // TODO: Add your drawing code here
    spriteBatch.Begin();
    clsMyDefenition.DrawPictures(spriteBatch);
    spriteBatch.End();
    // TODO: Add your drawing code here
    base.Draw(gameTime);
} 

我们程序的基础

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    graphics.PreferredBackBufferHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height - 
      System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height/10;
    graphics.PreferredBackBufferWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - 
      System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width/10;
    graphics.ApplyChanges();
    clsMyDefenition.PropertyWindowsScreenHeight = this.Window.ClientBounds.Height;
    clsMyDefenition.PropertyWindowsScreenWidth = this.Window.ClientBounds.Width;
    //It makes the content Default path
    Content.RootDirectory = "Content";
    clsMyDefenition.PropertyContent = Content;
}

以及我们在这里的主要初始化

protected override void Initialize()
{
    // TODO: Add your initialization logic here
    
    clsMyDefenition.InitializeDefenitions();
    //To make mouse visible
    this.IsMouseVisible = true;

    base.Initialize();
}

现在我们的绘制图片函数:

public void DrawPictures(SpriteBatch mybatch)
{
    for (int i = 0; i < mypictures.Length; i++)
    {
        if (mypictures[i].ShouldItBeShownInThisScreen)
        {
            mybatch.Draw(mypictures[i].Texture, mypictures[i].rectangleDestination, 
              Microsoft.Xna.Framework.Color.White);
        }
    }
}

标签的动画引擎

public void DoAnimationFrame(ref picture mypicture)
{
    if (mypicture.ShouldItBeShownInThisScreen)
    {
        if (mypicture.HasItAnimation)
        {
            if (mypicture.IsAnimationOn)
            {
                if (second % mypicture.FramePerSecond == 0)
                {
                    mypicture.strfilename = createFilename(mypicture.OriginalFilenameWithoutIndex, 
                      ref  mypicture, mypicture.TotalAnimationFrame);
                    mypicture.CurentAnimationFrame++;
                }
            }
        }
    }
}

public string createFilename(string OriginalFileName,ref picture mypicture,int TotalAnimationFrame)
{
    mypicture.CurentAnimationFrame++;
    string tempStr = "";
    if (mypicture.CurentAnimationFrame > TotalAnimationFrame) mypicture.CurentAnimationFrame = 1;
    tempStr = OriginalFileName + mypicture.CurentAnimationFrame.ToString();
    return tempStr;
}

为了追踪时间

public int second=0;
public int minute = 0;
public int hour=0;
public int day = 0; 

public void fncGenerateTime()
{
    second++;
    if (second == 60)
    {
        second = 0;
        minute++;
    }
    if (minute == 60)
    {
        minute = 0;
        hour++;
    }
    if (hour == 24)
    {
        day++;
    }
}

关注点

就这样完成了,如果提到任何文章中的不足之处,将会进行更新。

我们看到了如何绘制按钮,为按钮创建鼠标事件,如何为我们的标签创建一些动画,并且还发出了蜂鸣声。MP3 和 wav 文件类型都涵盖了。

是不是很有趣?请评论!

历史  

开始于 2013 年 1 月 23 日。

2013 年 1 月 29 日更新了鼠标事件

© . All rights reserved.