Click here to Skip to main content
15,867,141 members
Articles / Game Development

Guess My Drawing!

Rate me:
Please Sign up or sign in to vote.
4.87/5 (21 votes)
9 Jan 2013CPOL3 min read 47.6K   697   34   15
A Windows Forms application to share a whiteboard with many clients with only one drawer, in a gamy way.

Introduction

This piece of code represents a windows application, it is basically a whiteboard sharing service between users using another code as a server; it consists of a whiteboard that’s shared between many people, one as a drawer and the others as guessers. The drawer is the guy who can draw on the white board, while the guessers are the people who receive the drawings and try to guess it. The first one, the drawer, writes a word describes what he’s drawing, without the guessers knowing it, then he starts to draw and the guessers try to guess the drawing, and the games goes on. The code is coded using C# and data are transferred using UDP.

Clients can log in by choosing any name they like and the server's IP. 

Using the code 

There're two code files, the server and the client one.

The Server:

It's a console application that adds clients to its list, and receives UDP messages from clients analyse them and forward/unforward them to other clients. For example, if a guesser guessed a word, other guessers will be notified of this in a text box, another example is the secret word of the drawing, it will not be forwarded to other clients but kept in the server to be checked with each guess.

Image 1

The Client: 

This solution has two classes, the windows from class, and the panel class.

The windows form class is called Form1, a silly name! But it kinda meant something as it was my first C# project.

Anyway, the class consists of four methods to capture the clicks of the four buttons in the interface.

Image 2

Image 3

And it has two background threads, read() and DrawOnPanel().

First the read() method, it is for reading from the UPD connection after the user joins as a drawer or guesser.

C#
public void read()
{
    Thread t = new Thread(new ThreadStart(delegate
    {
        while(!abortThreads)
        {
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = {0};
            try
            {
                data = client.Receive(ref remoteEP);
                msg = Encoding.ASCII.GetString(data, 0, data.Length);

            }
            catch (SocketException e)
            {
                abortThreads = true;
            }

            if (msg.StartsWith("draw"))
            {
                msg = msg.Substring(5);
                int xVal = 0, yVal = 0;
                for (int i = 0; msg.Length - 1 > 0; i++)
                {
                    if (msg.Substring(i, 1) == "y")
                    {
                        xVal = Int32.Parse(msg.Substring(0, i));
                        msg = msg.Substring(i + 1);
                        i = 0;
                    }

                    if (msg.Substring(i, 1) == "x")
                    {
                        yVal = Int32.Parse(msg.Substring(0, i));
                        msg = msg.Substring(i + 1);
                        toDraw.Add(new Point(xVal, yVal));
                        i = 0;
                    }
                }
                startDrawing = true;
            }

            else if (msg.StartsWith("accept"))
                SetText(Encoding.ASCII.GetString(data, 0, data.Length));

            else if (msg.StartsWith("gues"))
            {
                if (msg.EndsWith("true"))
                    SetText(msg.Substring(5, msg.Length - 9) + " which was RIGHT! ");
                if (msg.EndsWith("false"))
                    SetText(msg.Substring(5, msg.Length - 10) + " which was WRONG! ");
            }

            else if (msg.StartsWith("quit"))
            {
                msg = "quit";
                data = Encoding.ASCII.GetBytes(msg);
                client.Send(data, data.Length);
                client.Close();
                SetText("The drawer quitted, the game is finished! ");
                abortThreads = true;
                Thread.CurrentThread.Abort();
            }
            else
            {
                if(msg.Length > 5) 
                    SetText(msgList.Text + Environment.NewLine + 
                      Encoding.ASCII.GetString(data, 4, data.Length - 4));
            }
        }
    }));
    t.IsBackground = true;
    t.Start();
}

It basically waits for a message using the receive method for the UDP, and then encode it to a string, msg, and then goes and checks for its content in a series of an if-else statements.

The second thread, DrawOnPanel(), draws whenever there's a draw message, and it's controlled by a boolean variable in the read() thread named startDrawing

C#
private void DrawOnPanel()
{
    hwnd = thePanel.Handle;
    Thread t0 = new Thread(new ThreadStart(delegate
        {
            using (Graphics graphics = Graphics.FromHwnd(hwnd))
            {
                while (!abortThreads)
                {
                    if(startDrawing)
                    if (toDraw.Count > 0)
                    {
                        object holder = toDraw[0];
                        Point now = (Point)holder, previous = (Point)holder;
                        for (int i = 0; i < toDraw.Count; i++)
                        {
                            holder = toDraw[i];
                            now = (Point)holder;
                            graphics.DrawLine(MyPanel.p, now, previous);
                            previous = now;
                        }
                        Console.WriteLine(now + "  last  " + previous);
                        startDrawing = false;
                        toDraw.Clear();
                    }
                }
            }
        }));

    t0.IsBackground = true;
    t0.Start();
} 

.. 

