Recent

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

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #75 on: October 03, 2017, 09:57:20 am »
Have you forget the GetItem?
Use GetItem(x, y) = snake the check if that location is occupied by snake body.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #76 on: October 03, 2017, 10:13:26 am »
oh so how should i use that to find all the snake body location?

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #77 on: October 03, 2017, 10:20:31 am »
Code: Pascal  [Select][+][-]
  1.  getitem(snakesegment^.left, snakesegment^.top):=snake;      

it says unit1.pas(515,4) Error: Argument can't be assigned to

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #78 on: October 03, 2017, 10:40:47 am »
GetItem is a function, you can't set value for a function.

Here is example code for put new fruit:

Code: Pascal  [Select][+][-]
  1.   repeat
  2.     FoodPos.Left := Random(WorldWidth+1);
  3.     FoodPos.Top  := Random(WorldHeight+1);
  4.   until (GetItem(FoodPos.Left, FoodPos.Top) = Empty);
  5.   PutItem(Foodpos.Left, FoodPos.Top, Fruit);

I haven't test the code above, but it should work.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #79 on: October 03, 2017, 10:47:21 am »
yes it works really well :)

how should i do collision?
Code: Pascal  [Select][+][-]
  1.      if getitem(snakesegment^.left, snakesegment^.top)= snake then
  2.       begin
  3.        timer1.enabled:=false;
  4.       end;    

i tired this but does not work

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #80 on: October 03, 2017, 10:53:18 am »
You do not have to check the SnakeBody. You can simple check the GameWorld, which is simpler and easier.

function IsSnakeThere(X, Y: Integer): Boolean;
begin
  result := (GetItem(X, Y) = Snake);
end;

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #81 on: October 03, 2017, 11:10:54 am »
You do not have to check the SnakeBody. You can simple check the GameWorld, which is simpler and easier.

function IsSnakeThere(X, Y: Integer): Boolean;
begin
  result := (GetItem(X, Y) = Snake);
end;

but how can i check if the head hits its own tail?

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #82 on: October 03, 2017, 11:33:09 am »
Why do you need to check if it is head or tail? But if you want, here the code:

Code: Pascal  [Select][+][-]
  1. IsSnakeHeadThere(X, Y: Integer): Boolean;
  2. var
  3.   SnakeSegment: PRect;
  4. begin
  5.   result := False;
  6.   if (SnakeBody.Count <= 0) then Exit;
  7.   SnakeSegment := SnakeBody[0];
  8.   if (SnakeBody^.Top = Y) and (SnakeBody^.Left = X) then result := True;
  9. end;
  10.  
  11. IsSnakeTailThere(X, Y: Integer): Boolean;
  12. var
  13.   SnakeSegment: PRect;
  14. begin
  15.   result := False;
  16.   if (SnakeBody.Count <= 1) then Exit; // if only 1 segment, then there is no tail
  17.   SnakeSegment := SnakeBody[SnakeBody.Count-1];
  18.   if (SnakeBody^.Top = Y) and (SnakeBody^.Left = X) then result := True;
  19. end;

Again, I haven't tested the code above but I believe it should work.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #83 on: October 03, 2017, 11:39:31 am »
so if the head hits its own tail it's supposed to die right? do i need to check if it is head or tail? can i do it in other way or?

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #84 on: October 03, 2017, 11:43:25 am »
You can simply add some code at the beginning of Timer1Timer:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. var
  3.   i:integer;
  4. begin
  5.   snakepos.left := snakepos.left + xdirection;
  6.   snakepos.top  := snakepos.top  + ydirection;
  7.   if (GetItem(snakepos.left, snakepos.top) = Snake) then // the snake hits its own body
  8.   begin
  9.     // do something here
  10.   end;
  11.   ...
  12.  

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #85 on: October 03, 2017, 11:56:03 am »
Code: Pascal  [Select][+][-]
  1.  if (GetItem(snakepos.left, snakepos.top) = Snake) then // the snake hits its own body
  2.   begin
  3.     timer1.enabled:=false;
  4.   end;

i did this and the timer stopped as soon i compiled it. i think it's because the snake head is part of 'Snake' item so maybe that's why it doesn't work

