* * *

Author Topic: how to delete the canvas rectangle  (Read 10518 times)

shs

  • Sr. Member
  • ****
  • Posts: 310
how to delete the canvas rectangle
« on: September 01, 2017, 01:37:04 pm »
procedure TForm1.FormPaint(Sender: TObject);
begin
  canvas.rectangle(a, b, c, d);
end;                       

a.b.c.d are all random numbers and i want to draw rectangle in random position every second. but one more thing i want to do is to delete the previous rectangle or x seconds previous rectangle every second so that only certain number of rectangles can be shown  on the form.

p.s filling the triangle with default color is not i want. i want to permanently delete the rectangle       

Leledumbo

  • Hero Member
  • *****
  • Posts: 7742
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: how to delete the canvas rectangle
« Reply #1 on: September 01, 2017, 02:24:15 pm »
a.b.c.d are all random numbers and i want to draw rectangle in random position every second. but one more thing i want to do is to delete the previous rectangle or x seconds previous rectangle every second so that only certain number of rectangles can be shown  on the form.
You should maintain a data structure representing currently drawn rectangles, perhaps along with the second they're created and modify the data structure accordingly (e.g. move rectangles from one index to another, resize the container, etc.). This data structure will then be a base for you to draw upon the canvas.
p.s filling the triangle with default color is not i want. i want to permanently delete the rectangle     
There's no such a thing, Canvas.Rectangle does NOT create a rectangle object (which then gets drawn), but draw pixels forming a rectangle (hope you understand the difference), as any other Canvas drawing methods do. As such, "deletion" is indeed filling the same space with the canvas' background color.

FormPaint will clear the canvas anyway, so if you don't draw again what was drawn the previous FormPaint, it will be gone.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #2 on: September 01, 2017, 02:44:51 pm »
a.b.c.d are all random numbers and i want to draw rectangle in random position every second. but one more thing i want to do is to delete the previous rectangle or x seconds previous rectangle every second so that only certain number of rectangles can be shown  on the form.
You should maintain a data structure representing currently drawn rectangles, perhaps along with the second they're created and modify the data structure accordingly (e.g. move rectangles from one index to another, resize the container, etc.). This data structure will then be a base for you to draw upon the canvas.

how do i maintain a data structure for that?

Handoko

  • Hero Member
  • *****
  • Posts: 1771
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #3 on: September 01, 2017, 03:56:23 pm »
Hello rhong7,
Welcome to the forum.

You can use array, record, TList, TObjectList, etc to maintain a collection of items. My example below use TFPList. If you don't know which one to use, TList is okay for most cases. You can download my test.zip for testing.

