Recent

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

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #90 on: October 03, 2017, 01:38:39 pm »
Okay, you need a variable to indicate the game have just started but the snake is not moving yet. Reading your code I found that you can use "direction = 0" for this purpose.

So in your Timer1Timer event put this code before MoveSnake(snakepos):
Code: Pascal  [Select][+][-]
  1. if (GetItem(snakepos.left, snakepos.top) = Snake) and not(Direction = 0) then
  2.   begin
  3.     timer1.enabled:=false;
  4.   end;

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #91 on: October 03, 2017, 01:49:50 pm »
it shows up on the screen now but when i press key (when i change direction ), the timer1 stops. so i think
it's not becasue of the direction

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #92 on: October 03, 2017, 01:53:45 pm »
Really? It works correctly on my computer. Try to replace your Timer1.Timer with this one:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. var
  3.   i:integer;
  4. begin
  5.   case direction of
  6.     1:  begin
  7.           xdirection:=-1;
  8.           ydirection:=0;
  9.         end;
  10.     2:  begin
  11.           xdirection:=1;
  12.           ydirection:=0;
  13.         end;
  14.     3:  begin
  15.           xdirection:=0;
  16.           ydirection:=-1;
  17.         end;
  18.     4:  begin
  19.           xdirection:=0;
  20.           ydirection:=1;
  21.         end;
  22.   end;
  23.  
  24.  if (snakepos.left = foodpos.left) and (snakepos.top = foodpos.top)  then
  25.    begin
  26.  
  27.     repeat
  28.     FoodPos.Left := Random(22)+1;
  29.     FoodPos.Top  := Random(22)+1;
  30.     until (GetItem(FoodPos.Left, FoodPos.Top) = Emtpy);
  31.      growing:=true;
  32.      score:=score+4;
  33.      count.caption:=inttostr(score);
  34.  
  35.      drawgameworld;
  36.    end;
  37.  
  38.  if (snakepos.left > 23) or (snakepos.left < 1) or (snakepos.top > 23) or (snakepos.top < 1)  then
  39.    begin
  40.     for i:= 3 to 5 do
  41.       begin
  42.        (FindComponent('l' + IntToStr(i)) as TLabel).visible:=true;
  43.       end;
  44.       timer1.enabled:=false;
  45.       edit1.Visible:=true;
  46.       button1.Visible:=true;
  47.       l4.caption:= count.caption;
  48.       count.visible:=false;
  49.       clearworld;
  50.       putitem(foodpos.left, foodpos.right, emtpy);
  51.    end;
  52.  
  53.    snakepos.left:=snakepos.left+xdirection;
  54.    snakepos.top:=snakepos.top+ydirection;
  55.    if (GetItem(snakepos.left, snakepos.top) = Snake) and not(Direction = 0) then
  56.    begin
  57.      timer1.enabled:=false;
  58.    end;
  59.    MoveSnake(snakepos);
  60. end;

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: how to delete the canvas rectangle
« Reply #93 on: October 03, 2017, 02:00:51 pm »
Could not help this one. Properly deletes a canvas...:
« Last Edit: October 03, 2017, 02:04:49 pm by Thaddy »
Specialize a type, not a var.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #94 on: October 03, 2017, 02:03:07 pm »
Is it your own monitor?

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: how to delete the canvas rectangle
« Reply #95 on: October 03, 2017, 02:06:50 pm »
 O:-) Canvas.free Set the canvas free... :P
Specialize a type, not a var.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #96 on: October 03, 2017, 02:10:24 pm »
@handoko

thank you it works :)

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #97 on: October 03, 2017, 02:12:58 pm »
@Thaddy

Not just simply freeing the canvas but FreeAndNil(Canvas);

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #98 on: October 03, 2017, 02:29:47 pm »
@shs

Congratulation, you've managed to create your first game using Lazarus. It is cross platform, it works on my Linux too! ;)


But here one thing I should told you. Do you remember I said you need to free the memory of the snake's tail? So in the form closing you should free each memory of the body segments. Here I provide you the pseudocode:

For each item in SnakeBody do begin
   Set SnakeSegment to point to the memory location
   Free the SnakeSegment
end

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: how to delete the canvas rectangle
« Reply #99 on: October 03, 2017, 02:57:44 pm »
@Thaddy

Not just simply freeing the canvas but FreeAndNil(Canvas);
https://community.embarcadero.com/blogs/entry/a-case-when-freeandnil-is-your-enemy-38916

If you NEED FreeAndNil there is usually something wrong with either you skills or the architecture....It belongs to "bordercase" programmers or bordercase - as in seldom needed - code.
I respect your skills, so it must be the other  ::) :o case?

Pascal is too easy in this case: a C or C++ programmer would got bitten... That's why they are not likely to make such mistakes...( they crashed too many times..)

FreeAndNil is for experienced programmers. Beginners should just free... It's like driving a Tesla in autodrive and not realizing you will cause an accident.
Or a malfunctioning parachute: guy hanging on it thinks everything ok, still flying....
« Last Edit: October 03, 2017, 03:08:54 pm by Thaddy »
Specialize a type, not a var.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #100 on: October 03, 2017, 03:25:06 pm »
I was kidding, no need to be serious.  :D

I know the different between Free and FreeAndNil. I know for sure that some cases Free only is not enough, must use FreeAndNil.

Mick

  • Jr. Member
  • **
  • Posts: 51
Re: how to delete the canvas rectangle
« Reply #101 on: October 03, 2017, 04:56:41 pm »
https://community.embarcadero.com/blogs/entry/a-case-when-freeandnil-is-your-enemy-38916
Hmm, Thaddy, but did you read carefully that blog post you are referring to?
Quote from the blog post: "You rely on the fact that it is nil to know that you need to allocate it. This may seem like the perfect case where you should use FreeAndNil! That is in-fact the very problem. There are cases where you should FreeAndNil in this scenario."

If you NEED FreeAndNil there is usually something wrong with either you skills or the architecture....It belongs to "bordercase" programmers or bordercase - as in seldom needed - code.
With all due respect, but this is a bold statement, imho too generalized. Then what should you do in order to indicate that the variable or property that you manage does not store the object instance anymore because the instance was already destroyed? Set to nil. So what's the difference and where is the evil of FreeAndNil in this case?

FreeAndNil is for experienced programmers. Beginners should just free...
But the beginners (and I believe the experienced ones as well) should also set the variable that stored the reference to the destroyed instance to nil.
So they can use FreeAndNil, it's designed for that purpose, isn't it?

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #102 on: October 03, 2017, 11:35:28 pm »
isn't it this?
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  2. begin
  3.   SnakeBody.Free;
  4.  
  5. end;      

Mick

  • Jr. Member
  • **
  • Posts: 51
Re: how to delete the canvas rectangle
« Reply #103 on: October 04, 2017, 02:02:37 am »
It is.

In my post I was only trying to tell that Thaddy's criticism for FreeAndNil went too far (imho).

In this particular case you are probably perfectly fine with using Free only. That's because you do it in the FormClose event handler, which I believe is the main form of your application. So after this handler will be executed and the destructor called on the instance referenced by the SnakeBody variable / property, you will probably never try to reference the SnakeBody variable / property again, because application will be terminated. So it doesn't really matter if the property still stores the reference of already destroyed instance.

However, if you would add FormDestroy handler (which is executed later in the TForm class lifetime), any attempt of referencing the SnakeBody there would give you access violations, obviously. You could try to prevent from that by checking if SnakeBody is nil (to mark that this variable / property is "invalid"). But you did not set the SnakeBody to nil after freeing it, either by simple assignment of nil to your SnakeBody, or calling FreeAndNil (which does exactly as the name suggest, fist Free, then assing nil - that's why it takes the parameter as var, so it can modify it).

My conclusion - as long as you will not try to "reuse" that variable that stored the instance that was destroyed, you are perfectly fine. But if you would need to "reuse" it (e.g. check if it is still valid, make decision if you need create new one, etc) - assign nil to the variable that stored the reference to the destroyed / freed instance, either by assigning nil after calling Free, or by calling FreeAndNil.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #104 on: October 04, 2017, 04:33:41 am »
 @shs

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  2. var
  3.   SnakeSegment: PRect;
  4.   i: Integer;
  5. begin
  6.   For i := 0 to (SnakeBody.Count - 1) do
  7.     begin
  8.       SnakeSegment := SnakeBody[i];
  9.       FreeMem(SnakeSegment);
  10.     end;
  11.   SnakeBody.Free;
  12.   ...

 

TinyPortal © 2005-2018