Need Help with Double Buffer in C#
To give a little story:
I'm using the Visual Studio C# 2008 Express Edition.
I'm making a chess based game. With the double buffering off on the form it draws great except for the flicker. However when I turn Double Buffering on for the form nothing shows at all. I have an OnPaint that I use in place of the regular Paint.
There is an event handler that calls OnPaint when the form is clicked. When I click I see the board flash really quick and then go right back to the background color.
I treid removing my OnPaint and going with the regular Paint and then nothing shows on the screen at all.
Basically my question is to get the double buffering to work from turning it on the form what do I need to do in the program itself? Do I need to use the the Setstyles and if so which ones? I can easily move any of the drawing methods if need be.
Any help is appreciated. Thanks in advance.
Ok here is Form1.cs
To make it easier to find here are the high points:
Any suggestions or do you need the other code like FormDesigner.cs?
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Collections;namespace Chess{ public partial class Form1 : Form { const int SQWIDTH = 80; const int SQHEIGHT = 80; bool shipSelection = true; bool shipMove = false; Rectangle sqSize = new Rectangle(0, 0, 75, 75); Board gameBoard = new Board(); Ship selectedShip = new Ship(); List<Ship> shipList = new List<Ship>(); public Form1() { InitializeComponent(); Paint += new PaintEventHandler(OnPaint); } void OnPaint(object sneder, EventArgs e) { DrawBoard(); DrawShips(); } public void DrawBoard() { Graphics g = this.CreateGraphics(); for (int r = 0; r < gameBoard.boardSpaces.GetLength(0); r++) { for (int c = 0; c < gameBoard.boardSpaces.GetLength(1); c++) { g.DrawRectangle(Pens.LightGray, gameBoard.boardSpaces[r, c].area.Location.X, gameBoard.boardSpaces[r, c].area.Location.Y, SQWIDTH, SQHEIGHT); } } g.Dispose(); } public void DrawShips() { Graphics g = this.CreateGraphics(); foreach (Ship ship in shipList) { g.DrawImage(ship.shipImage, ship.mouseHitBox.Location); } g.Dispose(); } public void LoadBoard() { gameBoard.boardSpaces[0, 0] = new Space(new Rectangle(50, 40,SQWIDTH,SQHEIGHT)); gameBoard.boardSpaces[0, 1] = new Space(new Rectangle(130, 40, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[0, 2] = new Space(new Rectangle(210, 40, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[0, 3] = new Space(new Rectangle(290, 40, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[0, 4] = new Space(new Rectangle(370, 40, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[0, 5] = new Space(new Rectangle(450, 40, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[0, 6] = new Space(new Rectangle(530, 40, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[0, 7] = new Space(new Rectangle(610, 40, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[1, 0] = new Space(new Rectangle(50, 120, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[1, 1] = new Space(new Rectangle(130, 120, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[1, 2] = new Space(new Rectangle(210, 120, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[1, 3] = new Space(new Rectangle(290, 120, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[1, 4] = new Space(new Rectangle(370, 120, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[1, 5] = new Space(new Rectangle(450, 120, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[1, 6] = new Space(new Rectangle(530, 120, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[1, 7] = new Space(new Rectangle(610, 120, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[2, 0] = new Space(new Rectangle(50, 200, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[2, 1] = new Space(new Rectangle(130, 200, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[2, 2] = new Space(new Rectangle(210, 200, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[2, 3] = new Space(new Rectangle(290, 200, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[2, 4] = new Space(new Rectangle(370, 200, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[2, 5] = new Space(new Rectangle(450, 200, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[2, 6] = new Space(new Rectangle(530, 200, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[2, 7] = new Space(new Rectangle(610, 200, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[3, 0] = new Space(new Rectangle(50, 280, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[3, 1] = new Space(new Rectangle(130, 280, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[3, 2] = new Space(new Rectangle(210, 280, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[3, 3] = new Space(new Rectangle(290, 280, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[3, 4] = new Space(new Rectangle(370, 280, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[3, 5] = new Space(new Rectangle(450, 280, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[3, 6] = new Space(new Rectangle(530, 280, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[3, 7] = new Space(new Rectangle(610, 280, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[4, 0] = new Space(new Rectangle(50, 360, SQWIDTH,SQHEIGHT)); gameBoard.boardSpaces[4, 1] = new Space(new Rectangle(130, 360, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[4, 2] = new Space(new Rectangle(210, 360, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[4, 3] = new Space(new Rectangle(290, 360, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[4, 4] = new Space(new Rectangle(370, 360, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[4, 5] = new Space(new Rectangle(450, 360, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[4, 6] = new Space(new Rectangle(530, 360, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[4, 7] = new Space(new Rectangle(610, 360, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[5, 0] = new Space(new Rectangle(50, 440, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[5, 1] = new Space(new Rectangle(130, 440, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[5, 2] = new Space(new Rectangle(210, 440, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[5, 3] = new Space(new Rectangle(290, 440, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[5, 4] = new Space(new Rectangle(370, 440, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[5, 5] = new Space(new Rectangle(450, 440, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[5, 6] = new Space(new Rectangle(530, 440, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[5, 7] = new Space(new Rectangle(610, 440, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[6, 0] = new Space(new Rectangle(50, 520, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[6, 1] = new Space(new Rectangle(130, 520, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[6, 2] = new Space(new Rectangle(210, 520, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[6, 3] = new Space(new Rectangle(290, 520, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[6, 4] = new Space(new Rectangle(370, 520, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[6, 5] = new Space(new Rectangle(450, 520, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[6, 6] = new Space(new Rectangle(530, 520, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[6, 7] = new Space(new Rectangle(610, 520, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[7, 0] = new Space(new Rectangle(50, 600, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[7, 1] = new Space(new Rectangle(130, 600, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[7, 2] = new Space(new Rectangle(210, 600, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[7, 3] = new Space(new Rectangle(290, 600, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[7, 4] = new Space(new Rectangle(370, 600, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[7, 5] = new Space(new Rectangle(450, 600, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[7, 6] = new Space(new Rectangle(530, 600, SQWIDTH, SQHEIGHT)); gameBoard.boardSpaces[7, 7] = new Space(new Rectangle(610, 600, SQWIDTH, SQHEIGHT)); } private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) { this.Close(); } } private void Form1_MouseClick(object sender, MouseEventArgs e) { if (shipSelection) { foreach (Ship ship in shipList) { if (ship.mouseHitBox.Contains(e.Location)) { selectedShip = ship; shipSelection = false; shipMove = true; } } } else if(shipMove) { for (int r = 0; r < gameBoard.boardSpaces.GetLength(0); r++) { for (int c = 0; c < gameBoard.boardSpaces.GetLength(1); c++) { if (gameBoard.boardSpaces[r, c].IsEmpty()) { if (gameBoard.boardSpaces[r, c].area.Contains(e.Location)) { selectedShip.UpdateLocation(gameBoard.boardSpaces[r, c].area.Location, gameBoard, r,c); shipMove = false; shipSelection = true; this.Invalidate(); } } } } } } private void Form1_Load(object sender, EventArgs e) { LoadBoard(); Fighter fighter1 = new Fighter(0, "Red Dot", "Test", "Red", new Bitmap(Properties.Resources.redTest), gameBoard.boardSpaces[1, 0].area, 1,0); Fighter fighter2 = new Fighter(0, "Red Dot", "Test", "Red", new Bitmap(Properties.Resources.redTest), gameBoard.boardSpaces[6, 0].area, 6, 0); shipList.Add(fighter1); shipList.Add(fighter2); DrawBoard(); DrawShips(); } }}
To make it easier to find here are the high points:
public Form1() { InitializeComponent(); Paint += new PaintEventHandler(OnPaint); } void OnPaint(object sneder, EventArgs e) { DrawBoard(); DrawShips(); } public void DrawBoard() { Graphics g = this.CreateGraphics(); for (int r = 0; r < gameBoard.boardSpaces.GetLength(0); r++) { for (int c = 0; c < gameBoard.boardSpaces.GetLength(1); c++) { g.DrawRectangle(Pens.LightGray, gameBoard.boardSpaces[r, c].area.Location.X, gameBoard.boardSpaces[r, c].area.Location.Y, SQWIDTH, SQHEIGHT); } } g.Dispose(); } public void DrawShips() { Graphics g = this.CreateGraphics(); foreach (Ship ship in shipList) { g.DrawImage(ship.shipImage, ship.mouseHitBox.Location); } g.Dispose(); }
Any suggestions or do you need the other code like FormDesigner.cs?
Your problem is that you are calling CreateGraphics(). This does NOT do what you think it does. Use the provided graphics object in either the event or in the overridden OnPaint method.
I am not sure whether this is helpful or not, but simple 2-D GDI form-based should be enough with this:
public void EnableDoubleBuffering(){ // Set the value of the double-buffering style bits to true. this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); this.UpdateStyles();}
Read the post before this one, that should do it. But you can also just render it to a second bitmap so you can post process the buffer ( for nice effects )
Questions for the above:
"Your problem is that you are calling CreateGraphics(). This does NOT do what you think it does. Use the provided graphics object in either the event or in the overridden OnPaint method."
Can you expand on that for me?
Where would I put this code in the program? Does it go in the form and then call that method in the constructor or load of the form?
"Your problem is that you are calling CreateGraphics(). This does NOT do what you think it does. Use the provided graphics object in either the event or in the overridden OnPaint method."
Can you expand on that for me?
public void EnableDoubleBuffering(){ // Set the value of the double-buffering style bits to true. this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); this.UpdateStyles();}
Where would I put this code in the program? Does it go in the form and then call that method in the constructor or load of the form?
I am not sure you are asking me or Mike.Popoloski .
But should be like the sample http://www.codeproject.com/KB/cs/SimpleAnalogClockWidget.aspx (that's my article actually :) )
But should be like the sample http://www.codeproject.com/KB/cs/SimpleAnalogClockWidget.aspx (that's my article actually :) )
Quote:Original post by gan
I am not sure you are asking me or Mike.Popoloski .
But should be like the sample http://www.codeproject.com/KB/cs/SimpleAnalogClockWidget.aspx (that's my article actually :) )
I was asking both actually.
The link you provided is broken.
I think this is what Mike means (been a while since I did much GDI+ drawing) but I think the EventArgs for the OnPaint event should pass you a Graphics object for the form. You can use this to do your drawing instead of creating a Graphics object yourself. Also if you are implementing your own buffered painting code I believe you should specify some flags for your form during initialisation using Setstyle(flag, value) These are:
As I say, it's been a while so I'd advise you do some Googling for WinForms double buffered graphics to pick up the fine details - there are quite a few useful resources.
Setstyle(Controlstyles.AllPaintingInWmPaint, true);Setstyle(Controlstyles.UserPaint, true);Setstyle(Controlstyles.DoubleBuffer, true);
As I say, it's been a while so I'd advise you do some Googling for WinForms double buffered graphics to pick up the fine details - there are quite a few useful resources.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement