Need a good physics tutorial

Started by
7 comments, last by DesignerX 16 years, 10 months ago
I need a good physics tutorial which describes how to control objects movements with the mouse (using springs as some people suggested) and how to compute collision detection between two circles (or flat cylinders) and response to it as well. I'm writing an Air Hockey game and have no idea how to start with the game physics (i.e. collision between the mallet and the hockey puck etc...) I tried some brute forced approaches but had no success (only frustration :/) I'd be really thankfull if someone could refer me to a good tutorial relevant to the described above. thx alot.
There is nothing that can't be solved. Just people that can't solve it. :)
Advertisement
If the game is 2D or atleast if the physics could be handled in 2D then the physics would be pretty similar to those of a 2D pool game and pool physics should be pretty easy to find tutorials for on the internet. As far as the mouse part goes just subtract the mallets position from the mouse position, scale that to a certain speed and add that vector to the velocity. Oh, and if you do that you probably need to have a pretty high friction on the mallets speed or it might end up in orbit around the mouse.

edit: replaced "position or velocity" with "velocity"




[Edited by - Alrecenk on May 26, 2007 3:18:51 PM]
This article
hosted on gamasutra might be what you are looking for.

Cheers.
Quote:Original post by Alrecenk
As far as the mouse part goes just subtract the mallets position from the mouse position, scale that to a certain speed and add that vector to the position or the velocity. Oh, and if you add it to the velocity you probably need to have a pretty high friction on the mallets speed or it might end up in orbit around the mouse.


This is wrong, as discussed in the other tread. There are several disadvantages to doing mouse control that way. The best way to do it is to let the physics engine take care of everything and just attach a spring with rest length 0 and a high spring constant between the object and mouse.
Yeah, adding to position would be bad, but adding to velocity and having friction works fine in my experience. The only difference between this and a spring system is that force doesn't change based on how far away the mouse is. As long as the acceleration is high it should work fine. If someone is asking questions like this I think it's fairly safe to assume they don't have a physics engine to call spring functions on, and might appreciate a better description of what you are suggesting.
Aressera is right about the mouse movements. I tried the substraction method and when I move the mouse very fast the mallet doesn't collide with the hockey puck (since the offset is quite large it just appears after the puck instead of colliding with it)

Aressera, can you plz refer me to a good tutorial about the springs subject ?
Alrecenk, can you plz elaborate some more about your method ? is it accurate enough ?

[Edit]
CableGuy, I started to read the article and it looks very promising, thx.

[Edited by - DesignerX on May 27, 2007 2:39:20 PM]
There is nothing that can't be solved. Just people that can't solve it. :)
Ok, so to make sure I wasn't completely wrong I wrote a test program. The main differences between the two methods is that with what I suggested the mallet will lag behind the mouse quite a bit more than if you use the spring method, but my method limits the amount of force that can be applied with the mallet since moving the mouse faster does not increase the acceleration of the mallet. My suggestion at this point is to go with what Aressera said and just do some sort of hack if you need to limit the amount of force that can be applied. And here's some pseudocode for that:

//vector to mousea[0] = mx-p[0] ;a[1] = my-p[1] ;//scale based on constant and the distance^2double m = ac*dot(a,a) ;a = setlength(a,m) ;//add that scaled vector to velocityv[0]+=a[0] ;v[1]+=a[1] ;//apply airresistanceb[0] = v[0] ;b[1] = v[1] ;b = setlength(b,Math.max(length(b)-f*m,0)) ;v[0] = b[0] ;v[1] = b[1] ;

The only difference between the methods being the " *dot(a,a) " which my orgininal suggestion did not include.

edit: and in regards to it not colliding that's probably because either your acceleration and velocity are too high or your timestep is not small enough. You can probably fix that by decreasing the speed of everything and calculating the physics more times per second. If you don't have the cycles to spare to do that then you could move to swept collission stuff but that'll be alot harder.
Quote:Original post by DesignerX
Aressera, can you plz refer me to a good tutorial about the springs subject ?


well, for starters, hook's law is the main thing that you need to know:

|F| = -k*dx

where |F| is the magnitude of the spring force, k is the spring constant and dx is the current length of the spring minus it's resting length:

dx = x - x0

where x is the current length of the spring and x0 is the resting length of the spring (the length when the spring is not attached to anything)

you can find x by using the distance formula:

x = sqrt( (x1 - x2)^2 + (y1 - y2)^2 )

where (x1, y1) is on end of the spring in 2D space and (x2, y2) is the other end. These two points should be on different objects (the mouse and the controlled object in your case). Therefore every time you update the physics, you set (x1, y1) to be the current coordinates of the mouse. You then calculate the spring force's magnitude by setting (x2, y2) to be the current position of the controlled object and going through with the necessary calculations.

Once you have the spring force's magnitude, you need to convert this to a vector quantity for 2D physics calculations as shown:

vector n = < x1 - x2, y1 - y2 >

vector F = |F|*(n/|n|)

n is the vector from the object to the mouse's position. In this calculation you first find n, then you normalize n by dividing it by it's magnitude, and then finally multiply |F| by this vector. The resulting vector is the spring force for the object. If for instance you wanted to have the spring between 2 different objects instead of 1 object and the mouse, you would just negate this vector and that would be the spring force for the other object. Code for this:

[Source]void applySpringForce( Object* object1, Object* object2, double k, double x0 ){    // find n    Vector3 n = object1->position - object2->position;        // the magnitude of n happens to be the current length of the spring    double nMag = n.magnitude();        // find the spring force's magnitude (Hook's law)    double fMag = -k*( nMag - x0 );        // the normalized n    Vector3 nu = n / nMag;        // calculate the forces    Vector3 force1 = fMag*nu;    Vector3 force2 = -fMag*nu;        // apply the forces    object1->applyForce( force1 );    object2->applyForce( force2 );}[/Source]




This code isn't perfect, and it doesn't allow for the spring to be attached anywhere other than the center of each object. Adding this functionality isn't hard though.

---------------------------------

Once you have the spring force between the two objects, you can then integrate it (along with gravity, etc) using the simple Euler's method and Newton's 2nd law of motion:

Newton's 2nd law:

?F = ma

where ?F is the sum of all forces (gravity, spring, friction, etc..), m is mass, and a is the acceleration of the object. Keep in mind that all of these quantities are all vectors (except for mass).

Euler integration:

v = v + (?F / m)*dt
x = x + v*dt

where v is the velocity of an object, x is the position, and dt is the time interval that you are integrating over.

That's all for now. look around if you want more, I especially recommend reading all of the article on Chris Hecker's site about physics: http://chrishecker.com/Rigid_Body_Dynamics
Aressera, your approach seems very promising, thx for the detailed explanation. ( I will apply it as soon as I'll return to my physics part in my game)

Thank you all for your replies. You all have been very helpful.
There is nothing that can't be solved. Just people that can't solve it. :)

This topic is closed to new replies.

Advertisement