Reputation: 2890
I'm trying to create a Game of Life emulator. I previously got it working with a StrGrid however that was slower and I was told to use a DrawGrid.
My program works by having two arrays, strArray that holds all the values for the next generation of cells, and currentArray that holds all the values for the current generation of cells (both are type array [1 .. 127] of array [1 .. 127] of string;, I know it would be better to use a boolean array but this is an older program). On a timer, an algorithm counts the number of alive cells around each cell and gives it a value in strArray, T (Designating an alive cell) or F (Designating a dead cell). This pattern is then written to currentArray to be used the next time the alive cells need to be calculated. I then would like to change the color of each cell to white if the relevant cell matches 'F' in the currentArray, and change it to black if it matches 'T'. I'd also like to be able to color a cell I click black and change it's value in the data table to 'T'.
However, I'm unfamiliar with drawgrids and can't seem to find any relevant information that makes any sense to me. When I was using a string grid, you could access the contents of each cell by using stringgrid.cells[stringgrid.col, stringgrid.row] := 'whatever'; however I can't find a similar method for a DrawGrid.
To summarise, I need help to:
I hope you can help me. Thankyou!
Upvotes: 0
Views: 4525
Reputation: 595467
The only real difference between TDrawGrid
and TStringGrid
is that TDrawGrid
does not store any cell data itself whereas TStringGrid
does, and also that you have to draw everything yourself in a TDrawGrid
whereas TStringGrid
default-draws the cell strings for you (but you can also custom draw the cells if desired). You have your own arrays for storing your cell data. Use the OnDrawCell
event to draw the cells however you want. It gives you the Col
and Row
of the cell currently being drawn. You would simply access the corresponding array elements and set the grid's Canvas
properties accordingly, such as its Brush.Color
and Font.Color
, then call the Canvas.FillRect()
and Canvas.TextRect()
methods as needed.
As for handling clicks, all you would do is update your array as needed and then Invalidate()
the grid to trigger a repaint using the latest data.
For example:
procedure TForm1.TimerTick(Sender: TObject);
begin
// update contents of currentArray as needed...
DrawGrid1.Invalidate;
end;
procedure TForm1.DrawGrid1Click(Sender: TObject);
begin
if currentArray[DrawGrid1.Col][DrawGrid1.Row] <> 'T' then
begin
currentArray[DrawGrid1.Col][DrawGrid1.Row] := 'T';
DrawGrid1.Invalidate;
end;
end;
procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Longint; Rect: TRect; State: TGridDrawState);
begin
if currentArray[ACol][ARow] = 'F' then
begin
DrawGrid1.Canvas.Brush.Color := clWhite;
DrawGrid1.Canvas.Font.Color := clBlack;
end else
begin
DrawGrid1.Canvas.Brush.Color := clBlack;
DrawGrid1.Canvas.Font.Color := clWhite;
end;
DrawGrid1.Canvas.FillRect(Rect);
DrawGrid1.Canvas.TextRect(Rect, Rect.Left, Rect.Top, currentArray[ACol][ARow]);
end;
Upvotes: 6