Learn more about collection:
http://wiki.freepascal.org/Data_Structures,_Containers,_Collections

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, StdCtrls, ExtCtrls, Spin;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Label1: TLabel;
  17.     SpinEdit1: TSpinEdit;
  18.     Timer1: TTimer;
  19.     procedure Button1Click(Sender: TObject);
  20.     procedure FormCreate(Sender: TObject);
  21.     procedure FormDestroy(Sender: TObject);
  22.     procedure FormPaint(Sender: TObject);
  23.     procedure Timer1Timer(Sender: TObject);
  24.   end;
  25.  
  26. var
  27.   Form1: TForm1;
  28.  
  29. implementation
  30.  
  31. type
  32.   TItem = record
  33.     X1, X2, Y1, Y2: Integer;
  34.     Color: TColor;
  35.   end;
  36.   PItem = ^TItem;
  37.  
  38. var
  39.   Items: TFPList; // list of PItem
  40.  
  41. {$R *.lfm}
  42.  
  43. { TForm1 }
  44.  
  45. procedure TForm1.Button1Click(Sender: TObject);
  46. begin
  47.   Timer1.Enabled := not(Timer1.Enabled);
  48.   if Timer1.Enabled then
  49.     Button1.Caption := 'Pause'
  50.   else
  51.     Button1.Caption := 'Start';
  52. end;
  53.  
  54. procedure TForm1.FormCreate(Sender: TObject);
  55. begin
  56.   Items := TFPList.Create;
  57. end;
  58.  
  59. procedure TForm1.FormDestroy(Sender: TObject);
  60. begin
  61.   Timer1.Enabled := False;
  62.   Items.Free;
  63. end;
  64.  
  65. procedure TForm1.FormPaint(Sender: TObject);
  66. var
  67.   Item: TItem;
  68.   i: Integer;
  69. begin
  70.   for i := 0 to (Items.Count-1) do
  71.   begin
  72.     Item := PItem(Items[i])^;
  73.     Canvas.Brush.Color := Item.Color;
  74.     Canvas.Rectangle(Item.X1, Item.Y1, Item.X2, Item.Y2);
  75.   end;
  76. end;
  77.  
  78. procedure TForm1.Timer1Timer(Sender: TObject);
  79. var
  80.   Item: PItem;
  81.   X1, Y1, X2, Y2: Integer;
  82.   Selected: Integer;
  83. begin
  84.   if (Random(10) > 3) then // new rectangle
  85.   begin
  86.     if (Items.Count >= SpinEdit1.Value) then Exit;
  87.     X1 := Random(Width);
  88.     Y1 := Random(Height);
  89.     X2 := X1 + Random(80);
  90.     Y2 := Y1 + Random(80);
  91.     New(Item);
  92.     Item^.X1 := X1;
  93.     Item^.Y1 := Y1;
  94.     Item^.X2 := X2;
  95.     Item^.Y2 := Y2;
  96.     Item^.Color := RGBToColor(Random(255), Random(255), Random(255));
  97.     Items.Add(Item);
  98.   end
  99.   else // remove rectangle
  100.   begin
  101.     if (Items.Count <= 0) then Exit;
  102.     Selected := Random(Items.Count);
  103.     Items.Delete(Selected);
  104.   end;
  105.   Repaint;
  106. end;
  107.  
  108. end.
« Last Edit: September 01, 2017, 03:58:31 pm by Handoko »

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #4 on: September 02, 2017, 02:32:40 am »
Hello rhong7,
Welcome to the forum.

You can use array, record, TList, TObjectList, etc to maintain a collection of items. My example below use TFPList. If you don't know which one to use, TList is okay for most cases. You can download my test.zip for testing.

Learn more about collection:
http://wiki.freepascal.org/Data_Structures,_Containers,_Collections

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, StdCtrls, ExtCtrls, Spin;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Label1: TLabel;
  17.     SpinEdit1: TSpinEdit;
  18.     Timer1: TTimer;
  19.     procedure Button1Click(Sender: TObject);
  20.     procedure FormCreate(Sender: TObject);
  21.     procedure FormDestroy(Sender: TObject);
  22.     procedure FormPaint(Sender: TObject);
  23.     procedure Timer1Timer(Sender: TObject);
  24.   end;
  25.  
  26. var
  27.   Form1: TForm1;
  28.  
  29. implementation
  30.  
  31. type
  32.   TItem = record
  33.     X1, X2, Y1, Y2: Integer;
  34.     Color: TColor;
  35.   end;
  36.   PItem = ^TItem;
  37.  
  38. var
  39.   Items: TFPList; // list of PItem
  40.  
  41. {$R *.lfm}
  42.  
  43. { TForm1 }
  44.  
  45. procedure TForm1.Button1Click(Sender: TObject);
  46. begin
  47.   Timer1.Enabled := not(Timer1.Enabled);
  48.   if Timer1.Enabled then
  49.     Button1.Caption := 'Pause'
  50.   else
  51.     Button1.Caption := 'Start';
  52. end;
  53.  
  54. procedure TForm1.FormCreate(Sender: TObject);
  55. begin
  56.   Items := TFPList.Create;
  57. end;
  58.  
  59. procedure TForm1.FormDestroy(Sender: TObject);
  60. begin
  61.   Timer1.Enabled := False;
  62.   Items.Free;
  63. end;
  64.  
  65. procedure TForm1.FormPaint(Sender: TObject);
  66. var
  67.   Item: TItem;
  68.   i: Integer;
  69. begin
  70.   for i := 0 to (Items.Count-1) do
  71.   begin
  72.     Item := PItem(Items[i])^;
  73.     Canvas.Brush.Color := Item.Color;
  74.     Canvas.Rectangle(Item.X1, Item.Y1, Item.X2, Item.Y2);
  75.   end;
  76. end;
  77.  
  78. procedure TForm1.Timer1Timer(Sender: TObject);
  79. var
  80.   Item: PItem;
  81.   X1, Y1, X2, Y2: Integer;
  82.   Selected: Integer;
  83. begin
  84.   if (Random(10) > 3) then // new rectangle
  85.   begin
  86.     if (Items.Count >= SpinEdit1.Value) then Exit;
  87.     X1 := Random(Width);
  88.     Y1 := Random(Height);
  89.     X2 := X1 + Random(80);
  90.     Y2 := Y1 + Random(80);
  91.     New(Item);
  92.     Item^.X1 := X1;
  93.     Item^.Y1 := Y1;
  94.     Item^.X2 := X2;
  95.     Item^.Y2 := Y2;
  96.     Item^.Color := RGBToColor(Random(255), Random(255), Random(255));
  97.     Items.Add(Item);
  98.   end
  99.   else // remove rectangle
  100.   begin
  101.     if (Items.Count <= 0) then Exit;
  102.     Selected := Random(Items.Count);
  103.     Items.Delete(Selected);
  104.   end;
  105.   Repaint;
  106. end;
  107.  
  108. end.

