首页 > 解决方案 > WinForms (C#) 仅通过 Timer 每隔一个循环更新 PictureBoxes

问题描述

我正在使用 C# 中的 WinForms 开发视频扑克风格的街机游戏。当玩家点击“发牌”按钮时,表单上的 5 个图片框从正面朝下的卡片图像切换为正面朝上的卡片图像。我可以毫不费力地让它们同时翻转,但我希望每张卡片之间有一点延迟,以便它们从左到右显示。

我从 Microsoft .NET 官方文档(本页的第二个示例)中找到了一个示例,它使用 Timer 的方式只会循环一定次数,非常适合我,因为我只想翻转 5 张卡片.

但是,当我在游戏中使用该示例时,会发生一些奇怪的事情。卡片从左到右成对显示两张,而不是一次一张。当我设置断点并逐步执行时,我的计数器确实增加了 1,但表单仅在每隔一次通过时更新图像。

为什么会这样?我能做些什么来解决它?

交易按钮点击:

private void dealdraw_button1_Click(object sender, EventArgs e)
{
  // If we are dealing a new hand...
  if (dealPhase == "deal")
  {
    // Change game phase
    dealPhase = "draw";

    // Generate a new deck of cards
    deck = new Deck();

    // Shuffle the deck
    deck.Shuffle();

    // Deal five cards to the player
    playerHand = deck.DealHand();

    // Start timer loop
    InitializeTimer();

    // Enable "Hold" buttons
    for (int i = 0; i < 5; i++)
    {
      playerHoldButtons[i].Enabled = true;
    }
  }
}

初始化定时器():

private void InitializeTimer()
{
  counter = 0;
  timer1.Interval = 50;
  timer1.Enabled = true;
  // Hook up timer's tick event handler.  
  this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
}

Timer1_Tick:

private void timer1_Tick(object sender, EventArgs e)
{
  if(counter >= 5)
  {
    // Exit loop code
    timer1.Enabled = false;
    counter = 0;
  }
  else
  {
    playerHandPictureBoxes[counter].Image = cardFaces_imageList1.Images[playerHand[counter].imageListIndex];
    counter = counter + 1;
  }
}

标签: c#winformstimer

解决方案


InitializeTimer 方法中的问题。罪魁祸首是您在每次点击中一次又一次地添加 Tick 事件处理程序。

public partial class Form1 : Form
{
    PictureBox[] playerHandPictureBoxes = new PictureBox[5];
    int counter = 0;
    public Form1()
    {
        InitializeComponent();
        CreateCards();
    }
    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void CreateCards()
    {
        int pWidth = 50;
        int left = 10;
        for (int i = 0; i < playerHandPictureBoxes.Length; i++)
        {
            playerHandPictureBoxes[i] = new PictureBox
            {
                Top = 10,
                Left = left + (left * i) + (i * pWidth),
                BackColor = Color.Red,
                Width = pWidth,
                Height = 50,
                BackgroundImage = imageList1.Images[0],
                BackgroundImageLayout = ImageLayout.Stretch
            };
        }

        this.Controls.AddRange(playerHandPictureBoxes);
    }

    private void InitializeTimer()
    {
        counter = 0;
        timer1.Interval = 500;
        timer1.Enabled = true;
        // Detach any previouly added event handlers
        this.timer1.Tick -= Timer1_Tick;
        // Hook up timer's tick event handler.  
        this.timer1.Tick += Timer1_Tick;

    }

    private void Timer1_Tick(object sender, EventArgs e)
    {
        if (counter >= 5)
        {
            // Exit loop code
            timer1.Enabled = false;
            counter = 0;
        }
        else
        {
            playerHandPictureBoxes[counter].BackgroundImage = imageList1.Images[1];
            counter += 1;
        }
    }

    private void btnDeal_Click(object sender, EventArgs e)
    {
        InitializeTimer();

        // Enable "Hold" buttons
        //for (int i = 0; i < 5; i++)
        //{
        //    playerHoldButtons[i].Enabled = true;
        //}
    }
}

推荐阅读