Forum > Games

Simple ball bounce

(1/6) > >>

lazboy10:
Hi!
So my problem is that i have been trying to get a ball to hit another ball and then bounce in the correct angle.
i have working code for the actual collision part, but for the life of me i just cant get the other ball to bounce correctly in the right angle.

My math skills are terrible so im hoping someone could help me with some working code... what i need is the bounce code only, i don't need any velocity or optimized code. just the basic bounce part.

here is my collision code that works:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TestCollision: boolean;var  CentreAX, CentreAY, CentreBX, CentreBY, vDx, vDy, fDist: Single;begin  {red ball}  CentreAX := (Balls[1].Position.X + 24) / 2;  CentreAY := (Balls[1].Position.Y + 24) / 2;  {white ball}  CentreBX := (Balls[0].Position.X + 24) / 2;  CentreBY := (Balls[0].Position.Y + 24) / 2;   vDx := CentreBX - CentreAX;  vDy := CentreBY - CentreAY;   fDist := Sqrt((vDx * vDx) + (vDy * vDy));   if fDist<12 then    Result := True  else    Result := False;end; 

Mr.Madguy:
It's simple conservation of momentum. In case of equal masses velocities are simply swapped and mirrored against plane, that is perpendicular to line between two ball centers. Collision point also lies in a middle of that line. Hit detection - is simple distance measurement between centers. If distance <= 2 radius, then it's hit.

Looks like simple googling gives proper result.

BobDog:

You can look at this.
(simple console graphics only)
Tested win 10, 32 and 64 bit fp.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---   program balls; uses windows;   const    DC_BRUSH=18;    const    DC_PEN=19;        Type V2=object     x,y,dx,dy:single;    radius:integer;     c:longword;      End; type aov=array[1..4] of v2;     function SetDCBrushColor(p:hdc;colour:COLORREF): COLORREF; stdcall external 'gdi32.dll' name 'SetDCBrushColor';    function SetDCPenColor(p:hdc;colour:COLORREF): COLORREF; stdcall external 'gdi32.dll' name 'SetDCPenColor';           function rgb(r:word;g:word;b:word) :longword;   begin   exit(((b Shl 16) Or ((g) Shl 8) Or (r) Or $FF000000)- $FF000000)   end;   procedure hidecursor(); var    consoleHandle:handle;     info:CONSOLE_CURSOR_INFO ;     begin     consolehandle := GetStdHandle(STD_OUTPUT_HANDLE);     info.dwSize := 100;     info.bVisible := FALSE ;     SetConsoleCursorInfo(consoleHandle, @info);     End;          procedure MoveAndDraw(wh:hdc;var b:aov);     var lx,ly:single;i,r,j:integer;     begin     for i:=low(b) to high(b) do     begin     lx:=b[i].x;ly:=b[i].y;     r:=b[i].radius;     SetDCBrushColor(wh,rgb(0,0,0));     SetDCPenColor(wh,rgb(0,0,0));     ellipse(wh,trunc(lx-r),trunc(ly-r),trunc(lx+r),trunc(ly+r));     b[i].x:=b[i].x+b[i].dx;     b[i].y:=b[i].y+b[i].dy;     SetDCBrushColor(wh,b[i].c);     SetDCPenColor(wh,b[i].c);     for j:=0 to 5 do     ellipse(wh,trunc(b[i].x-r),trunc(b[i].y-r),trunc(b[i].x+r),trunc(b[i].y+r));     end;     end;          procedure HandleEdges(var b:aov);     var i,r:integer;     begin     for i:=low(b) to high(b) do     begin     r:=b[i].radius;     if (b[i].x<r) then begin b[i].x:=r;b[i].dx:=-b[i].dx; end;     if (b[i].x>(800-r)) then begin b[i].x:=800-r;b[i].dx:=-b[i].dx; end;          if (b[i].y<r) then begin b[i].y:=r;b[i].dy:=-b[i].dy; end;     if (b[i].y>(600-r)) then begin b[i].y:=600-r;b[i].dy:=-b[i].dy; end     end;          end;           function HandleBallCollisions(Var b:aov):boolean ;Var  L,impulsex,impulsey,dot,impactx,impacty: single;  ma,mb,f1,f2: single;  n1,n2: Integer;  flag:boolean=false;Begin  For n1 :=low(b) To high(b) -1 Do    Begin      For n2 :=n1+1 To high(b) Do        Begin          L := Sqrt( (b[n1].x-b[n2].x)*(b[n1].x-b[n2].x) + (b[n1].y-b[n2].y)*(b[n1].y-b[n2].y));          If L< (b[n1].radius+b[n2].radius) Then            Begin            flag:=true;              impulsex := (b[n1].x-b[n2].x)/L ;              impulsey := (b[n1].y-b[n2].y)/L ;              // in case of large overlap (non analogue motion)              b[n1].x := b[n2].x+(b[n1].radius+b[n2].radius)*impulsex ;              b[n1].y := b[n2].y+(b[n1].radius+b[n2].radius)*impulsey ;               impactx := b[n1].dx-b[n2].dx ;              impacty := b[n1].dy-b[n2].dy ;              dot := impactx*impulsex+impacty*impulsey ;              ma := b[n1].radius;              mb := b[n2].radius;              ma := ma*ma;   // weigh by area (radius squared)              mb := mb*mb;              f1 := 2*mb/(ma+mb);   // ball weight factors              f2 := 2*ma/(ma+mb);              b[n1].dx:= b[n1].dx-dot*impulsex *f1;              b[n1].dy:= b[n1].dy-dot*impulsey *f1;               b[n2].dx:=b[n2].dx+ dot*impulsex *f2 ;               b[n2].dy:= b[n2].dy+dot*impulsey *f2 ;            End;        End; // n2    End;  // n1    exit(flag);End;        Var  p:hwnd;  wh:hdc; b:aov; beginb[1].x:=100;b[1].y:=200;b[1].dx:=0.06;b[1].dy:=0.04;b[1].radius:=45;b[1].c:=rgb(255,100,0); b[2].x:=500;b[2].y:=300;b[2].dx:=-0.06;b[2].dy:=-0.08;b[2].radius:=40;b[2].c:=rgb(0,255,0); b[3].x:=200;b[3].y:=500;b[3].dx:=0.06;b[3].dy:=-0.07;b[3].radius:=35;b[3].c:=rgb(0,0,255); b[4].x:=300;b[4].y:=400;b[4].dx:=-0.06;b[4].dy:=0.07;b[4].radius:=30;b[4].c:=rgb(0,100,255);  p := GetConsoleWindow();setwindowpos(p, HWND_TOPMOST, 100, 100, 810, 630,SWP_SHOWWINDOW);    wh:=GetDC(p);    SelectObject(wh,GetStockObject(DC_BRUSH));    SelectObject(wh,GetStockObject(DC_PEN));     hidecursor;     ShowScrollBar(p, SB_BOTH, FALSE);    while true do    beginMoveAndDraw(wh,b);HandleEdges(b);if HandleBallCollisions(b) then //clearscreen- optionalbegin    SetDCBrushColor(wh,rgb(0,0,0));    SetDCPenColor(wh,rgb(0,0,0));    rectangle(wh,0,0,810,630);end;     end; end.  

speter:
In case anyone is interested, here is a GUI version of BobDog's code.

cheers
S.

loaded:

--- Quote from: speter on February 01, 2022, 08:30:56 am ---In case anyone is interested, here is a GUI version of BobDog's code.

--- End quote ---
I am one of those who are interested.
Many thanks for the code, BobDog  and speter

Navigation

[0] Message Index

[#] Next page

Go to full version