can you make snake game with those ideas?

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #5 on: September 02, 2017, 04:16:39 am »
Code: [Select]
    if (Items.Count <= 0) then Exit;
    Selected := Random(Items.Count);
    Items.Delete(Selected);
  end;
  Repaint;
end;

end.
[/quote]

instead of deleting random rectangle, can i delete the one that was created a second before?


molly

  • Hero Member
  • *****
  • Posts: 2034
Re: how to delete the canvas rectangle
« Reply #6 on: September 02, 2017, 04:31:15 am »
instead of deleting random rectangle, can i delete the one that was created a second before?
That depends on what you meant by "second before". If by "second before" you meant position then yes. If you meant "second before" as 1000 milliseconds then you are doing something wrong  ;)

Handoko

  • Hero Member
  • *****
  • Posts: 1771
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #7 on: September 02, 2017, 04:38:33 am »
can you make snake game with those ideas?

Yes and No.

Yes, because the ability to draw and delete objects on the screen is the very basic skill needed for game creation. No, because snake game requires more programming skills than you thought.

Creating snake game is not hard but you need to able to understand and use these:

- Multidimensional array
http://wiki.freepascal.org/Multidimensional_arrays

- Reading user input
https://www.freepascal.org/docs-html/rtl/crt/keypressed.html
https://www.freepascal.org/docs-html/rtl/crt/readkey.html
http://wiki.freepascal.org/LCL_Key_Handling

- Collision Detection
Read the simplify version "Hit Testing":
https://en.wikipedia.org/wiki/Hit-testing

- Choosing a Graphics Library
http://wiki.freepascal.org/Graphics_libraries

- Able to use game loop properly
http://gameprogrammingpatterns.com/game-loop.html

Snake is a good project for beginners to learn how to create computer games. But if you have problem to understand all the things mentioned above, it may be to challenging for you. Instead you may try to create animations like falling rectangles, bouncing ball, etc.

Similar to snake is pong game. I think it will be easier because it doesn't need to calculate collision with it's own body and it doesn't need to store data of it's body segments.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #8 on: September 02, 2017, 05:36:15 am »
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  LCLType, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Timer1: TTimer;
    Timer2: TTimer;
    procedure Button1Click(Sender: TObject);

    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);

  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  snake: Trect;
  tail: Trect;
  a:integer;
  b:integer;
  c:integer;
  d:integer;
  direction:integer;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin

 a:=(random(24))*20;
 b:=(random(24))*20 ;
 c:=a+20;
 d:=b+20 ;

 snake.left:=a;
 snake.top:=b;
 snake.right:=c;
 snake.bottom:=d;

 tail.left:=a+40;
 tail.top:=b;
 tail.right:=c+40;
 tail.bottom:=d;






end;



procedure TForm1.Button1Click(Sender: TObject);
begin
  canvas.rectangle(snake.left, snake.top, snake.right, snake.bottom);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
  );
