65.9K
CodeProject is changing. Read more.
Home

Dartboard User Control in C#

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (15 votes)

Oct 27, 2003

2 min read

viewsIcon

97402

downloadIcon

2835

Shows a dartboard on which you can click and which returns the score thrown

Introduction

When I play darts with my friends at home we have a laptop with us to hold scores and statistics. We used Excel to do the job, but I was encouraged to build a more sophisticated solution. So, I came up with the idea to click on a dartboard picture to calculate the scores thrown and the statistics. So this article shows the usercontrol and the delegates/events I used.

Using the code

There are 2 interesting parts in this challenge:

  • How to determine the score based on a click somewhere on the dartboard;
  • Using delegates and events;

For the first part I used the middle of the bull (that is the middle of the picture) as my base point (0,0). Since I know the X and Y coordinate I can calculate the degrees by using the atan() function.

double  dblHoekInRadians  = System.Math.Atan2(  posY ,  posX  );
double  dblHoekInGraden  = dblHoekInRadians * 180 / System.Math.PI;

When I know the degrees I know which number was clicked. The dartboard has 20 slices of equal size. So, each slice is of 360 / 20 = 18 degrees. Remember, the middle is my base, so number 13 is between 9 and 27 degrees and number 4 is between 27 and 45.

The next thing to do is to check which ring was clicked (bull, triple, double or else just single). I calculated the distince from the base (0,0) to the clicked X,Y coordinate. Now, the Pythagoras guy is entering our life!

double  dblLengte  = System.Math.Sqrt(  posX * posX  +  posY * posY );
int  intLengte  = (int)System.Math.Floor(  dblLengte  );

Well, this was the hard part.

The next thing is to develop some events to be raised. I chose to have 4 events: NoScoreThrown, SingleScoreThrown, DoubleScoreThrown and TripleScoreThrown. I declared them like this:

public event NoScoreThrownEventHandler  NoScoreThrown ;
protected virtual void OnNoScoreThrown( DartbordEventArgs  e  )
{
  if(  NoScoreThrown  != null )
  {
    NoScoreThrown( this,  e  );
  }
}

For these events I used 4 delegates:

//Declare the delegates for each event
public delegate void NoScoreThrownEventHandler( object  sender , 
  DartbordEventArgs  e  );
public delegate void SingleThrownEventHandler( object  sender , 
  DartbordEventArgs  e  );
public delegate void DoubleThrownEventHandler( object  sender , 
  DartbordEventArgs  e  );
public delegate void TripleThrownEventHandler( object  sender , 
  DartbordEventArgs  e  );

I also defined my own EventArgs with specific data about the scores and throws.

  /// <SUMMARY>
  /// Holds data about the score and throw
  /// </SUMMARY>
  public class  DartbordEventArgs  : EventArgs
  {
    private readonly int  mintScore ;
    private readonly string  mstrScore ;
    private readonly int  mintThrow ;

    //Constructor
    public DartbordEventArgs( int  Score , string  ScoreText , int  Throw  )
    {
      this.mintScore =  Score ;
      this.mstrScore =  ScoreText ;
      this.mintThrow =  Throw ;
    }

    #region Properties
    public int  Score 
    {
      get
      {
        return mintScore;
      }
    }

    public string  ScoreText 
    {
      get
      {
        return mstrScore;
      }
    }

    public int  Throw 
    {
      get
      {
        return mintThrow;
      }
    }
    #endregion

  }

Based on the score thrown I raise the right event. I used a class variable (boolean) to know whether I hit a single, double, triple or noscore.

//Raise the event(s)
DartbordEventArgs  dea  = new DartbordEventArgs(  mintScore ,  
  mstrScoreText ,  mintThrow  );

if(  mIsTriple  ) OnTripleThrown( dea );
if(  mIsDouble  ) OnDoubleThrown( dea );
if(  mIsSingle  ) OnSingleThrown( dea );
if(  mIsNoScore  ) OnNoScoreThrown( dea );

That's basically it. Have fun!