### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Make a Dynamic Shape Array and make an Array of That  (Read 2690 times)

#### KodeZwerg

• Hero Member
• Posts: 1216
• Fifty shades of code.
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #30 on: January 26, 2023, 12:00:25 pm »
Now how to make a synchronised mouse click event in  TForm1.ShapeEvent ?
I show you one way of how to solve in attachment.
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

#### KodeZwerg

• Hero Member
• Posts: 1216
• Fifty shades of code.
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #31 on: January 26, 2023, 12:06:12 pm »
I missed to put correct code into the "else"
Please update line #152 to:
Code: Pascal  [Select][+][-]
1.       (Sender as TShape).Brush.Color := btnColor.ButtonColor;
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

#### Boleeman

• Jr. Member
• Posts: 87
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #32 on: January 26, 2023, 12:53:17 pm »
Wow KodeZwerg. That's so cool.
(Just got back from an outdoors park gym workout at 10.30 pm).

I was looking at your magnificent code:

LTag := (Sender as TShape).Tag;  means the tag number is the shape clicked tag. (that's one thing I did not how to write in the code. It makes sense now.
if (LTag > (FBlockRow * FBlockCol)) means the click is not i the initial row by column block
LTag := LTag mod (FBlockRow * FBlockCol); means tag number is the left over from mod division

The part I am still trying to understand is:

Code: Pascal  [Select][+][-]
1.                [color=red][b] if ((i = LTag) or (i - (FBlockRow * FBlockCol) = LTag)) [/b][/color]then
2.                   FBlocks[Brows, Bcols, Srows, Scols].Brush.Color := btnColor.ButtonColor;
3.                 Inc(i);
4.                 if (i > (FBlockRow * FBlockCol)) then
5.                   i := 1;

Would i be the block number, like the second 5x5 block, 3rd 5x5 block number and so on.

Still can't get over how you coded all of that so efficiently. I was struggling with the logic and how to write it into TfrmMain.ShapeEvent procedure code.

I am so impressed.

Thanks for helping out once again KodeZwerg.

« Last Edit: January 26, 2023, 01:30:21 pm by Boleeman »

#### KodeZwerg

• Hero Member
• Posts: 1216
• Fifty shades of code.
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #33 on: January 26, 2023, 01:07:11 pm »
Code: Pascal  [Select][+][-]
1. procedure TfrmMain.ShapeEvent(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X , Y: Integer);
2. var
3.   Brows, Bcols, Srows, Scols: Integer;
4.   LTag, i: Integer;
5. begin
6.   if cbSync.Checked then
7.     begin
8.       // my counter (from 1 to 25 if its 5x5)
9.       i := 1;
10.       // get correct tag (from 1 to 25 if its 5x5)
11.       LTag := (Sender as TShape).Tag;
12.       // if we are outside of 25, recalculate
13.       if (LTag > (FBlockRow * FBlockCol)) then
14.         LTag := LTag mod (FBlockRow * FBlockCol);
15.       // it was exact the 25, so set it to 25
16.       if LTag = 0 then
17.         LTag := (FBlockRow * FBlockCol);
18.       // loop to update tag
19.       for Brows := 0 to Pred(FBlocksRow) do
20.         for Bcols := 0 to Pred(FBlocksCol) do
21.           for Srows := 0 to Pred(FBlockRow) do
22.             for Scols := 0 to Pred(FBlockCol) do
23.               begin
24.                 // "i" represent now every shape from 1 to 25 inside each block
25.                 if (i = LTag) then
26.                   FBlocks[Brows, Bcols, Srows, Scols].Brush.Color := btnColor.ButtonColor;
27.                 Inc(i);
28.                 if (i > (FBlockRow * FBlockCol)) then
29.                   i := 1;
30.               end;
31.     end
32.     else
33.       (Sender as TShape).Brush.Color := btnColor.ButtonColor;
34. end;

Quote
(i - (FBlockRow * FBlockCol) = LTag))
that was a relict, outdated and i missed to remove.
Wow KodeZwerg. That's so cool.
I am happy to help.
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