begin

  case direction of
  0:if key in [vk_left] then
     begin
      direction:=3;
     end;


  1:if key in [vk_left] then
     begin
      direction:=1 ;
     end;


  2: if key in [vk_left] then
     begin
      direction:=3;
     end;


  3: if key in [vk_left] then
     begin
      direction:=3;
     end;

  4: if key in [vk_left] then
     begin
      direction:=3;
     end;

  end;

  case direction of
  0:if key in [vk_right] then
     begin
      direction:=1;
     end;


  1:if key in [vk_right] then
     begin
      direction:=1 ;
     end;


  2: if key in [vk_right] then
     begin
      direction:=1;
     end;


  3: if key in [vk_right] then
     begin
      direction:=3;
     end;

  4: if key in [vk_right] then
     begin
      direction:=1;
     end;

  end;

  case direction of
  0:if key in [vk_up] then
     begin
      direction:=4;
     end;


  1:if key in [vk_up] then
     begin
      direction:=4 ;
     end;


  2: if key in [vk_up] then
     begin
      direction:=2;
     end;


  3: if key in [vk_up] then
     begin
      direction:=4;
     end;

  4: if key in [vk_up] then
     begin
      direction:=4;
     end;

  end;


  case direction of
    0:if key in [vk_down] then
       begin
        direction:=2;
       end;


    1:if key in [vk_down] then
       begin
        direction:=2 ;
       end;


    2: if key in [vk_down] then
       begin
        direction:=2;
       end;


    3: if key in [vk_down] then
       begin
        direction:=2;
       end;

    4: if key in [vk_down] then
       begin
        direction:=4;
       end;

end;

end;



procedure TForm1.Timer1Timer(Sender: TObject);

begin
  Canvas.Pen.Color := clBlue;
  Canvas.Brush.Color:=clwhite;
  canvas.rectangle(snake.left, snake.top, snake.right, snake.bottom);


end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  if direction = 1 then
    begin
      snake.left:=snake.left+20;
      snake.right:=snake.right+20;

    end;                       

this is everything i have done but i do not know what to do next. how can i delete the rectangle that has been created before in this coding?

can you make snake game with those ideas?

Yes and No.

Yes, because the ability to draw and delete objects on the screen is the very basic skill needed


shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #9 on: September 02, 2017, 05:50:42 am »
here is the attachment

Handoko

  • Hero Member
  • *****
  • Posts: 1771
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #10 on: September 02, 2017, 06:06:52 am »
You've made a good start. You have potential to be a game programmer.

Have you understand how to use array? You need a 2 dimensional array to store the map information. And one more a single dimension array to store to snake body segment information.

Your code can run on my Linux computer, this is screenshot of your code:

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #11 on: September 02, 2017, 06:25:09 am »
You've made a good start. You have potential to be a game programmer.

Have you understand how to use array? You need a 2 dimensional array to store the map information. And one more a single dimension array to store to snake body segment information.

Your code can run on my Linux computer, this is screenshot of your code:

i understand how to use array but i don't know how to use it in this game.
my code works on my computer as well but i want the rectangles to be deleted every second so the snake can move around with one rectangle.
If you don't mind, can you help me with the coding please? thanks you very much for keep replying to me, i appreciate it a lot!

Handoko

  • Hero Member
  • *****
  • Posts: 1771
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #12 on: September 02, 2017, 06:46:11 am »
I'm currently not at my home. I'll be back maybe 4 hours later.

molly

  • Hero Member
  • *****
  • Posts: 2034
Re: how to delete the canvas rectangle
« Reply #13 on: September 02, 2017, 07:03:12 am »
Not wanting to strip this way form you handoko but 4 hours can be long for someone who is eagerly waiting :)

A little tip for TS: when you want to remove a rectangle, then just do not draw it on the next iteration.

Which brings us to: do not draw on the canvas of a form outside the paint event, use the OnPaint  event for that. You can use invalidate to 'update' your canvas drawing.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #14 on: September 02, 2017, 08:14:48 am »
I'm currently not at my home. I'll be back maybe 4 hours later.
okay thank you

Not wanting to strip this way form you handoko but 4 hours can be long for someone who is eagerly waiting :)

A little tip for TS: when you want to remove a rectangle, then just do not draw it on the next iteration.

Which brings us to: do not draw on the canvas of a form outside the paint event, use the OnPaint  event for that. You can use invalidate to 'update' your canvas drawing.

i'm okay with waiting and thank you for the tips

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus