matwachich Posted June 8, 2011 Share Posted June 8, 2011 I'm making a 2D games engin, which includes a small physics enginhere is the code that controls the ellastic collision between 2 objects ($hSprite1, $hSprite2) inspired from This linkLocal $dist = _GEng_SpriteToSprite_Dist($hSprite1, $hSprite2) ; the distance between the 2 objects Local $nx, $ny, $gx, $gy $nx = ($hSprite2[$_gSpr_PosX] - $hSprite1[$_gSpr_PosX]) / $dist $ny = ($hSprite2[$_gSpr_PosY] - $hSprite1[$_gSpr_PosY]) / $dist $gx = -1 * $ny $gy = $nx ; --- Local $v1n, $v1g, $v2n, $v2g $v1n = $nx * $hSprite1[$_gSpr_SpeedX] + $ny * $hSprite1[$_gSpr_SpeedY] $v1g = $gx * $hSprite1[$_gSpr_SpeedX] + $gy * $hSprite1[$_gSpr_SpeedY] $v2n = $nx * $hSprite2[$_gSpr_SpeedX] + $ny * $hSprite2[$_gSpr_SpeedY] $v2g = $gx * $hSprite2[$_gSpr_SpeedX] + $gy * $hSprite2[$_gSpr_SpeedY] ; --- If $hSprite1[$_gSpr_Masse] > 0 Then $hSprite1[$_gSpr_SpeedX] = $nx * $v2n + $gx * $v1g $hSprite1[$_gSpr_SpeedY] = $ny * $v2n + $gy * $v1g EndIf If $hSprite2[$_gSpr_Masse] > 0 Then $hSprite2[$_gSpr_SpeedX] = $nx * $v1n + $gx * $v2g $hSprite2[$_gSpr_SpeedY] = $ny * $v1n + $gy * $v2g EndIfthis code conciders that the 2 objects have the same mass, but i want to be able to compute collisions between object of different mass, and i don't know where to insert the mass variable ($hSpriteX[$_gSpr_Masse]) in the equationsNeed help please! Link to comment Share on other sites More sharing options...
UEZ Posted June 8, 2011 Share Posted June 8, 2011 (edited) Look at the code in where you can enable mass on the balls.Btw, there are plenty tutorial for collision detection in the web - just ask Google...Br,UEZ Edited June 8, 2011 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Mat Posted June 8, 2011 Share Posted June 8, 2011 I advise you get physics textbook Momentum = mass * velocity Total momentum before is the same as after. AutoIt Project Listing Link to comment Share on other sites More sharing options...
martin Posted June 8, 2011 Share Posted June 8, 2011 (edited) I'm making a 2D games engin, which includes a small physics engin here is the code that controls the ellastic collision between 2 objects ($hSprite1, $hSprite2) inspired from This link Local $dist = _GEng_SpriteToSprite_Dist($hSprite1, $hSprite2) ; the distance between the 2 objects Local $nx, $ny, $gx, $gy $nx = ($hSprite2[$_gSpr_PosX] - $hSprite1[$_gSpr_PosX]) / $dist $ny = ($hSprite2[$_gSpr_PosY] - $hSprite1[$_gSpr_PosY]) / $dist $gx = -1 * $ny $gy = $nx ; --- Local $v1n, $v1g, $v2n, $v2g $v1n = $nx * $hSprite1[$_gSpr_SpeedX] + $ny * $hSprite1[$_gSpr_SpeedY] $v1g = $gx * $hSprite1[$_gSpr_SpeedX] + $gy * $hSprite1[$_gSpr_SpeedY] $v2n = $nx * $hSprite2[$_gSpr_SpeedX] + $ny * $hSprite2[$_gSpr_SpeedY] $v2g = $gx * $hSprite2[$_gSpr_SpeedX] + $gy * $hSprite2[$_gSpr_SpeedY] ; --- If $hSprite1[$_gSpr_Masse] > 0 Then $hSprite1[$_gSpr_SpeedX] = $nx * $v2n + $gx * $v1g $hSprite1[$_gSpr_SpeedY] = $ny * $v2n + $gy * $v1g EndIf If $hSprite2[$_gSpr_Masse] > 0 Then $hSprite2[$_gSpr_SpeedX] = $nx * $v1n + $gx * $v2g $hSprite2[$_gSpr_SpeedY] = $ny * $v1n + $gy * $v2g EndIf this code conciders that the 2 objects have the same mass, but i want to be able to compute collisions between object of different mass, and i don't know where to insert the mass variable ($hSpriteX[$_gSpr_Masse]) in the equations Need help please! I assume you mean how do you allow for the different masses in your calculations of the resulting speeds. Based on that here are my meandering thoughts, and there might be others who can give better answers as always. The first thing I would think about is that enery and momentum must be conserved. So I would work out the momentum in x and y before the collision and make sure that the momentum was the same after the collision. I would assume a perfectly elestic collision; ie no energy given upo to friction in the collision. I don't actually know how 2 bodies respond to collisions so let's try a straight line collision. Say the small one is S and the big one is G, velocity of S is Vs and for B it's Vb. Mass of S is Ws and of B is Wb. so Initial total momentum is Mt = Ms + Mb = Wb * Vb + Ws * Vs After the collision each some momentum will be transferred from one to the other, and what's lost by one is gained by the other. The velocities after collision are say Rs and Rb for (rebound vel) so Ms * Rs + Mb * Rb = Ms * Vs + Mb * Vb (i) Say the change in velocity for S is J. Then the change in velocity for B will be K given by K*Mb = -J * Ms (ii) Since Rs = Vs + J and Rb = Vb - J * Ms/Mb we can write (i) again lik ethis Ms * (Vs + J) + Mb *(Vb - J * Ms/Mb) = Ms * Vs + Mb * Vb which only has J as an unknown so we can work it out. Now treat the X and Y components as I did the in-line example and I think you should be able to calculate the changes in velocity depending on the initial velocities and the relative masses. Since this is written as I think it up it neds to be treated with sceptism, but so far it sounds reasonable to me. EDIT: Typos Edited June 8, 2011 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
matwachich Posted June 8, 2011 Author Share Posted June 8, 2011 Ok! thanks! I inspired from the UEZ example and here is the result If Not __GEng_Sprite_IsSprite($hSprite2) Then Return SetError(1, 0, 0) ; --- Local $dist = _GEng_SpriteToSprite_Dist($hSprite1, $hSprite2) Local $mass_tot = $hSprite1[$_gSpr_Masse] + $hSprite2[$_gSpr_Masse] Local $nx, $ny, $gx, $gy $nx = ($hSprite2[$_gSpr_PosX] - $hSprite1[$_gSpr_PosX]) / $dist $ny = ($hSprite2[$_gSpr_PosY] - $hSprite1[$_gSpr_PosY]) / $dist $gx = -1 * $ny $gy = $nx ; --- Local $v1n, $v1g, $v2n, $v2g $v1n = $nx * $hSprite1[$_gSpr_SpeedX] + $ny * $hSprite1[$_gSpr_SpeedY] $v1g = $gx * $hSprite1[$_gSpr_SpeedX] + $gy * $hSprite1[$_gSpr_SpeedY] $v2n = $nx * $hSprite2[$_gSpr_SpeedX] + $ny * $hSprite2[$_gSpr_SpeedY] $v2g = $gx * $hSprite2[$_gSpr_SpeedX] + $gy * $hSprite2[$_gSpr_SpeedY] ; --- ;calculate new vectors according to mass $v_p1 = ($hSprite1[$_gSpr_Masse] - $hSprite2[$_gSpr_Masse]) / $mass_tot * $v1n + 2 * $hSprite2[$_gSpr_Masse] / $mass_tot * $v2n $v_p2 = ($hSprite2[$_gSpr_Masse] - $hSprite1[$_gSpr_Masse]) / $mass_tot * $v2n + 2 * $hSprite1[$_gSpr_Masse] / $mass_tot * $v1n ; --- If $hSprite1[$_gSpr_Masse] > 0 Then $hSprite1[$_gSpr_SpeedX] = $nx * $v_p1 + $gx * $v1g $hSprite1[$_gSpr_SpeedY] = $ny * $v_p1 + $gy * $v1g EndIf If $hSprite2[$_gSpr_Masse] > 0 Then $hSprite2[$_gSpr_SpeedX] = $nx * $v_p2 + $gx * $v2g $hSprite2[$_gSpr_SpeedY] = $ny * $v_p2 + $gy * $v2g EndIf It works just as i need. The very big problem is the 'orbiting effect', here is how i solved it (partially, failing at high speed moving objects) expandcollapse popupLocal $rat1x, $rat1y ; ratio de vitesse x/y Local $rat2x, $rat2y ; ratio de vitesse x/y ; --- If $hSprite1[$_gSpr_SpeedX] = 0 Then $rat1x = 0 $rat1y = 1 ElseIf $hSprite1[$_gSpr_SpeedY] = 0 Then $rat1x = 1 $rat1y = 0 Else $rat1x = $hSprite1[$_gSpr_SpeedX] / (Abs($hSprite1[$_gSpr_SpeedY]) + Abs($hSprite1[$_gSpr_SpeedX])) $rat1y = $hSprite1[$_gSpr_SpeedY] / (Abs($hSprite1[$_gSpr_SpeedY]) + Abs($hSprite1[$_gSpr_SpeedX])) EndIf ;ConsoleWrite($rat1x & " , " & $rat1y & @CRLF) ; --- If $hSprite1[$_gSpr_SpeedX] < 0 Then $rat1x = -1 * Abs($rat1x) Else $rat1x = Abs($rat1x) EndIf If $hSprite1[$_gSpr_SpeedY] < 0 Then $rat1y = -1 * Abs($rat1y) Else $rat1y = Abs($rat1y) EndIf ; --- ; --- If $hSprite2[$_gSpr_SpeedX] = 0 Then $rat2x = 0 $rat2y = 1 ElseIf $hSprite2[$_gSpr_SpeedY] = 0 Then $rat2x = 1 $rat2y = 0 Else $rat2x = $hSprite2[$_gSpr_SpeedX] / (Abs($hSprite2[$_gSpr_SpeedY]) + Abs($hSprite2[$_gSpr_SpeedX])) $rat2y = $hSprite2[$_gSpr_SpeedY] / (Abs($hSprite2[$_gSpr_SpeedY]) + Abs($hSprite2[$_gSpr_SpeedX])) EndIf ;ConsoleWrite($rat2x & " , " & $rat2y & @CRLF) ; --- If $hSprite2[$_gSpr_SpeedX] < 0 Then $rat2x = -1 * Abs($rat2x) Else $rat2x = Abs($rat2x) EndIf If $hSprite2[$_gSpr_SpeedY] < 0 Then $rat2y = -1 * Abs($rat2y) Else $rat2y = Abs($rat2y) EndIf ; --- Local $x = 0 Do If $hSprite1[$_gSpr_Masse] > 0 Then If $hSprite1[$_gSpr_PosX] > $hSprite1[$_gSpr_OriX] And _ $hSprite1[$_gSpr_PosY] > $hSprite1[$_gSpr_OriY] And _ $hSprite1[$_gSpr_PosX] < $__GEng_WinW - $hSprite1[$_gSpr_OriX] And _ $hSprite1[$_gSpr_PosY] < $__GEng_WinH - $hSprite1[$_gSpr_OriY] Then $hSprite1[$_gSpr_PosX] += $rat1x $hSprite1[$_gSpr_PosY] += $rat1y EndIf EndIf If $hSprite2[$_gSpr_Masse] > 0 Then If $hSprite2[$_gSpr_PosX] > $hSprite2[$_gSpr_OriX] And _ $hSprite2[$_gSpr_PosY] > $hSprite2[$_gSpr_OriY] And _ $hSprite2[$_gSpr_PosX] < $__GEng_WinW - $hSprite2[$_gSpr_OriX] And _ $hSprite2[$_gSpr_PosY] < $__GEng_WinH - $hSprite2[$_gSpr_OriY] Then $hSprite2[$_gSpr_PosX] += $rat2x $hSprite2[$_gSpr_PosY] += $rat2y EndIf EndIf ;ConsoleWrite($rat1x & " , " & $rat1y & @CRLF) ;ConsoleWrite($rat2x & " , " & $rat2y & @CRLF) $x += 1 ;ConsoleWrite(" >>> " & $x & @CRLF) If $x = 10 Then ;ConsoleWrite("Max!" & @CRLF) ExitLoop EndIf Until Not _GEng_Sprite_Collision($hSprite1, $hSprite2, 0) ; check collision between the sprites (recursive call) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now