Recent

Author Topic: Animation for a four-in-a-row game  (Read 2711 times)

Roland57

  • Full Member
  • ***
  • Posts: 108
Re: Animation for a four-in-a-row game
« Reply #15 on: September 08, 2020, 07:12:07 pm »
Something else. I discovered, by starting the demo in a terminal, that there was this warning many times repeated:

Quote
WARNING: TGtk2WidgetSet.InvalidateRect refused invalidating during paint message: TForm1

If I understand correctly, the problem is that this operation

Code: Pascal  [Select][+][-]
  1. FBuffer.Draw(IMImage.Canvas, 0, 0, True);

calls automatically the FormPaint event. So I moved it outside the FormPaint procedure,

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. { ... }
  3. begin
  4.   { ... }
  5.     FBuffer.PutImage(LScale - 4, LScale * 2 - 4, FGrid, dmDrawWithTransparency);
  6.     FBuffer.Draw(IMImage.Canvas, 0, 0, True); // <----

and removed the FormPaint procedure. No more warning, and the result is still OK.

But after that I discovered another problem. The call to InvalidateRect

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. { ... }
  3. begin
  4.   { ... }
  5.     FBuffer.Draw(IMImage.Canvas, 0, 0, True);
  6.     LRect := FBuffer.ClipRect;
  7.     InvalidateRect(Self.Handle, @LRect, FALSE); // <----

becomes redundant: I can delete the line, the animation is still OK.

So what would be the correct approach?

« Last Edit: September 08, 2020, 07:17:47 pm by Roland57 »

winni

  • Hero Member
  • *****
  • Posts: 1992
Re: Animation for a four-in-a-row game
« Reply #16 on: September 08, 2020, 07:38:41 pm »
Something else. I discovered, by starting the demo in a terminal, that there was this warning many times repeated:

Quote
WARNING: TGtk2WidgetSet.InvalidateRect refused invalidating during paint message: TForm1

Hi!

I have seen that message so often and from so  many applications.
For me I have decided : I don't care anymore.

And I have not seen any problems with that.

Winni

Roland57

  • Full Member
  • ***
  • Posts: 108
Re: Animation for a four-in-a-row game
« Reply #17 on: September 08, 2020, 07:58:11 pm »
I have seen that message so often and from so  many applications.
For me I have decided : I don't care anymore.

Hi! Thank you for your answer. Yes, maybe I could simply ignore it... But I would prefer to understand exactly how things work.

Roland57

  • Full Member
  • ***
  • Posts: 108
Re: Animation for a four-in-a-row game
« Reply #18 on: September 09, 2020, 07:20:43 am »
I believed I had found a solution.

Code: Pascal  [Select][+][-]
  1.     //FBuffer.Draw(IMImage.Canvas, 0, 0, TRUE);
  2.     LRect := FBuffer.ClipRect;
  3.     //InvalidateRect(Self.Handle, @LRect, FALSE);
  4.     FBuffer.DrawPart(LRect, IMImage.Canvas, LRect.Left, LRect.Top, TRUE);

But this doesn't solve the problem, since the OS will still refresh all the window.  :-\

As far as I understand, the problem is the following: does it make sense to call InvalidateRect after an instruction (here FBuffer.Draw) which has already automatically called a repaint?

Is there a way to draw on a TImage (or another component) without calling automatically the OnPaint event?
« Last Edit: September 09, 2020, 07:22:40 am by Roland57 »

circular

  • Hero Member
  • *****
  • Posts: 3561
    • Personal webpage
Re: Animation for a four-in-a-row game
« Reply #19 on: September 09, 2020, 11:12:27 am »
I don't understand why you get this message. The general rule is:
- draw on the control canvas only in its OnPaint event, which is what you did
- call InvalidateRect outside of the OnPaint event, which is what you did as well

Do you get the warning about InvalidateRect repeatedly or just once?
Conscience is the debugger of the mind

circular

  • Hero Member
  • *****
  • Posts: 3561
    • Personal webpage
Re: Animation for a four-in-a-row game
« Reply #20 on: September 09, 2020, 01:28:37 pm »
In fact, reading the code I realized there are some problems with the painting method.

If you paint things yourself on the controls, you would rather not use TImage, because this component is designed to store a image and display it itself. Instead I suggest you use a TPaintBox.

The painting need to be in the paint handler of the control. If you draw on TPaintBox, then you would set the OnPaint event of TPaintBox, not of TForm.

To sum up:
- replace the TImage by TPaintBox
- draw in the OnPaint event of TPaintBox
- invalidate the TPaintBox not the TForm
Conscience is the debugger of the mind

winni

  • Hero Member
  • *****
  • Posts: 1992
Re: Animation for a four-in-a-row game
« Reply #21 on: September 09, 2020, 03:11:39 pm »
Hi!

Or you use the advantages of the TImage:

* You are allowed to draw at any time on the Image.canvas - The Image update itself
* You dont need an invalidate or an update - the image does it isself.

There are a lot of advantages with a TImage:

It has a bitmap inside. So you can copy the image for whatever purpose.
You can save the data as PNG, BMP, JPEG or ...
with
Image.Picture.PNG.saveToFile (or stream).

And the Image data is persistent:
You dont have to care about redraw.

Too much people think about the Tinage only as a picture container.
But itis widely used for maps or image manipulation.

Has to be said.

Winni

lucamar

  • Hero Member
  • *****
  • Posts: 3184
Re: Animation for a four-in-a-row game
« Reply #22 on: September 09, 2020, 03:58:18 pm »
Or you use the advantages of the TImage:

[...]

Too much people think about the Tinage only as a picture container.
But itis widely used for maps or image manipulation.

