Thread: Graphics does not draw over the whole screen

  1. #1
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265

    Graphics does not draw over the whole screen

    I wrote a snake game using WinForms and Graphics object.

    During the game, I draw somewhere on the form, but I've noticed that there is an area on the screen that the Graphics object can't draw there.
    The form doesn't sprawl all over the screen, actually, it's size is 768x565.
    So when I place it at the top-left corner of the screen it works perfectly, but at the center it's kind of cut.

    Look at these:
    When the form is placed at the top-left corner:
    http://img34.imageshack.us/img34/8568/topleftj.jpg

    When the form is placed at the bottom-right corner:
    http://img42.imageshack.us/img42/7048/centerjm.jpg
    You can see that now the snake is cut.

    Please tell me if you know why it happen, thanks.
    gavra.

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    What does your OnPaint() method look like? Are you using the form's ClientRectangle or what?
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I suspect you are in the wrong coordinate space. Please post some of your OnPaint() code or whatever drawing code you have.

  4. #4
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    I'm not using the OnPaint() method to draw the snake, I draw it when the user clicks the 'start new game' button.
    Here's the snake's draw method:
    Code:
            public void Draw()
            {
                foreach (Point organ in organs)
                {
                    graphics.FillRectangle(bodyBrush, new Rectangle(organ, Globals.defaultSize));
                }
            }
    The call is performed from here:
    Code:
            private void newToolStripMenuItem_Click(object sender, EventArgs e)
            {
                ClearPlayground();
                InitializeGame();
                timer1.Start();
            }
    
            private void InitializeGame()
            {
                snake = new Snake();
                food = new Food(graphics);
                key = Keys.Left;
                
                timer1.Interval = Globals.speed.interval;
                score = 0;
                
                ShowScoreDisplay();
                snake.Draw();
                food.Generate(snake.GetOrgans(), lvl.GetBricks());
                food.Draw();
                lvl.Draw();
            }
    I've noticed that it occurs in every form.
    I thought that maybe the origin is set when the CreateGraphics() method is called, but it turned out that it's not the cause.

    It even don't clears the form.
    http://img834.imageshack.us/img834/1663/84771861.jpg
    http://img255.imageshack.us/img255/4193/40720091.jpg
    http://img341.imageshack.us/img341/9731/52607813.jpg
    http://img291.imageshack.us/img291/3906/81947994.jpg
    gavra.

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You should do all drawing in OnPaint(). Otherwise when the window is resized and/or altered in someway you will be forced to call OnPaint(). Since the OnPaint() is automatically called during these events by WinForms if you override it you won't have to account for these specific cases.

    Remember that most coordinates in WinForms are in local coordinates or are relative to the upper left corner of the parent form. The exception to this rule is the Cursor position which is in screen coordinates. Also keep in mind that you can use PointToClient() and PointToScreen() to convert from screen coordinates to client coordinates (coordinates relative to the upper left corner of the parent form) and vice versa.

    So for instance if we have a text box inside of a form and the text box is at the upper left corner of the form the text box location is 0,0 regardless of the form's actual screen position. I cannot verify this next statement but given my experience with forms it appears that Position refers to screen coordinates and Location refers to local coordinates.

    Use Console.WriteLine() to output your drawing coordinates. I think you will find that they are way off of your form. Your drawing coordinates should be within the form's ClientRectangle. Keep in mind as well that various mouse event handlers and form event handlers pass coordinates in and they are usually, but not always, in local coordinates or client coordinates.
    This may mean in some mouse event handlers you might have to do some coordinate space conversion using the functions I mentioned in order to get everything to appear correct and behave correctly.

    So from my point of view you have two distinct unrelated problems:
    • Your painting is not appearing at times
    • Your painting is not in the right location in the form.


    My approach would be to forget the coordinates for now and simply override the OnPaint() and either put your drawing code in there or call out to your current Draw method. This will most likely fix your lack of painting issues. After that you can tackle the coordinate space issues. WinForms programming can be a pain but you can make it simpler by understanding the exact problems and if they are related or not. Sometimes a simple change in structure or change in method call order fixes everything. I would recommend buying a book but most of them are for .NET 2.0 and are older b/c MS has now recommended devs move to WPF.
    Last edited by VirtualAce; 01-08-2011 at 12:00 PM.

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    You need to connect a drawing method to the Paint event for the form, that redraws the snake and everything when it is called. What happends is that every time you move a window, resizes it or whatever it has to be redrawn, but since you dont redraw it will just clear it and it will appear like nothing is working.

    Edit: Bubba gave a more indepth reason what the problem is but I would strongly suggest that instead of overriding OnPaint connect a handler to Paint event.
    Last edited by Shakti; 01-08-2011 at 12:03 PM.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    What Shakti has mentioned is another approach so that you do not have to completely refactor your code. Either way you need to make sure that when WM_PAINT comes in to the WndProc of your form that your form paints itself using your drawing code. This will fix a whole host of drawing issues. His approach is a better one and requires less re-factoring of your existing code.

  8. #8
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    Oh, thanks.
    But I draw the snake when the user clicks the 'start new game' button. How can I now draw it from the Paint method? Should I set a Boolean variable as true when he click the button, and check the variable in the Paint method, draw and set it as false?
    gavra.

  9. #9
    Registered User
    Join Date
    Mar 2009
    Location
    england
    Posts
    209
    But I draw the snake when the user clicks the 'start new game' button. How can I now draw it from the Paint method?
    Force a redraw by using control.Invalidate() or control.Invalidate(specific_bounds).

  10. #10
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    what do you mean?
    gavra.

  11. #11
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    You draw the snake like you always draw it, based on its location and so on. It isn't enough to draw the snake once and then change the variables that you use to keep track of the snake, each time you change one of these variables you want to redraw the snake.

    Just like you connect a drawing method to the Paint event you can connect methods for KeyDown events. Control.KeyDown Event (System.Windows.Forms)

  12. #12
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    So I need to redraw the whole snake?
    I didn't connect any drawing method to any paint event.
    The link is invalid.
    gavra.

  13. #13
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Yes you need to redraw the whole snake. And you need to connect a handler to the Paint event.

    Funny, the link works for me, oh well just google "Paint event C#" and "KeyDown event C#", will give you good reading-material.

  14. #14
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    So do I need to do something like that:?
    Code:
    Form1_Paint()
    {
              if (onGame)
                   snake.Draw();       
    ...  
    }
    thanks.
    gavra.

  15. #15
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Yes, something along those lines would be a good start.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Feedback: Functional Specification Wording
    By Ragsdale85 in forum C++ Programming
    Replies: 0
    Last Post: 01-18-2006, 04:56 PM
  2. SDL segfault when trying to draw to screen
    By Blizzarddog in forum Game Programming
    Replies: 2
    Last Post: 12-09-2005, 07:53 AM
  3. draw function HELP!!!
    By sunoflight77 in forum C++ Programming
    Replies: 1
    Last Post: 05-10-2005, 11:28 PM
  4. saving screen to file
    By z0diac in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 02-23-2003, 07:00 PM
  5. Text on Graphics screen
    By bob5845 in forum C++ Programming
    Replies: 4
    Last Post: 04-03-2002, 09:08 PM