Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. Getting rid of lag with pictureBox

Getting rid of lag with pictureBox

Scheduled Pinned Locked Moved .NET (Core and Framework)
csharpc++game-devhelpquestion
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    pcxboy
    wrote on last edited by
    #1

    Hello, I am currently trying to develop a video game using .NET C++. The one thing I am having trouble with is when I move (with a Key_Down event) a pictureBox with an image set, there is always a lag, and thus a piece of the image's last position always appears. How would I get rid of this?? I had tried making it invisible, changing the pictureBox's location, then making it visible again, but that makes the image blink as it moves. Any help would be greatly appreciated. Thank you.:-D Michael

    R 1 Reply Last reply
    0
    • P pcxboy

      Hello, I am currently trying to develop a video game using .NET C++. The one thing I am having trouble with is when I move (with a Key_Down event) a pictureBox with an image set, there is always a lag, and thus a piece of the image's last position always appears. How would I get rid of this?? I had tried making it invisible, changing the pictureBox's location, then making it visible again, but that makes the image blink as it moves. Any help would be greatly appreciated. Thank you.:-D Michael

      R Offline
      R Offline
      Robert Rohde
      wrote on last edited by
      #2

      Hi, in a video game you shouldn't use a picture box. Remove it and paint the bitmap yourself onto the form/control/whatever by overriding the Paint method (don't forget to call the base implementation) and calling e.Graphics.DrawImage. This should be by far faster than the picturebox.

      P 1 Reply Last reply
      0
      • R Robert Rohde

        Hi, in a video game you shouldn't use a picture box. Remove it and paint the bitmap yourself onto the form/control/whatever by overriding the Paint method (don't forget to call the base implementation) and calling e.Graphics.DrawImage. This should be by far faster than the picturebox.

        P Offline
        P Offline
        pcxboy
        wrote on last edited by
        #3

        Hey thanks, I tried that and it worked a lot better, however the image still jumps and is blurry as I move it. Would there be a way to get rid of that? I know that in java they use a buffering strategy, however I do not know how to do that in .NET C++. Thanks for the help so far. Michael

        R 1 Reply Last reply
        0
        • P pcxboy

          Hey thanks, I tried that and it worked a lot better, however the image still jumps and is blurry as I move it. Would there be a way to get rid of that? I know that in java they use a buffering strategy, however I do not know how to do that in .NET C++. Thanks for the help so far. Michael

          R Offline
          R Offline
          Robert Rohde
          wrote on last edited by
          #4

          (I'll use C# syntax as Im not very familiar with C++) A simple double buffering can be enabled by adding this in the constructor of your form/control:

          SetStyle(ControlStyles.UserPaint, true);
          SetStyle(ControlStyles.AllPaintingInWmPaint, true);
          SetStyle(ControlStyles.DoubleBuffer, true);

          Does your image have the correct size or do you resize it while painting? If it has already the correct size use the DrawImageUnscaled function. If not resize it somewhere in the beginning:

          Bitmap resizedBitmap = new Bitmap(wantedWidth, wantedHeight);
          Graphics g = Graphics.FromImage(resizedBitmap);
          g.DrawImageUnscaled(oldBitmap, 0, 0, wantedWidth, wantedHeight);
          g.Dispose();
          //resizedBimtap is ready to use

          EDIT: You should also search for 'double buffering' here on CodeProject. There are some articles which might be interesting for you.

          P 1 Reply Last reply
          0
          • R Robert Rohde

            (I'll use C# syntax as Im not very familiar with C++) A simple double buffering can be enabled by adding this in the constructor of your form/control:

            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);

            Does your image have the correct size or do you resize it while painting? If it has already the correct size use the DrawImageUnscaled function. If not resize it somewhere in the beginning:

            Bitmap resizedBitmap = new Bitmap(wantedWidth, wantedHeight);
            Graphics g = Graphics.FromImage(resizedBitmap);
            g.DrawImageUnscaled(oldBitmap, 0, 0, wantedWidth, wantedHeight);
            g.Dispose();
            //resizedBimtap is ready to use

            EDIT: You should also search for 'double buffering' here on CodeProject. There are some articles which might be interesting for you.

            P Offline
            P Offline
            pcxboy
            wrote on last edited by
            #5

            the C# syntax isn't that different (I just used :: instead of .) however the buffer didn't appear to do anything. I guess it isn't possible to get rid of the flicker when painting an image, however I still do not know how it is done in java, but can't be done in .NET C++. Also, did you mean to make a paint event for the form, and then e->Graphics->DrawImage it, because that is what I did. Anyways, thanks again for the help. Michael

            R 1 Reply Last reply
            0
            • P pcxboy

              the C# syntax isn't that different (I just used :: instead of .) however the buffer didn't appear to do anything. I guess it isn't possible to get rid of the flicker when painting an image, however I still do not know how it is done in java, but can't be done in .NET C++. Also, did you mean to make a paint event for the form, and then e->Graphics->DrawImage it, because that is what I did. Anyways, thanks again for the help. Michael

              R Offline
              R Offline
              Robert Rohde
              wrote on last edited by
              #6

              No I meant overriding the OnPaint method of the form (but that shouldn't make a difference). I made a simple text which work fine for me (when the image is very big it slows down). Probably it helps you:

              public class Form1 : System.Windows.Forms.Form
              {
              private Point _curPos = new Point(0, 0);
              private Image _image;

              public Form1()
              {
              	base.KeyPress += new KeyPressEventHandler(Form1\_KeyPress);
              	SetStyle(ControlStyles.UserPaint, true);
              	SetStyle(ControlStyles.AllPaintingInWmPaint, true);
              	SetStyle(ControlStyles.DoubleBuffer, true);
              	\_image = new Bitmap("C:\\\\test2.jpg");
              }
              
              private void Form1\_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
              {
              	switch (e.KeyChar)
              	{
              		case 'w': \_curPos.Y -= 5; break;
              		case 's': \_curPos.Y += 5; break;
              		case 'a': \_curPos.X -= 5; break;
              		case 'd': \_curPos.X += 5; break;
              	}
              	Invalidate();
              }
              
              protected override void OnPaint(PaintEventArgs e)
              {
              	base.OnPaint (e);
              	e.Graphics.DrawImageUnscaled(\_image, \_curPos);
              }
              

              }

              Note that I'm calling the Invalidate method instead of Refresh. This is always better because the Refresh will repaint the form immediatly while Invalidate will wait until there is time to do so. If you have much more other things on your form it would also be a good idea to give a Rectangle into the form which specifies which particular region should be repainted.

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups