如何打开和关闭生成的按钮?

时间:2019-10-10 19:10:24

标签: c#

我正在尝试用C#制作Wack-A-Mole游戏。到目前为止,我所做的是使一个按钮生成一个按钮网格作为比赛场地。游戏的要点是单击已激活的按钮以获取要点。现在,我卡住的是(如标题所示)进行制作,以便一旦我单击“开始”,一个按钮将保持活动状态,而其他所有按钮将被禁用。

到目前为止,这是我的代码:

replies()

2 个答案:

答案 0 :(得分:0)

您可以使用Enabled property来确定哪些Button处于打开状态,哪些Button处于关闭状态。

如果一次只需要一个Button处于活动状态,一种简单的解决方法可能是在Form1类中添加一些字段。

  • 一个System.Collections.Generic.List<Button>,用于存储您在Form1.GenerateButton内部创建的所有按钮。例如,我们可以称其为_buttons
  • 一个Button用于存储当前选择的按钮。例如,我们可以称其为_enabledButton
  • 一个Random生成随机数,因此您可以随机选择一个按钮。例如,我们可以称其为_rng

确保在GenerateButton内设置button.Enabled = false,然后将button添加到_buttons字段中。

然后将方法添加到Form1,例如ActivateRandomButton,该方法可以执行以下操作...

private void ActivateRandomButton()
{
   if (_enabledButton != null)
   {
      // If one of the buttons is already enabled, disable it.
      _enabledButton.Enabled = false;
   }

   // Randomly select a button that you've created and enable it.
   _enabledButton = _buttons[_rng.Next(0, _buttons.Count)];
   _enabledButton.Enabled = true;
}

现在,在生成所有Button之后,您可以调用ActivateRandomButton将其中之一打开。您最终可能会添加一个Timer,并且可以在ActivateRandomButton事件中调用Tick

请注意,这是一种非常简单的方法。它存在一些问题,例如,一次始终只有一个并且只有一个按钮处于活动状态。自玩过Whack-a-Mole游戏以来已经很长时间了,但我觉得一次可能有多个痣“活跃”,甚至一次可能有零个痣“活跃”。希望这个答案能给您一些起点和基础。

答案 1 :(得分:0)

根据我的评论-请注意,此代码是未经测试的,甚至可能无法编译,因为我在用手机:

namespace Whack_a_mole
{
    public partial class Form1 : Form
    {
        private Random _rng = new Random(); //used to determine mole sleep and wake times
        private Timer _t = new Timer(); //ticks ever 0.1 s
        private List<Button> _buttons = new List<Button>(); //track our mole buttons

        public Form1()
        {
            InitializeComponent();
            label1.Visible = false;
            label1.Text = "Max size is 5";
            _t.Interval = 100;
            _t.Click += Timer_Tick;
        }

        private void StartButton_Click(object sender, EventArgs e)
        {
            _t.Start(); //start the timer

        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            //every 0.1 s we scan the board poke every mole
            foreach(Button b in _buttons){
              b.Enabled = (b.Tag as Mole).IsAwake(); //isawake will sometimes wake a mole up or put it to sleep if we didnt whack it soon enough
              if(b.Enabled) //if the mole is awake
                b.BackColor = Color.Red; //red tbuton = awake mole
              else
                b.BackColor = Color.Gray; //sleeping mole
            }
        }

        private void MoleButton_Click(object sender, EventArgs e)
        {
            Button b = (sender as Button); //many buttons share this handler; which button was clicked?
            Mole m = (b.Tag as Mole); //get the mole for that button
            m.Whack(); //whack it - puts to sleep and resets the sleep timer
            b.Enabled = false; //turn this button off
            b.BackColor = Color.Gray;
            b.Text = m.WhackCounter.ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int Area = Convert.ToInt32(textBox1.Text);
            if (Area < 6)
            {
                GenerateGrid(20, 20, Area, Area, 75, 75);
            } else
            {
                label1.Visible = true;
            }

        }

        private void GenerateGrid(int gridleft, int gridtop, int horizontalCount, int verticalcount, int width, int height)
        {
            for (int i = 0; i < verticalcount; i++)
            {
                GenerateRowOfButtons(gridleft, gridtop+height*i, horizontalCount, width, height);
            }
        }

        private void GenerateRowOfButtons (int startX, int startY, int count, int width, int height)
        {
            for (int i = 0; i < count; i++)
            {
                GenerateButton(startX+i*width, startY, width, height);
            }
        }

        private void GenerateButton (int x, int y, int width, int height)
        {
            Button button = new Button();
            button.Width = width;
            button.Height = height;
            button.Left = x;
            button.Top = y;
            button.Tag = new Mole(_rng); //associate a mole with the button
            button.BackColor = Color.Gray;
            button.Enabled = false;
            button.Click += MoleButton_Click; //all mole buttons handled by the smae click handler
            this.Controls.Add(button);
        }


    }
}

  //mole is a thing that has a counter, we decrement every 0.1 seconds by asking IsAwake()
 // the mole may wake up, and it is awake for another random time then sleeps again
  class Mole{

    //count the whacks. will put this on a button text hence public
    public int WhackCounter{get; set;}=0;
    private int _counter = 0; //this tracks how long the mole sleeps / wakes for
    private Random _r;
    private bool _awake = false; //this toggles every time the counter hits 0

    public Mole(Random r){
      _r = r;
      _counter = r.Next(1,100) //init to a random sleep time
    }

    public void Whack(){
      WhackCounter++; //up the whacks
      _counter = r.Next(10,100); //at tenths of a second it sleeps for 1 to 10 seconds
      _awake = false; //put to sleep
    }

    public bool IsAwake(){ //this method decrements the counter then returns if the mole is awake
      _counter--;
      if(_counter < 1){ //did we hit 0? cycle the mole state and re-randomize
        //toggle state
        _awake = !_awake;
        if(_awake)
          _counter = r.Next(20,50); //moles wake for between 2 and 5 seconds
        else
          _counter = r.Next(10,100);
      }
      return _awake;
    }
  }