2

我正在尝试使用 C# 构建二十一点游戏。我有一个赌场类和 player 、 card 和 deck 类,它们是赌场的对象。赌场向具有以下功能的玩家发一张随机牌:

        public void giveRandomCardTo(Player P)
        {
            P.takeCard(this.deck.getRandomCard());
        }

这很好用,但后来我想添加一个动画,比如使用计时器将封闭的卡片图像移动到玩家的卡片图片框。所以我将这部分添加到函数中:

public void giveRandomCardTo(Player P)
        {
            while (_timerRunning) {/*wait*/ }
            this.currentDealingID = P.id;
            if (this.currentDealingID >= 0 && this.currentDealingID < this.NumberOfPlayers && this.currentDealingID!=10) 
            {//Checking the current player is not the dealer.
                this.MovingCard.Show(); //Moving card is a picture box with a closed card
                _timerRunning=true;
                T.Start();
            }
            P.takeCard(this.deck.getRandomCard());    
        }

Timer T 的 Timer.Tick 事件处理程序是:

public void TimerTick(object sender, EventArgs e)
{
              movingcardvelocity = getVelocityFromTo(MovingCard.Location, this.Players[this.currentDealingID].CardPBS[0].Location);
              double divide=5;
              movingcardvelocity = new Point((int)(movingcardvelocity.X / divide), (int)(movingcardvelocity.Y / divide));
              this.MovingCard.Location = new Point(this.MovingCard.Location.X + movingcardvelocity.X, this.MovingCard.Location.Y + movingcardvelocity.Y);
//Stop if arrived:
              double epsilon = 20;
              if (Distance(this.MovingCard.Location, this.Players[this.currentDealingID].CardPBS[0].Location) < epsilon) 
    {
    _timerRunning=false;  
    this.MovingCard.Hide();
    T.Stop();
    }
}

定时器也很好用。但是当我一个接一个地发牌时,我必须等到第一个动画完成。并且中的while(_timerRunning){/*wait*/}行将void giveRandomCardTo程序卡在无限循环中。

我怎样才能让它等到bool _timerRunning = false

谢谢你的帮助。

4

2 回答 2

1

它可能对您有所帮助 - WaitHandle.WaitOne方法

有一个可以重用/修改的例子

于 2012-12-07T12:20:20.923 回答
1

你不需要等待。只需从事件处理程序调用您的方法Tick而不使用_timerRunning标志。停止计时器并将卡片交给玩家:

T.Stop(); 
this.MovingCard.Hide();
giveRandomCardTo(this.Players[this.currentDealingID]);

我还创建了一种IsCardArrivedTo(Point location)简化条件逻辑的方法:

public void TimerTick(object sender, EventArgs e)
{
     var player = Players[currentDealingID];
     Point pbsLocation = player.CardPBS[0].Location;
     MoveCard();

     if (IsCardArrivedTo(pbsLocation)) 
     {        
        MovingCard.Hide();
        T.Stop();
        giveRandomCardTo(player);
     }
}

private bool IsCardArrivedTo(Point location)
{
    double epsilon = 20;
    return Distance(MovingCard.Location, location) < epsilon;
}

private void MoveCard()
{
   // calculate new location
   MovingCard.Location = newLocation;
}

顺便说一句,在 C# 中,我们使用 CamelCasing 作为方法名称。

于 2012-12-07T12:22:30.757 回答