#### Boleeman

• Jr. Member
• Posts: 87
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #34 on: January 26, 2023, 01:16:52 pm »
OK I will update.

Thanks for adding the explanations.

So  "i" represent now every shape from 1 to 25 inside each block

I like looking over the code to analyse and learn from it.
It's great that you explained it further for me to better understand.

Still can't believe that you achieved what I thought was impossible to achieve. I hard coded mine in VB6, but looks like Lazarus does arrays better. I liked how you put in hints in the previous code to look for patterns. When you code do you use any tools? I was thinking of using a snippets library program, to store bits and pieces of code.
« Last Edit: January 26, 2023, 01:28:53 pm by Boleeman »

#### KodeZwerg

• Hero Member
• Posts: 1216
• Fifty shades of code.
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #35 on: January 26, 2023, 03:26:48 pm »
Thanks for adding the explanations.
XOXOXO

Still can't believe that you achieved what I thought was impossible to achieve. I hard coded mine in VB6, but looks like Lazarus does arrays better. I liked how you put in hints in the previous code to look for patterns.
Hardcoded = wrong coded
I always try to make everything generic working
Alpha releases often contain hardcoded, beta is than refactored to become final.
If I ever refactor this demo, I would for example replace "FBlockRow * FBlockCol" with a variable like "LMax" to just calculate "FBlockRow * FBlockCol" once.

When you code do you use any tools? I was thinking of using a snippets library program, to store bits and pieces of code.
The only tool I use is what the IDE offers me, from time to time a calculator if I am too sleepy to do it in my head.
I also read from time to time documentation about things to understand whats a possible correct way to handle those things.
My code library is big but to be honest, I do look very very rare into, I just keep adding
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

#### Joanna

• Sr. Member
• Posts: 297
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #36 on: January 27, 2023, 12:07:27 am »
I don’t know if this will be helpful or not but I’d like to pass along some advice that was given to me back when I had some frames with a lot of shapes in them....
You might eventually want to draw your shapes in a paintbox rather than using separate shape objects. When using paintbox Click Events determine which area in paintbox click occurred in simulating clicking on a shape.

If you ever have any difficulty with slowness like I did...
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc #lazarus #pascal
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

#### Boleeman

• Jr. Member
• Posts: 87
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #37 on: January 27, 2023, 07:48:37 am »
I can't believe the stats for this thread:    36 Replies   and   1547 Views

The reason for asking to do this Shapes Array way was to see if it could be done in Lazarus.
I made a hardcoded VB6 version for 3x3 and 6x6 squares and was always puzzled when thinking of a dynamic array way to do the tessellations. I would click on these outside the main grid to make the effects inside the larger grid. KodeZwerg's way in Lazarus was designed to click anywhere in the large grid to repeat that pattern. I was aware that the shapes would take longer to load, but the click event is not that long to execute.

It would be nice to see it done this Tessellation done by using the paintbox Click Events determine which area in paintbox click that it occurred, to compare the difference. Even thought of just having an original line grid array and then copying multiple canvas copies of it to a semi-transparent BGRABitmap.

I have some creative ideas for graphics programs, but tend to get bogged down by how to code it. I learnt quite a bit from KodeZwerg and VisualLab and Circular and speter and Jamie and WP and Alpine and ASerge over the Summer holiday period (Supershape, Polygons, Tesselator, Grid). I am very grateful for their patience and their guidance. I always wanted to have a go at doing Lazaras but tended to get bogged down with errors happening and not knowing how to correct them. I am slowing learning how to fix these errors, but still on that learning curve. This board has some nice members.
« Last Edit: January 27, 2023, 07:53:10 am by Boleeman »

#### KodeZwerg

