* * *

Author Topic: collision detection  (Read 2800 times)

J-G

  • Sr. Member
  • ****
  • Posts: 435
Re: collision detection
« Reply #30 on: October 13, 2017, 03:26:57 pm »
can you guys suggest me what i should do to make the the array balls to move like form balls?
I think that you actually mean 'FOAM' balls - where they distort on collision with each other or a bounding wall. That will be a whole different 'ball game' (apologies for the pun!! :-[)  -  and way beyond MY knowledge of graphics programming!
FPC 3.0.0  Lazarus 1.6  Win 7 Ult 64

rvk

  • Hero Member
  • *****
  • Posts: 2869
Re: collision detection
« Reply #31 on: October 13, 2017, 03:40:54 pm »
can you guys suggest me what i should do to make the the array balls to move like form balls?
I think that you actually mean 'FOAM' balls
Haha :D

No, I think he meant the way the other balls (when clicking form shape) move. Those are TShape in the form and not the array of the array balls.

Besides that... The array balls don't follow the main ball at all.
The form balls do follow the main ball but not just all the way. I think they need to follow the direction of the main ball just a but longer before changing direction.

shs

  • Sr. Member
  • ****
  • Posts: 260
Re: collision detection
« Reply #32 on: October 13, 2017, 04:01:11 pm »
oh really? i thought i coded them to follow the main ball. what should i do to make them follow the main ball?

rvk

  • Hero Member
  • *****
  • Posts: 2869
Re: collision detection
« Reply #33 on: October 13, 2017, 04:04:59 pm »
oh really? i thought i coded them to follow the main ball. what should i do to make them follow the main ball?
Please specify what you mean by follow.
Do you want them to act like the snake?
So that each element finally ends up in the same direction but in a straight line after the main ball.

shs

  • Sr. Member
  • ****
  • Posts: 260
Re: collision detection
« Reply #34 on: October 13, 2017, 04:15:46 pm »
yes that's exactly what i want

User137

  • Hero Member
  • *****
  • Posts: 1730
    • Nxpascal home
Re: collision detection
« Reply #35 on: October 13, 2017, 05:29:56 pm »
First thing i see in code is that you have TShape objects with names b1, b2, b3. Snake games always need an array, so first thing you could look into is how to create all circles manually in FormCreate. 3 circles or 100 circles, it doesn't matter. Same code should handle any number. You should know how for-loops work.

edit: Oops, i said that too early.. you had both kinds of ways at least partially.

And i did give formula. What there is now looks more complicated than you needed.

edit2: You actually had the following covered up well. Only issue you had is caused by integer rounding. You need to use floating point values for worm position, so you need a second array. Round the position into integer and copy to shape's left and top values at the end of the loop.
« Last Edit: October 13, 2017, 05:52:16 pm by User137 »

rvk

  • Hero Member
  • *****
  • Posts: 2869
Re: collision detection
« Reply #36 on: October 13, 2017, 05:37:42 pm »
Ok, first let's clean up your code a bit. Remove all components except the timer.
(see attached for cleaned up project)

Second, you have this line:
Code: Pascal  [Select]
  1.     vxx := (ball[i].left - 25) - (ball[i + 1].left - 25);
What are you trying to define with that point?
Is that the middle of the ball or is that the outer edge to which you want to connect the balls?

Now the balls find each other and connect. But as you can see, AFTER they connect, you never ever change the connect point. And you'll notice the initial connect point is always at a 45 degrees angle. That's because you use the vectors for top+radius and left+radius.

Try to change the point where they connect according to the direction the main ball is going. And even if they are connected the follow-balls should still move if they are not connected to the point at 0 (for down direction), 90 (for left), 180 (for up) or 270 (for right) degrees.


User137

  • Hero Member
  • *****
  • Posts: 1730
    • Nxpascal home
Re: collision detection
« Reply #37 on: October 13, 2017, 05:57:33 pm »
Rvk, the math was working. The circle segments were following correctly but didn't turn just enough, because of precision lost on float to integer conversion. You need to keep the floating point positions saved up.

shs

  • Sr. Member
  • ****
  • Posts: 260
Re: collision detection
« Reply #38 on: October 14, 2017, 02:56:13 am »
@rvk
Code: Pascal  [Select]
  1.  vxx := (ball[i].left - 25) - (ball[i + 1].left - 25);
i did that to get the center point but i just realised that it's wrong
it should be
Code: Pascal  [Select]
  1.  vxx := (ball[i].left + 25) - (ball[i + 1].left + 25);

also how should i do this?
Quote
Try to change the point where they connect according to the direction the main ball is going. And even if they are connected the follow-balls should still move if they are not connected to the point at 0 (for down direction), 90 (for left), 180 (for up) or 270 (for right) degrees.

which formula should i change?


@user137
hi i tried to do this
Quote
edit2: You actually had the following covered up well. Only issue you had is caused by integer rounding. You need to use floating point values for worm position, so you need a second array. Round the position into integer and copy to shape's left and top values at the end of the loop.

but i got errors

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  9.   LCLType;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Timer1: TTimer;
  17.     procedure FormCreate(Sender: TObject);
  18.     procedure FormKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
  19.     procedure Timer1Timer(Sender: TObject);
  20.   private
  21.     ball: array of tshape;
  22.     xpos: array of real;
  23.     ypos: array of real;
  24.     { private declarations }
  25.   public
  26.     { public declarations }
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.   direction: integer;
  32.  
  33. implementation
  34.  
  35. {$R *.lfm}
  36.  
  37. { TForm1 }
  38.  
  39. procedure TForm1.FormCreate(Sender: TObject);
  40. var
  41.   i: integer;
  42. begin
  43.    randomize;
  44.  
  45.   setlength(xpos, 3);
  46.   for i := 0 to 3-1 do
  47.   begin
  48.     xpos:= ball[i].Width + random(Width - ball[i].Width);
  49.   end;
  50.  
  51.   setlength(ypos, 3);
  52.   for i := 0 to 3-1 do
  53.   begin
  54.     ypos:=  ball[i].Height + random(Height - ball[i].Height);
  55.   end;
  56.  
  57.  
  58.   setlength(ball, 3);
  59.   for i := 0 to 3 - 1 do
  60.   begin
  61.     ball[i] := Tshape.Create(self);
  62.     ball[i].parent := self;
  63.     ball[i].shape := stcircle;
  64.     ball[i].Width := 30;
  65.     ball[i].Height := 30;
  66.     ball[i].top := ypos[i];
  67.     ball[i].left := xpos[i];
  68.     ball[i].brush.color := clwhite;
  69.     ball[i].pen.color := clwhite;
  70.   end;
  71.   ball[0].brush.color := clred;
  72.  
  73.  
  74. end;                                

Compile Project, Target: project1.exe: Exit code 1, Errors: 6
unit1.pas(48,57) Error: Incompatible types: got "Double" expected "TForm1.{Dynamic} Array Of Real"
unit1.pas(54,62) Error: Incompatible types: got "Double" expected "TForm1.{Dynamic} Array Of Real"
unit1.pas(66,27) Error: Incompatible type for arg no. 1: Got "Double", expected "LongInt"
unit1.pas(67,28) Error: Incompatible type for arg no. 1: Got "Double", expected "LongInt"
unit1.pas(122,49) Error: Incompatible type for arg no. 1: Got "Double", expected "LongInt"
unit1.pas(123,47) Error: Incompatible type for arg no. 1: Got "Double", expected "LongInt"


jamie

  • Full Member
  • ***
  • Posts: 100
Re: collision detection
« Reply #39 on: October 14, 2017, 03:10:14 am »
Xpos and Ypos are dynamic arrays you must index them.

 xpos
  • := ......etc...


jamie

  • Full Member
  • ***
  • Posts: 100
Re: collision detection
« Reply #40 on: October 14, 2017, 03:11:43 am »
Well, it seems the editor here is deleting the brackets. so I guess my post means nothing.
anyway, you need the index the xPOS and yPOS.

shs

  • Sr. Member
  • ****
  • Posts: 260
Re: collision detection
« Reply #41 on: October 14, 2017, 03:23:21 am »
oh thank you i put index for both but i still get these errors

Compile Project, Target: project1.exe: Exit code 1, Errors: 4
unit1.pas(66,27) Error: Incompatible type for arg no. 1: Got "Real", expected "LongInt"
unit1.pas(67,28) Error: Incompatible type for arg no. 1: Got "Real", expected "LongInt"
unit1.pas(122,49) Error: Incompatible type for arg no. 1: Got "Double", expected "LongInt"
unit1.pas(123,47) Error: Incompatible type for arg no. 1: Got "Double", expected "LongInt"

molly

  • Hero Member
  • *****
  • Posts: 1922
Re: collision detection
« Reply #42 on: October 14, 2017, 04:51:08 am »
@jamie:
you can use code tags for that. The forum software "eats" the brackets.

Code: [Select]
xpos[x] := ......etc...
@shs
The compiler already gives you a hint:

Quote
unit1.pas(66,27) Error: Incompatible type for arg no. 1: Got "Real", expected "LongInt"
unit1.pas(67,28) Error: Incompatible type for arg no. 1: Got "Real", expected "LongInt"
unit1.pas(122,49) Error: Incompatible type for arg no. 1: Got "Double", expected "LongInt"
unit1.pas(123,47) Error: Incompatible type for arg no. 1: Got "Double", expected "LongInt"
Depending on your calculation requirements you can use round or trunc for that.

On a sidenote: it isn't very custom (anymore) to define your variables as type real, better use single or double (or as user rvk used type valreal)
« Last Edit: October 14, 2017, 04:55:05 am by molly »

shs

  • Sr. Member
  • ****
  • Posts: 260
Re: collision detection
« Reply #43 on: October 14, 2017, 10:47:39 am »
@molly

hi but user137 said
Rvk, the math was working. The circle segments were following correctly but didn't turn just enough, because of precision lost on float to integer conversion. You need to keep the floating point positions saved up.

so is there any other way to solve this problem without using rounding? or is it okay to use round? there many different opinions for this so i am not really sure which one is right

User137

  • Hero Member
  • *****
  • Posts: 1730
    • Nxpascal home
Re: collision detection
« Reply #44 on: October 14, 2017, 11:08:45 am »
Say you want to move a ball 0.1 to right every turn, so you do
Code: Pascal  [Select]
  1. Ball.Left:=round(Ball.Left+0.1);
But what actually happens is that the ball will not move at all. So you need the position in float

Code: Pascal  [Select]
  1. TVector = record
  2.     x, y: single;
  3.   end;
  4. ...
  5.   BallPos: TVector;
  6. ...
  7. BallPos.x:=BallPos.x+0.1;
  8. Ball.Left:=round(BallPos.x);
Now it would move with small increments.

 

Recent

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