And that's it for the Form1 class, other methods can be found in the source code. 

The panel class is called MyPanel and  it overrides the Panel class.

public class MyPanel : Panel and it overrides three mouse events methods, OnMouseDown()OnMouseUp(), and OnMouseMove() methods.

I'll go through them one by one. 

The first method, OnMouseDown()  has only one line, just to set a boolean value to true to indicate that we can start taking the points and store them in case of a drawer. 

C#
protected override void OnMouseDown(MouseEventArgs e)
{
    mouse_down = true;
}

and the third method, OnMouseMove(), stores the points in an arraylist to be sent. 

C#
protected override void OnMouseMove(MouseEventArgs e)
{
    if (Form1.isDrawer)
    {
        if (last_point.Equals(Point.Empty))
            last_point = new Point(e.X, e.Y);
        if (mouse_down)
        {

            IntPtr hwnd = this.Handle;

            using (Graphics graphics = Graphics.FromHwnd(hwnd))
            {
                Point pMousePos = new Point(e.X, e.Y);
                graphics.DrawLine(p, pMousePos, last_point);
                Console.WriteLine(pMousePos + "  last  " + last_point);
                pointss.Add(pMousePos);
            }
        }
        last_point = new Point(e.X, e.Y);
    }
} 

And the second method, OnMouseUp(), will convert the arraylist into a string and then into bytes and send them via the established UPD connection.

C#
protected override void OnMouseUp(MouseEventArgs e)
{
    mouse_down = false;
    if (Form1.isDrawer)
    {
        string msg = "draw";
        for (int i = 0; i < pointss.Count; i++)
        {
            Point poi = (Point)pointss[i];
            msg += ("x" + poi.X + "y" + poi.Y);
        }
        msg += "x";
        pointss.Clear();
        byte[] data = Encoding.ASCII.GetBytes(msg);
        if (client != null)
            client.Send(data, data.Length);
    }
}

That sums up the main ideas of the tool, any questions about the code are welcomed. 

Points of Interest 

Some things I did in a strange way to get with my tool, you may think they are fun or creative, but eventually they worked stunningly! Here are some: 

- There's no free drawing capability in C#, so my trick was to draw small lines to make it look like a free drawing style.

- I convert the line points in the arraylist into a string to send them via the UDP connection easily.

Drawing on the panel was a headache without calling the Paint() method! I was only drawing in a small portion of the panel, so I used the tricky way in the DrawOnPanel() method that I developed to get rid of the problem, with the help of this question thread in Stackoverflow website:

The Reference.

 

 Conclusion

And by this I conclude my very first online article, if you have any feedback, questions, ideas or any comments, please do speak, it'd be my pleasure to hear all what is going on in your creative minds. 

History 

null; 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
Codes > Bio

Comments and Discussions

 
GeneralMy vote of 5 Pin
Member 38528545-Apr-13 9:00
Member 38528545-Apr-13 9:00 
GeneralMy vote of 5 Pin
Member 38528545-Apr-13 9:00
Member 38528545-Apr-13 9:00 
GeneralMy vote of 5 Pin
Anurag Gandhi13-Jan-13 20:22
professionalAnurag Gandhi13-Jan-13 20:22 
Nice One!!
GeneralMy vote of 5 Pin
Wasifa2510-Jan-13 6:53
Wasifa2510-Jan-13 6:53 
GeneralMy vote of 4 Pin
Savalia Manoj M9-Jan-13 16:37
Savalia Manoj M9-Jan-13 16:37 
GeneralMy vote of 5 Pin
Ahsan Murshed9-Jan-13 16:11
Ahsan Murshed9-Jan-13 16:11 
Generalyou have done efforts on nice subject Pin
Aarti Meswania8-Jan-13 17:37
Aarti Meswania8-Jan-13 17:37 
GeneralRe: you have done efforts on nice subject Pin
Albara Hakami9-Jan-13 8:49
Albara Hakami9-Jan-13 8:49 
QuestionMissing reference Pin
Hezek1ah29-Dec-12 14:36
Hezek1ah29-Dec-12 14:36 
GeneralMy vote of 5 Pin
gaga blues27-Dec-12 19:26
gaga blues27-Dec-12 19:26 
GeneralRe: My vote of 5 Pin
Albara Hakami27-Dec-12 23:28
Albara Hakami27-Dec-12 23:28 
GeneralMy vote of 5 Pin
Ravi Bhavnani27-Dec-12 14:33
professionalRavi Bhavnani27-Dec-12 14:33 
GeneralRe: My vote of 5 Pin
Albara Hakami27-Dec-12 14:36
Albara Hakami27-Dec-12 14:36 
GeneralMy vote of 5 Pin
Venkatesh Mookkan26-Dec-12 16:53
Venkatesh Mookkan26-Dec-12 16:53 
GeneralRe: My vote of 5 Pin
Albara Hakami26-Dec-12 23:02
Albara Hakami26-Dec-12 23:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.