Reputation: 1915
I'm trying to build a blackjack game using C#. I have a casino class and player , card and deck classes which are objects of casino. Casino deals a random card to a player with the function:
public void giveRandomCardTo(Player P)
{
P.takeCard(this.deck.getRandomCard());
}
this works nicely, but then I wanted to add an animation, like a closed card image moves to the player's card picturebox, using a timer. So I added this part to the function:
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());
}
and the Timer.Tick eventhandler of Timer T is:
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();
}
}
Timer works nicely, too. But when I'm dealing cards one after another, I have to wait until the first animation finishes. And the line while(_timerRunning){/*wait*/}
in void giveRandomCardTo
stucks the program in an infinite loop.
How can I make it wait until bool _timerRunning = false
?
Thanks for any help.
Upvotes: 2
Views: 4546
Reputation: 1673
It can be helpful for you - WaitHandle.WaitOne method
There is an example you can reuse/modify
Upvotes: 1
Reputation: 236188
You don't need to wait. Just call your method from Tick
event handler without usage of _timerRunning
flag. Stop timer and give card to player:
T.Stop();
this.MovingCard.Hide();
giveRandomCardTo(this.Players[this.currentDealingID]);
Also I'd created a method IsCardArrivedTo(Point location)
to simplify conditional logic:
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;
}
BTW in C# we use CamelCasing for method names.
Upvotes: 1