I am developing a mini golf game in Scenekit. I have applied dynamic physics body to the ball and static physics body to the grass surface and the brick walls show in this image.
Issue:
When I apply the force to the ball, the ball’s linear and angular speeds change as shown in the graphs. The ball’s speeds don’t reduce to zero (so that the ball can stop) but remains constant after certain value.
Ball linear speed graph
Ball angular speed graph
Analysis Tests:
When I increase the values to both the rolling friction and the friction, the ball speed is reduced quickly but remains constant after certain value (similar to the above graphs).
When I increase the values of the linear damping and the angular damping, the ball speed behavior is same as the point #1.
When I set the gravity value to -9.8 m/s2, the ball’s linear speed remains constant after 0.1 m/s. If I reduce the gravity value to -5 m/s2, the ball’s linear speed remains constant after 0.05 m/s.
The friction, linear friction, linear damping and angular damping are same throughout the motion of the ball.
There is 1 millimeter overlapping between the ball and the surface of the golf course.
Questions:
From the analysis test #3, I think the gravity is causing the constant ball speed issue. Is my assumption correct? If yes, how can I fix the issue? I can’t remove the gravity field as without the gravity field the ball will not roll along the grass and it will slide.
Why the friction and the damping properties are not affecting the ball speed after certain value?
Are there any other physics properties can cause such issue?
From the analysis test #5, are there any chances that the ball is receiving upward push to correct the position of the ball?
Solutions:
After reducing the gravity value to -1 m/s2 and physics simulation speed to 4 (4 times fast physics simulation), the issue is fixed. However, I am worried that these settings will cause issues in further development of the game.
If I increase the physics timestep from 60 FPS to 200 FPS, the issue is resolved. How solution 2 can fix this issue?
I would appreciate any suggestions and thoughts on this topic. Thank you.
Related
I am developing a simple Golf game as shown in the below image.
I am facing below issues:
Even if I apply small amount of force, the ball continuous move along the grass? Grass friction is not stopping the ball.
Sometimes, the ball speed is increased after colliding with the walls instead the ball speed should decreased after collision with the walls. The walls are having box collider.
Sometimes, the ball reverses its direction after colliding with walls.
Code:
Physics properties of the ball:
ball.physicsBody.affectedByGravity = true;
ball.physicsBody.mass = 0.0450;
ball.physicsBody.restitution = 0.8;
ball.physicsBody.friction = 0.3;
ball.physicsBody.allowsResting = true;
Physics properties of the grass:
golf.physicsBody.friction = 0.8;
Physics properties of the walls:
leftWall.physicsBody.friction = 0;
leftWall.physicsBody.restitution = 0.8;
I have set the physics world gravity value to -9.8.
I am looking for suggestions to fix the above listed issue. Thank you.
To stop rolling, in a 3D physics world, you need angular damping, or linear damping, or a bit of both.
The friction component, when dealing with a rapidly spinning ball, can transpose to increased rate of movement, upon collisions.
A ball spinning in the reverse direction to its travel vector may have enough angular momentum to reverse its direction of travel when its friction is sufficient for it to gain traction on surfaces it collides with.
I'm building a relatively simple game in SpriteKit where you can bounce a ball based on a user's touch location, using something like ball.physicsBody.applyImpulse(someVector).
I've been trying to understand how to gravity and vectors work by playing with the values of the physicsWorld.gravity vector and the vector of impulse I apply on the ball and I think I need some clarification;
If I use this code:
self.physicsWorld.gravity = CGVectorMake(0, -10)
ball.physicsBody.applyImpulse(CGVectorMake(0, 10))
Shouldn't the ball, based on this code and according to common sense not move at all, as the pulling and pushing forces are equal, or at least go up the exact distance of 10 before starting to fall in this case?
In reality what happens is that the ball does bounce up and is going a distance of over 10 pixels up.
Why is it behaving like that, and what exact value do I need to use for the vectors to cancel out so that the ball remains completely still?
I'd be happy for any sort of explanation, Thanks in advance.
That 10 is not pixels, for gravity, it is meters per second, so you need to take the 10 and divide by FPS to get 1 frame, (1/6 meter) and then you need to figure out what meter to pixel ratio is, and that will get you the number of pixels. For impulse, it is Newton seconds, which is pushing 1 kilogram 1 meter per second. So you need to figure out the mass of the item to figure out how many meters it is really moving per second. So if your objects mass was 1 KG, then it would balance to 0. I am not going to do the actual math to tell you how to calculate this stuff, you will have to research on your own.
In Summary:
Gravity unit is meters per second
Impulse unit is newtown second AKA kilogram meter per second
You need to match units in order for things to balance out to 0
See https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKPhysicsBody_Ref/#//apple_ref/occ/instm/SKPhysicsBody/applyImpulse: and https://developer.apple.com/library/mac/documentation/SpriteKit/Reference/SKPhysicsWorld_Ref/index.html#//apple_ref/occ/instp/SKPhysicsWorld/gravity if you want to learn more.
I have a physics body that is uneven but not dynamic (the terrain) and a physics body (character) that is dynamic and is on top of the terrain, and I want this character to move along the terrain simulating kind of a "walking" action where it will keep going up the terrain but it won't fall back (or move back) like a ball because of gravity, and to set a maximum tilt so that it does not tip over.
My attempt was to add a force in the direction I want the character to move but this is causing the character to fall back due to gravity, and I don't want to disable gravity because then character won't fall down when going down the terrain.
Thank you very much
this is why using a physics engine for a platforming game is very difficult and not always a great approach..
you can try sprite.physicsBody.allowsRotation = false
might help
Create SKAction to move your character to destination point or dx and dy. Run that SKAction from your character node with the runAction. Like
SKAction.moveByX(...
When the action is finished, gravity will bring the character down.
If the movement is slow, play with the character's physicsBody friction and/or mass.
You can also change the the character's physicsBody.velocity = CGVectorMake(
And your terrain will be better with edgeLoop physicsBody which won't be dynamic.
And with uneven you mean inclined but smooth? If not smooth and with edges, your character may get held up at an edge depending on center of gravity of character and if you are allowing rotation.
Alright, so I'm trying to create my own Physics engine for a 3D XNA game, and I'm having troubles calculating how much I should move my object by for gravity.
XNA's game timer occurs every 16 milliseconds, so after some calculations, and using 9.81m/s as my gravitational velocity, you can see that you should increase the velocity of the object that has gravity by:
0.15696 meters/16milliseconds
- basically every update call should increase the object by 0.15696 meters
The questions is, how do I convert 0.15696 meters into pixels. Obviously if I just use a 1:1 relationship the object will only move 9.81 pixels/second. Which does not really simulate gravity :P Does anyone have a good idea on how I can determine how many pixels I should move the object by?
Thanks for all the help!
Although 2d game dev is more pixel-centric, 3d game dev doesn't concern itself with pixels for this kind of stuff, but rather units. Unit size is completely arbitrary.
Typically, you have a velocity vector whose magnitude is equivalent to the meters(or feet or ??) per second that your object is going. That way the position is updated each frame by adding this velocity * the elapsed time since last frame (the 16.6666 ms). The acceleration from gravity is added to the velocity vector in the same way:
Vector3 gravity = Vector3.Down * 9.81f;
//in the update loop
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;//0.01666667 (or 16.67 ms) # 60FPS
velocity += gravity * elapsed;
position += velocity * elapsed;
In this example, I've arbitrarily established that 1 xna unit == 1 meter.
You just have to figure out how large an "area" your screen represents; then its simple scaling. If you have a 2D representation of a satellite orbiting earth, then your "Y" pixels represent ground to satellite (approximately 35,000 meters).
Use your equations from classical physics (http://en.wikipedia.org/wiki/List_of_equations_in_classical_mechanics), and then just scale real dimensions to your screen.
I have a rotating sphere that the user rotates by applying a virtual force, like a virtual accelerator. I want to be able to simulate a nice momentum effect so that when they lift off the accelerator the ball winds down in speed in a natural and realistic way, as if due to friction and/or gravity. I don't want to get into any deep physics equations. I'd like to do this quick so if I could find a code sample that shows how to do this, or even a page of formulas clear enough that I could encode, that would be great.
I'd like a formula that has one or two adjustable coefficients that I could tune to make the ball decelerate faster or slower depending on my needs. I don't want to get into anything heavy like an open source physics library or the like. Just something simple.
I'm using Delphi 6 Pro but I also know C/C++, Basic, Java, and Javascript.
Velocity is change in displacement. Acceleration is change in velocity.
Gravity or friction just causes an acceleration (possibly negative).
So all you need to do is apply a negative acceleration when they do not activate the accelerator.
So lets assume you have an angle that is changing. Applying the accelerator increases the amount the angle changes by each iteration or time step. If your angle is t and your change in angle is called dt (angular velocity) then when the accelerator is applied you'll have:
t = t + dt
dt = dt + a
where a depends on how much force you're applying, or how much they've 'pressed' the accelerator (i.e. this is the acceleration).
You'll probably want to limit dt (i.e. speed of rotation) - if you only want to spin in one direction you'll have an upper positive limit and a lower limit of 0. If you want both directions, you can have a lower negative limit and an upper positive limit.
All you need to do is make a some negative number when the accelerator is not applied (if dt is positive - make a positive if dt is negative), and ensure you don't 'wrap' (i.e. make dt 0 when it gets near 0).
It has been some time ago, but according to my dynamics study books the Mass Moment of Inertia for a sphere is defined as I=(2/5)m*r^2. m is the mass, r is the radius of the sphere (all in SI untis). On this page you'll find some examples to use the mass moment of inertia to calculate deceleration of the sphere as a result of the applied negative torque. This toqrue is a result of the friction. Since you are not defining the material of the surface of the sphere and the surroudings you cannot calculate the friction and will have to choose a good force yourself.
As long as you are not solving stellar problems, I don't see how gravity has much to do with decelerating the rotation.
Friction is almost proportional to the current rotation speed (actually the speed on the surface of the sphere).
So a formula for the current rotation speed over time w(t) may be something like this:
w(t) = w0*exp(-c*(t - t0))
with t0 being the time the friction starts, wt being the rotation speed at that time.
The coefficient c > 0 determines how fast the speed will decrease - the higher c, the faster the speed will go down. This formula is valid for all t >= t0.
Note that for t = t0 the exp function returns 1 and you get the initial speed, while for t -> ∞ the exp function (and so the resulting speed) returns -> 0 (the minus in front of the c guarantees this).
You've already accepted an answer, but I'll put in my piece.
I'll assume you already know how to make the sphere spin at a constant rate, and how to make it accelerate under the applied torque. Making it decellerate is just a matter of applying another torque, one that must be calculated.
When an object slides on a solid surface, the rate of deceleration is constant. The force is in the direction opposite to motion, and its magnitude depends on a couple of things but not speed. When the object comes to a full stop, the force vanishes. The same applies to a globe turning on a solid pivot.
When an object passes through a fluid, the force of decelleration increases with speed, so the faster the object the greater the drag. As the object slows down, decelleration grows weaker, and the object keeps slowing down but never stops. This describes a globe spinning in air or water. At reasonably high speeds, drag is proporional to v2, and at very low speeds it is proportional to v (I don't know about the transition between these domains).
So I suggest t = -a wb, where w is angular velocity. The parameter a is the strength of the friction, and b describes the kind of decelleration; b=0 is like friction on a solid pivot, b=2 is like spinning in air, and b=1 is like rotating in syrup. Other values of b may or may not look realistic or be realistic.