I don't know why people insist on using (and worse, recommending) TImage for something for which it wasn't designed. That control was thought out as, indeed, a container to show images. When one needs a control into which one can load an image, modify it, draw in it, or whatever, the control to use is a TPaintBox.

Not to say, of course, that TImage cannot be used for it, but TPaintBox was designed exactly for that. :-\
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

circular

  • Hero Member
  • *****
  • Posts: 3561
    • Personal webpage
Re: Animation for a four-in-a-row game
« Reply #23 on: September 09, 2020, 04:59:07 pm »
TImage has its use, but it would be redundant with TBGRABitmap (you would need to draw the BGRABitmap on the TBitmap of TImage). Also you don't have much control on update.
Conscience is the debugger of the mind

Roland57

  • Full Member
  • ***
  • Posts: 108
Re: Animation for a four-in-a-row game
« Reply #24 on: September 09, 2020, 06:23:03 pm »
Thank you all for your answers. The TPaintBox solution works perfectly. I will post the code when it is clean. Too tired tonight to make good work.  :)

winni

  • Hero Member
  • *****
  • Posts: 1992
Re: Animation for a four-in-a-row game
« Reply #25 on: September 09, 2020, 07:35:19 pm »

Not to say, of course, that TImage cannot be used for it, but TPaintBox was designed exactly for that. :-\

Hi!

Lets assume you want to draw a map of Europe. You have a very lot of Multi-Polygons, Polygons, Polylines and Points.
You want to draw the borders, the rivers, the roads, the railroads, the ferries. The big and the medium cities, the mountain peaks and the historical sites. And all the captions in different size and style. With a lot af Icons for the different needs.

And that all in the OnPaint event of a PaintBox??????

Keep on dreaming .....

Winni

Handoko

  • Hero Member
  • *****
  • Posts: 3902
  • My goal: build my own game engine using Lazarus
Re: Animation for a four-in-a-row game
« Reply #26 on: September 09, 2020, 08:20:51 pm »
I think I understand what winni meant.

If you need doing drawing with lots of objects, for example building a painting software like GIMP or Krita. It is better to use TImage. As already said, the pixel data is persistent.

For example, I ever did realistic photo painting using Krita, that took me hours to finish it. If using TPaintBox to build that kind of software, we need a variable to store all my painting strokes var Data: array of TPaintAction. How long the array will be to store all my strokes? That should also includes my actions of changing brush type and size, color picking, erasing, etc. I believe the length of the array to store all the actions could be thousands or maybe more. Using TPaintBox is not good for this case. Computer memory maybe won't be an issue but, the performance won't be good.

The name TPaintBox is confusing. I think it should be TDrawBox. Because it is more suitable for drawing some simple shapes, lines, texts, etc. When I hear the word painting, I will think of the activity of stroking a canvas hundreds times using many different type of brushes.

Off course, in programming impossible can become possible. For this case (not the OP's case) we still can use TPaintBox and optimize the performance by using a buffer. The buffer only keeps the last result of all the user actions. So TPaintBox's OnPaint only needs to draw the buffer, it's very fast. I can be done but not correctly done.

Sorry off topic.  :D
« Last Edit: September 09, 2020, 08:42:50 pm by Handoko »

circular

  • Hero Member
  • *****
  • Posts: 3561
    • Personal webpage
Re: Animation for a four-in-a-row game
« Reply #27 on: September 09, 2020, 10:26:10 pm »
In this case, you can use TBGRAVirtualScreen. It stores the content as a TBGRABitmap so you don't have to redraw everything all the time. It is a bit like a TImage in some sense, except that it triggers a Redraw event when the bitmap needs to be redrawn, and you can say what part of the image is to be redrawn.
Conscience is the debugger of the mind

winni

  • Hero Member
  • *****
  • Posts: 1992
Re: Animation for a four-in-a-row game
« Reply #28 on: September 09, 2020, 10:42:05 pm »
Quote
WARNING: TGtk2WidgetSet.InvalidateRect refused invalidating during paint message: TForm1

@Roland57

Sometimes the things seem to get better.

I recompiled an own programm which is some years old.
It was notorious  giving the above message every second - when the timer did some graphic update stuff.
Meanwhile " my" gtk2 and fpc/Lazarus are updated.
The warning is totaly gone with the exception of the programm start .
There it is shown once.

So I don't know whom to blame: gtk2 or fpc/Lazarus

How to get the latest version of fpc/Lazarus is written in this forum.

So what about your gtk2 version???

To get the version number from the bash is ridiculous:
Depends if you work with DEB- or RPM-packages and a lot of other things.

The easiest way is Pascal:

Code: Pascal  [Select][+][-]
  1. uses ......,gtk2;
  2. ......
  3. showMessage(IntToStr(gtk_major_version)+' / '+IntToStr(gtk_minor_version));
  4. .....
  5.  
  6.  

This shows for me 2 / 24

So: Update your system? Or ignore the message like I did for a long time.

Keep on hackin'

Winni


devEric69

  • Sr. Member
  • ****
  • Posts: 381
Re: Animation for a four-in-a-row game
« Reply #29 on: September 09, 2020, 10:57:53 pm »
TImage versus TPaintBox? It depends.

If it's a question of making just a simple diagram (with graphical objects such as controls of different shapes, links, selection elastics with the mouse), a TPaintBox is more adapted to the management of the "chain of responsibility" of the lm_paint events processing (OnPaint), among the parent \ child controls (using the drawing helper functions, in order to redraw \ update only the new invalid areas \ rectangles).

The essential thing is that there is a canvas :) .
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

 

TinyPortal © 2005-2018