how should i do?

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #86 on: October 03, 2017, 11:58:23 am »
Okay, I know what is wrong. Please provide your complete code. I will check where is wrong. And give me some time.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: how to delete the canvas rectangle
« Reply #87 on: October 03, 2017, 12:05:54 pm »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   SnakeSegment: PRect;
  4. begin
  5.   SnakeBody := TList.Create;
  6.   snakepos.left:=random(24);
  7.   snakepos.top:=random(24);
  8.  
  9.   foodpos.left:=random(24);
  10.   foodpos.top:=random(24);
  11.  
  12.   New(SnakeSegment);
  13.   SnakeSegment^ := snakepos;
  14.   SnakeBody.Add(SnakeSegment);
  15.  
  16.   drawgameworld;
  17.  
  18.   edit1.clear;
  19.  
  20. end;
  21.  
  22. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  23. begin
  24.   SnakeBody.Free;
  25.  
  26. end;
  27.  
  28.  
  29.  
  30. procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
  31.   );
  32. begin
  33.  
  34.   if score >= 1 then
  35.     begin
  36.       case direction of
  37.         1,3,4: if key=vk_left then
  38.            begin
  39.            direction:=1;
  40.            end;
  41.         2: if key=vk_left then
  42.            begin
  43.            direction:=2;
  44.            end;
  45.       end;
  46.  
  47.       case direction of
  48.         2,3,4: if key=vk_right then
  49.            begin
  50.            direction:=2;
  51.            end;
  52.         1: if key=vk_right then
  53.            begin
  54.            direction:=1;
  55.            end;
  56.       end;
  57.  
  58.       case direction of
  59.         1,2,3: if key=vk_up then
  60.            begin
  61.            direction:=3;
  62.            end;
  63.         4: if key=vk_up then
  64.            begin
  65.            direction:=4;
  66.            end;
  67.       end;
  68.  
  69.       case direction of
  70.         1,2,4: if key=vk_down then
  71.            begin
  72.            direction:=4;
  73.            end;
  74.         3: if key=vk_down then
  75.            begin
  76.            direction:=3;
  77.            end;
  78.     end;
  79.   end;
  80.  
  81.   if score = 0 then
  82.     begin
  83.       if key=vk_left then
  84.         begin
  85.          direction:=1;
  86.         end;
  87.  
  88.       if key=vk_right then
  89.         begin
  90.          direction:=2;
  91.         end;
  92.  
  93.       if key=vk_up then
  94.         begin
  95.          direction:=3;
  96.         end;
  97.  
  98.       if key=vk_down then
  99.         begin
  100.          direction:=4;
  101.         end;
  102.   end;
  103. end;
  104.  
  105. procedure TForm1.Timer1Timer(Sender: TObject);
  106. var
  107.   i:integer;
  108. begin
  109.  
  110.   case direction of
  111.     1:  begin
  112.           xdirection:=-1;
  113.           ydirection:=0;
  114.         end;
  115.     2:  begin
  116.           xdirection:=1;
  117.           ydirection:=0;
  118.         end;
  119.     3:  begin
  120.           xdirection:=0;
  121.           ydirection:=-1;
  122.         end;
  123.     4:  begin
  124.           xdirection:=0;
  125.           ydirection:=1;
  126.         end;
  127.   end;
  128.  
  129.  
  130.    if (snakepos.left = foodpos.left) and (snakepos.top = foodpos.top)  then
  131.      begin
  132.        foodpos.left:=random(22)+1;
  133.        foodpos.top:=random(22)+1;
  134.        PutItem(foodpos.left, foodpos.top, fruit);
  135.  
  136.        snakeisgrowing:=true;
  137.        score:=score+1;
  138.        count.caption:=inttostr(score);
  139.      end;
  140.  
  141.    if (snakepos.left > 23) or (snakepos.left < 1) or (snakepos.top > 23) or (snakepos.top < 1)  then
  142.      begin
  143.       for i:= 3 to 5 do
  144.         begin
  145.          (FindComponent('l' + IntToStr(i)) as TLabel).visible:=true;
  146.         end;
  147.         timer1.enabled:=false;
  148.         edit1.Visible:=true;
  149.         button1.Visible:=true;
  150.         l4.caption:= count.caption;
  151.         count.visible:=false;
  152.         clearworld;
  153.         putitem(foodpos.left, foodpos.right, emtpy);
  154.      end;
  155.  
  156.    snakepos.left:=snakepos.left+xdirection;
  157.    snakepos.top:=snakepos.top+ydirection;
  158.    MoveSnake(snakepos);
  159. end;
  160.  
  161. procedure TForm1.ClearWorld;
  162. var
  163.   X, Y: Integer;
  164. begin
  165.   for X := 1 to WorldWidth do
  166.     for Y := 1 to WorldHeight do
  167.       GameWorld[X, Y] := Emtpy;
  168. end;
  169.  
  170. procedure TForm1.PutItem(X, Y: Integer; Item: TItem);
  171. begin
  172.   if (X < 1) or (X > WorldWidth) then Exit;
  173.   if (Y < 1) or (Y > WorldHeight) then Exit;
  174.   GameWorld[X, Y] := Item;
  175. end;
  176.  
  177. function TForm1.GetItem(X, Y: Integer): TItem;
  178. begin
  179.   Result := Emtpy;
  180.   if (X < 1) or (X > WorldWidth) then Exit;
  181.   if (Y < 1) or (Y > WorldHeight) then Exit;
  182.   Result := GameWorld[X, Y];
  183. end;
  184.  
  185. procedure TForm1.DrawGameWorld;
  186. const
  187.   Padding = 0;
  188. var
  189.   X, Y: Integer;
  190.   ScreenX, ScreenY: Integer;
  191. begin
  192.   Refresh;
  193.   for X := 1 to WorldWidth do
  194.     for Y := 1 to WorldHeight do
  195.       begin
  196.         ScreenX := X * Scale;
  197.         ScreenY := Y * Scale;
  198.         case GameWorld[X, Y] of
  199.           Emtpy: ; // do nothing
  200.           Snake: begin
  201.                    Canvas.Pen.Color := shape1.brush.color;
  202.                    Canvas.Brush.Color := clwhite;
  203.                    Canvas.Rectangle(ScreenX, ScreenY, ScreenX+Scale, ScreenY+Scale);
  204.                  end;
  205.           Fruit: begin
  206.                    Canvas.Pen.Color := shape1.brush.color;
  207.                    Canvas.Brush.Color := clRed;
  208.                    Canvas.rectangle(ScreenX+padding, ScreenY+padding, ScreenX+Scale-padding, ScreenY+Scale-padding);
  209.                  end;
  210.           end;
  211.       end;
  212. end;
  213.  
  214. procedure TForm1.MoveSnake(NewHead: TRect);
  215. var
  216.   SnakeSegment: PRect;
  217. begin
  218.   New(SnakeSegment);
  219.   SnakeSegment^ := NewHead;
  220.   SnakeBody.Insert(0, SnakeSegment);
  221.   if not(SnakeIsGrowing) then
  222.    begin
  223.     SnakeSegment := SnakeBody[SnakeBody.Count-1];
  224.     PutItem(SnakeSegment^.Left, SnakeSegment^.Top, Emtpy);
  225.     Freemem(SnakeSegment);
  226.     SnakeBody.Delete(SnakeBody.Count-1);
  227.    end;
  228.   SnakeIsGrowing := False;
  229.   PutItem(snakepos.left, snakepos.top, snake);
  230.   PutItem(foodpos.left, foodpos.top, fruit);
  231.  
  232.   if (snakeSegment^.left = snakepos.left) and snakesegment^.top = snakepos.top) then
  233.    begin
  234.     timer1.enabed:=true;
  235.    end;
  236.  
  237.   Drawgameworld;
  238. end;
  239.  
  240. end.
  241.                  

bee

  • Sr. Member
  • ****
  • Posts: 393
Re: how to delete the canvas rectangle
« Reply #88 on: October 03, 2017, 12:18:38 pm »
@Handoko… well done, bro. You're so patient and helpful. Respect!

And, you should blog all these snake game tutorial. Many newbies could learn from it. :)
-Bee-

A long time pascal lover.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: how to delete the canvas rectangle
« Reply #89 on: October 03, 2017, 01:00:04 pm »
@bee

I am afraid I do not have time to do blogging. But I am preparing a short game creation tutorial - The Furious Paladin - the game I submitted for Graphics Contest 2017. Newbies can learn many interesting tricks from the tutorial.

@shs

You have not provided the complete code, I can compile it. Please provide them as the zip file.

 

TinyPortal © 2005-2018