diabolos Posted January 23, 2009 Posted January 23, 2009 (edited) I apologize if this is in the wrong place; however, I need some assistance. I am a student at ITT Tech and I had to write my own version of Conway's Game Of Life program. I got it working, I used a listbox and used the words dead or alive to represent the cells. NOW, I would like to use red and green boxes in a grid that are drawn on a panel. I have been messing with this for a roughly week now. I have a basic idea but I just cant figure out how to get the panel to REDRAW the new boxes when I click my Seed button. If you need more information please ask, I will be glad to provide any info. Public Class Form1 Dim seed As Double Dim num As Double Dim MAX = 52 Dim cells1(MAX, MAX) As Boolean Dim cells2(MAX, MAX) As Boolean Dim currentRow As String Private Sub btnSeed_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSeed.Click If Not IsNumeric(txtGridSize.Text) Or Not IsNumeric(txtSeed.Text) Then MessageBox.Show("Please Enter a numerical value into BOTH Grid size AND Seed", "ERROR!", MessageBoxButtons.OK) txtGridSize.Clear() txtSeed.Clear() txtGridSize.Focus() Else MAX = CInt(txtGridSize.Text) ReDim cells1(MAX, MAX) Try seed = CInt(txtSeed.Text) Randomize(seed) Catch ex As Exception MessageBox.Show("An exception occurred:" & vbCrLf & ex.Message & " : Please enter a number between -2,147,483,648 and 2,147,483,647", "Uh Oh!", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error) End Try ' this will start the loop for populating the cells randomly For X = 0 To MAX For Y = 0 To MAX num = Rnd() If (num <= 0.5) Then cells1(X, Y) = False Else cells1(X, Y) = True End If Next Y Next X End If End Sub Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint For x As Integer = 0 To MAX For y As Integer = 0 To MAX e.Graphics.DrawRectangle(Pens.Black, 50 + x * 10, 50 + y * 10, 10, 10) If cells1(x, y) = False Then e.Graphics.FillRectangle(Brushes.Red, 50 + x * 10 + 1, 50 + y * 10 + 1, 9, 9) ' these parameters are set to SHOW the gridlines Else e.Graphics.FillRectangle(Brushes.Green, 50 + x * 10 + 1, 50 + y * 10 + 1, 9, 9) ' these parameters are set to SHOW the gridlines End If Next y Next x Panel1.Invalidate() End Sub End Class Edited January 24, 2009 by diabolos Quote
Leaders snarfblam Posted January 23, 2009 Leaders Posted January 23, 2009 The first thing I see wrong is that you are using the Form's paint event to handle painting for the panel. Overriding the Form1.OnPaint method is equivalent to handling the Form's Paint event, but you don't want to draw on the form, you want to draw on the panel. The code in your OnPaint method should be moved to Panel1_Paint. And just a note: whenever you override any OnSomething method, you need to call the overridden (base) method. In other words, you would need to call MyBase.OnPaint(e) in the OnPaint method. Otherwise some event handlers might not be called. As for your problem of getting things to be redrawn, the important concept here is invalidation. The Paint event (or OnPaint method) is responsible for doing the drawing, but it needs to be told when to draw. This is done by invalidation. You want to call the Panel1.Invalidate method to tell it that part of the control is invalid. For example, suppose the panel were covered by another window, and then that window is dragged out of the way. The panel now needs to be redrawn. It has graphical leftovers on it from the window that was dragged away, and is therefore invalid. In that case, Windows will automatically invalidate your panel for you. In other words, "invalidating" a control simply means informing it that it needs to be redrawn. If your program's data changes, and that change needs to be shown on the control, you need to invalidate the panel yourself, by calling Panel1.Invalidate. Quote [sIGPIC]e[/sIGPIC]
diabolos Posted January 24, 2009 Author Posted January 24, 2009 I see, Thank you for taking the time to sort through this. I really appreciate your feedback! :o I will try what you suggested and get back to you when I find out if this is going to work for me. Thank you so much! Quote
diabolos Posted January 24, 2009 Author Posted January 24, 2009 (edited) Ok, so I did as you said; however, I have another question. How would I perform a call to panel1 to have it paint from the press of a button in form1? Why does the panel1_paint subroutine get called continuously when I run my program? is there a way to run my program and have it show nothing until I click my seed button to draw the grid and such? I am only assuming it is in a loop because I tried to put the panel1.invalidate() in there and it just flickers forever :) I am sorry, I am better with C++, and Java :) Let me give you a better idea of what I want to accomplish here: 1.) Upon running the program, the controls are all visible and the panel HAS NOT been populated with any drawing of any kind YET... 2.) When I enter the grid size and seed value into their respective boxes, I will hit the "Go!" button. This should randomly generate Boolean values throughout the multidimensional array cells1 and then call the paint method to populate the panel1 with a grid size that the user entered and fill the boxes of each grid with red boxes (if false) and green boxes(if true). NOTE: this is where I am stuck; I have not implemented anything else yet until I can figure out the painting part. The following is what I wish to accomplish after the preceding part is completed 3.) Create a button to "step" through each generation of life of the cells according to the rules of John Conway's game of life. 4.) Each time the step button is pressed, the rules are applied and this could change the values of each cell, thus needing them to be repainted and displayed to the user. Thanks for your time and patience! P.S. I edited my original post to show what my code looks like now. Edited January 24, 2009 by diabolos Quote
MrPaul Posted January 25, 2009 Posted January 25, 2009 Call panel1.Invalidate() when needed I am only assuming it is in a loop because I tried to put the panel1.invalidate() in there and it just flickers forever :) You put Panel1.Invalidate() in the paint event handler? Each time you call Panel1.Invalidate(), the paint event will be called and the panel will be redrawn. You should only be calling Panel1.Invalidate() when you want to redraw the panel - it sounds like this will be in two places: In the event handler for your "Go!" button (after populating the boolean values) In the event handler for your "step" button (after updating the values) However, the paint event could be called at any time, for example when the form is shown or when a window which was obscuring the panel is moved away. To compensate for this, your paint event handler needs to check whether "Go!" has been clicked. For example: Dim goPressed As Boolean = False Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint If (goPressed) Then 'Draw game state End If End Sub Private Sub btnSeed_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSeed.Click 'Populate values 'Draw panel goPressed = True Panel1.Invalidate() End Sub Private Sub btnStep_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStep.Click 'Update values 'Redraw panel Panel1.Invalidate() End Sub Good luck :cool: Quote Never trouble another for what you can do for yourself.
diabolos Posted January 25, 2009 Author Posted January 25, 2009 (edited) Re: Call panel1.Invalidate() when needed Beautiful, Thank you so much for your help! It works perfectly! Cheers! I figured out how to get rid of the flickering by double buffering the main form and just getting rid of the panel and placing the code in a different sub. I added a handle MyBase.paint to the sub and now, no more flickering :) it is a beautiful thing :) thanks alot for all the help! :) Edited January 26, 2009 by diabolos Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.