• Hero Member
• Posts: 1216
• Fifty shades of code.
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #38 on: January 27, 2023, 10:41:27 am »
I don’t know if this will be helpful or not but I’d like to pass along some advice that was given to me back when I had some frames with a lot of shapes in them....
You might eventually want to draw your shapes in a paintbox rather than using separate shape objects. When using paintbox Click Events determine which area in paintbox click occurred in simulating clicking on a shape.

If you ever have any difficulty with slowness like I did...
Than I would rather do like Handoko telled, switching to a paintbox or image and instead of shapes, draw rectangles, get x/y location to know which "shape" was clicked on to maybe repeat that action for others.
My demo is a simplified way to get the proper result and easy handling since everything is its own object.
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

#### Handoko

• Hero Member
• Posts: 4784
• My goal: build my own game engine using Lazarus
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #39 on: January 27, 2023, 11:58:31 am »
The way I suggested in the reply #2 - as I already mentioned - is hard way solution. It's fun, the programmer will have more control on the visual result and it is lightweight. Less memory and fast.

Sorry I don't mean to discourage the OP. KodeZwerg solution is relatively easy and he provided good explanation, unfortunately the OP seems a bit slow following it. I would recommend anybody should already able fully understand KodeZwerg's solution before try doing the hard way.

#### Joanna

• Sr. Member
• Posts: 297
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #40 on: January 27, 2023, 02:23:41 pm »
It’s definitely easier to start with actual shape controls at beginning.
A lot of complicated things you need to work your way up to with easier stuff otherwise it will be overwhelming...

In my case it was a frame for picking colors so each shape was a color to choose. I created all the shapes at runtime.
If I remember correctly there was no click event for tshapes so I used onmouseup event.

Playing with colorful shapes is definitely a fun way to learn programming.
Lazarus reminds me of vbasic only better
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc #lazarus #pascal
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

#### Boleeman

• Jr. Member
• Posts: 87
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #41 on: January 27, 2023, 02:24:13 pm »
The other important property is that you can remove the border of each shape to make interesting continuous colour effects. In the attached picture the brown line is continuous (just as a simple example). Would the grid line method be able to have no borders?

BTW:
Is there a quick way to clear the colour of all shapes (like a collection way used in Vb6) rather than looping through all the array items? I tried this but it did not work. I think Controls is the problem?

Code: Pascal  [Select][+][-]
1. procedure TfrmMain.bnClearClick(Sender: TObject);
2. var
3.   i: integer;
4. begin
5.   for i := 0 to ControlCount-1 do
6.     if Controls[i] is TShape then
7.     begin
8.       (Controls[i] as TShape).Brush.Color:=clWhite;
9.     end;
10. end;
« Last Edit: January 27, 2023, 02:37:49 pm by Boleeman »

#### KodeZwerg

• Hero Member
• Posts: 1216
• Fifty shades of code.
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #42 on: January 27, 2023, 02:43:57 pm »
Added your feature in a correct way
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

#### Boleeman

• Jr. Member
• Posts: 87
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #43 on: January 27, 2023, 02:52:34 pm »
Ah I see not "controls(i) but Components "

What does Pred mean?  Hovering over Pred says Type LongInt  so does that change type from longInt to integer?

I saw Pred in the code but did not really know why it was used (just assumed it was needed).

OK:  Pred returns the element that precedes the element that was passed to it. Thanks KodeZwerg.

Was also looking to toggle the border of each shape ON and OFF  and the 5 pixel gap between blocks with one checkbox but could not find the border property in

FBlocks[Brows, Bcols, Srows, Scols].??????

« Last Edit: January 27, 2023, 03:26:37 pm by Boleeman »

#### KodeZwerg

• Hero Member
• Posts: 1216
• Fifty shades of code.
##### Re: Make a Dynamic Shape Array and make an Array of That
« Reply #44 on: January 27, 2023, 02:59:02 pm »
Ah I see not "controls(i) but Components "

What does Pred mean?  Hovering over Pred says Type LongInt  so does that change type from longInt to integer?
Lol, I literal used that method all the time and just by now you asking me what Pred() means?
Quote
Pred returns the element that precedes the element that was passed to it.
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »