Simple "bouncing ball" physics?
Blitz3D Forums/Blitz3D Beginners Area/Simple "bouncing ball" physics?
| ||
I'm a bit of a physics newbie, so I'll need help with this... What variables would need to be defined in order to allow simple "bouncing ball" physics to be obtained? Currently, I have worked out that my ball needs to have a mass, and that a value for gravity needs to be defined. I would like my ball to bounce realistically off the walls of a cuboid 3D room. However, my game is not like Pong, so I don't want the ball to have a constant velocity - rather, I'd like it to be influenced by gravity. (Basically, what I mean by this is that even if the ball hits a wall or even the ceiling, it will ultimately hit the floor again anyway due to gravity.) If anyone could offer some more help as to how to go about implementing basic "bouncing ball" physics in 3D, then I'd love to hear it, as I currently have absolutely no idea what I'm doing when it comes to physics - but I realise that if I want to program games, then I'd need some sort of physics knowledge to be able to simulate different things. What I'd like to eventually have with this game is a gravity value for each level (taking 10 as Earth's gravity), so that I can change the way the ball bounces (how high it bounces, or how slowly it falls) with different levels. I'd also like the ball's left/right movement controllable using the keyboard, so that you can move the bouncing ball over an obstacle course, which will be the point of my game. Sorry for the long post, thanks for your time, and many thanks in advance for your help. I get easily confused when it comes to matters of physics, so please try and explain this to me in as newbie-friendly a way as possible. Thanks. |
| ||
This is how i've done it in the past. Not with Blitz but in other languages. Hope I remembered it right... ;You need variables for speed for each vector SpeedX=0 SpeedY=0 SpeedZ=0 ;Then you need vector speeds Dx=0 Dy=0 Dz=0 ;Then you need flags for adding or subtracting vector speeds DirX=1 DirY=1 DirZ=1 ;Then you need to calculate speed for each vector SpeedX=SpeedX+(Dx*DirX) SpeedY=SpeedY+(Dy*DirY) SpeedZ=SpeedZ+(Dz*DirZ) ;Then you need to take into account gravity if Dy>0 then Dy=Dy-Gravity ;Then you need to take into account boundaries ;and perform an elastic transfer of inertia If EntityX<min or EntityX>max then DirX=DirX * (-1) If EntityY<min or EntityY>max then DirY=DirY * (-1) if EntityZ<min or EntityZ>max then DirZ=DirZ * (-1) ;Then finally, if you want the ball to eventually slow ;down then subtract a resistance force from vector speeds. if Dx>0 then Dx=Dx-.1 else Dx=0 if Dy>0 then Dy=Dy-.1 else Dy=0 if Dz>0 then Dz=Dz-.1 else Dz=0 |
| ||
Hmm... so how would I take into account the mass of the ball, considering I want the bouncing effect to change depending on how heavy the ball is? We have gravity, but eventually, I want to have different ball materials which will affect the ball's mass, and therefore its bounce: like rubber (normal bounce), steel (littler bounce) and glass (paperweight style - no bounce, just roll)... I will fiddle with the example you've given though. Thanks for that. It is much appreciated, for now, at least I have something to start with. :) However, even though I'm fiddling, nothing is yet final. I'm still open to suggestions. |
| ||
Hi, there is a code for simple ball boucing (with gravity, friction) which was used millions of times. This code appears often on this forum. But I am not sure who writes it (swift ?) and where is this code. Maybe in the code archive? Anyway, try to do a search on this forum. The code is very simple, and yet perfect for what you want to do! |
| ||
All objects fall at the same rate regardless of their mass (Isaac Newton). The only thing the mass of the ball would change would be collisions with other balls of lesser or greater mass (not equal transfer of vector inertia). As for different materials, that would also only change the transfer of inertia when hitting other objects or the wall. (ie: a rubber ball may rebound with 99% of the energy it hits the wall whereas a bowling ball may only transfer 20% of its energy in a collision). |
| ||
Here's some code to cut-n-paste ------------------------------- ; Bouncing ball physics ; Const GRAVITY#=-.05 Graphics3D 640,480 ;Lets create the floor Room=CreateTerrain(64) PositionEntity room,-32,0,-32 ;Create Ball RedBall=CreateSphere(8) EntityColor RedBall,255,0,0 ;Create Camera camera=CreateCamera() PositionEntity camera,0,5,-16 ;Variables for Ball x#=0 y#=20 ;set ball 20 units above floor z#=0 dx#=0 ;at rest dy#=0 ;at rest dz#=0 ;at rest elasticity#=.75 ;value from >0 to <1 (1=pure elastic collision) While Not KeyHit(1) If y=<1 Then y=1 dy=-dy dy=dy * elasticity End If If y>=1 Then dy=dy + GRAVITY x=x+dx y=y+dy z=z+dz End If PositionEntity RedBall, x, y, z UpdateWorld RenderWorld Flip Wend End |
| ||
Apocalypse (Posted 2004-01-31 11:01:46) All objects fall at the same rate regardless of their mass (Isaac Newton). Really, so if I throw you and a feather out of an airplane at 1000 feet you both will hit the ground at the same time? What school did you go to? I am sure Isaac Newton is turning in his grave. Here's some theory for you:- The magnitude of terminal velocity depends on the weight of the falling body. For a heavy object, the terminal velocity is generally greater than a light object. This is because air resistance is proportional to the falling body's velocity squared. For an object to experience terminal velocity, air resistance must balance weight. An example that shows this phenomenon was the classic illustration of a rock and a feather being dropped simultaneously. In a vacuum with zero air resistance, these two objects will experience the same acceleration. But on the earth this is not true. Air resistance will equal weight more quickly for the feather than it would for the rock. Thus the rock would accelerate longer and experience a terminal velocity greater than the feather. Another factor that affects terminal velocity is the orientation at which a body falls. If an object falls with a larger surface area perpendicular to the direction of motion it will experience a greater force and a smaller terminal velocity. On the other hand, if the object fell with a smaller surface area perpendicular to the direction of motion, it will experience a smaller force and a greater terminal velocity. |
| ||
This version bounces in all three axis and uses the Blitz logo as a texture for the ball to give the appearance of actually rolling. Simple and basic. You will need to make sure you have the image file blitzlogo.bmp to run the demo now. ----------------------------------------------------------- ; Bouncing ball physics ; Const GRAVITY#=-.05 Graphics3D 640,480 ;Lets create the floor Room=CreateTerrain(64) PositionEntity room,-32,0,-32 ;Create Ball RedBall=CreateSphere(8) ;EntityColor RedBall,255,0,0 FlipMesh RedBall txt=LoadTexture("blitzlogo.bmp") EntityTexture RedBall, txt ;Create Camera camera=CreateCamera() PositionEntity camera,0,15,-45 SeedRnd (MilliSecs()) ;Variables for Ball x#=0 y#=20 ;set ball 20 units above floor z#=0 dx#=Rand(5) dy#=0;at rest dz#=Rand(5) elasticity#=.8 ;value from >0 to <1 (1=pure elastic collision) friction#=.01 PointEntity camera, RedBall While Not KeyHit(1) If KeyHit(57) Then ;Variables for Ball x#=0 y#=20 ;set ball 20 units above floor z#=0 dx#=Rand(5) dy#=0;at rest dz#=Rand(5) End If If y=<1 Then y=1 dy=-dy dy=dy * elasticity End If If x=<-32 Then x=-32 dx=-dx dx=dx * elasticity End If If x>=32 Then x=32 dx=-dx dx=dx * elasticity End If If z=<-32 Then z=-32 dz=-dz dz=dz * elasticity End If If z>=32 Then z=32 dz=-dz dz=dz * elasticity End If If y>=1 Then dy=dy + GRAVITY y=y+dy End If x=x+dx z=z+dz dx=dx-(dx*friction) dz=dz-(dz*friction) ;Move ball to new coords PositionEntity RedBall, x, y, z ;Rotate mesh to give appearance of rolling RotateMesh RedBall, -dz*100,0,-dx*100 UpdateWorld RenderWorld Text 0,5,"Press ESC to Exit" Text 0,15,"Press SPACE to throw ball" Flip Wend End |
| ||
[joncom2000] >>Really, so if I throw you and a feather out of an airplane at 1000 feet you both will hit the ground at the same time? What school did you go to? I am sure Isaac Newton is turning in his grave<< You are speaking about a completely different set of physics when you talk about wind resistance. The original post was speaking to a general algorithm for bouncing a ball, not a feather. Your pedantic rant, while wonderfully written, is woefully out of place for this discussion. PS: Throw your feather and a bowling ball on the moon and they both indeed fall at the same rate. Isaac Netwon rolling in his grave INDEED! |
| ||
The magnitude of terminal velocity depends on the weight of the falling body. No. There is no 'weight' aspect to physics. There is mass and force. For a heavy object, the terminal velocity is generally greater than a light object. No. Weight has nothing to do with it. This is because air resistance is proportional to the falling body's velocity squared. No. The two most significant factors are speed and cross-sectional area of the object. For an object to experience terminal velocity, air resistance must balance weight. No. Terminal velocity is reached when air resistance becomes as great a force as the acceleration of gravity, thus preventing any further acceleration.Here's some good info on Newtons Second Law. |
| ||
Flameduck, this is taken from the site you point to Terminal velocity occurs when the air resistance (sometimes called "drag") force equals the weight iof the falling object. This means that: the object is falling with a constant velocity - its acceleration is zero. heavy objects will have a higher terminal velocity than light objects. Therefore, heavy objects will fall faster in air than light objects. So your saying my previous post is wrong yet the site you point to says basicly the same thing? Ok no problem. Apocalypse, sorry, I do not imply that your coded example is incorrect, it does exactly as the original poster requested :) I just disagree with your statement on Newton's theory. But enough of that, you have given a good example of simulating a bouncing ball, lets let Ash see how he get's on and put the topic back on track :) |
| ||
Hmmmmmmm... I've been playing around with your example, Apocalypse, and I've found that it's good if you specify the position values absolutely. However, I'm currently toying with the idea of using the Blitz collision system to handle collisions with the ground and walls - because my level is not just a box... It's a CShop level with ramps and obstacles, and I want an easy way to handle all the collisions. The gravity works until the ball collides with the level; after that, it gets stuck on the ground and does not bounce back up. Here's the code I have: If Not EntityCollided(Player(i)\Model, COLTYPE_Level) Then Player(i)\dY = Player(i)\dY + MAP_CurrentMap\Gravity Player(i)\Y = Player(i)\Y + Player(i)\dY ElseIf EntityCollided(Player(i)\Model, COLTYPE_Level) Then Player(i)\Y = CollisionY(Player(i)\Model, 1) + 0.1 ResetEntity Player(i)\Model DebugLog Player(i)\Y Player(i)\dY = -Player(i)\dY DebugLog Player(i)\dY Player(i)\dY = Player(i)\dY * Player(i)\Elasticity Player(i)\Y = Player(i)\Y + Player(i)\dY EndIf PositionEntity Player(i)\Model, Player(i)\X, Player(i)\Y, Player(i)\Z When the ball hits the ground, the values of Player(i)\Y and Player(i)\dY get stuck in this loop: 0.1 -10.0 0.1 10.0 Why does this happen, and how can I get the ball to bounce back up, rather than stay on the ground like a vegetable? (I'm only working with the Y axis for now - once I get the Y axis working, I can just use the same principle for the X and Z axes, to enable collisions on the walls.) Your help is much appreciated. |
| ||
Here is the new and improved version.; ; Bouncing ball physics - by Vincent DeCampo 2/1/04 ; Const GRAVITY#=-.05 Const BALLS=1 Const GROUND=2 Graphics3D 640,480 ;*** Type for Ball *** Type Ball_Object Field Entity Field Pivot Field x# Field y# Field z# Field dx# Field dy# Field dz# Field xMin# Field xMax# Field yMin# Field yMax# Field zMin# Field zMax# Field elasticity# Field friction# End Type Collisions BALLS, BALLS, 1, 2 Collisions BALLS, GROUND,2, 3 ;*** Lets create the floor *** Room=CreateTerrain(64) PositionEntity room,-32,0,-32 EntityColor Room, 0, 150, 0 Plane1=CreateTerrain(64) EntityColor Plane1, 160,0,0 PositionEntity Plane1,-48,32,-32 RotateEntity Plane1,0,0,-45 EntityType Plane1, GROUND Plane2=CreateTerrain(64) EntityColor Plane2, 0,0,170 PositionEntity Plane2,0,-16,-32 RotateEntity Plane2,0,0,45 EntityType Plane2, GROUND ;******* Create Initial Ball ****** Blitz.Ball_Object = New Ball_Object InitBallVars(Blitz) ;***** Create Camera ***** camera=CreateCamera() PositionEntity camera,0,35,-50 PointEntity camera, Blitz\Entity ;********************************** ; Main Loop ;********************************** ; While Not KeyHit(1) If KeyHit(57) Then ;***** Seed RND Generator ***** SeedRnd (MilliSecs()) ;*** Create New Ball *** Blitz.Ball_Object = New Ball_Object InitBallVars Blitz End If ;**** Perform Room Physics **** For Ball.Ball_Object = Each Ball_Object BallPhysics (Ball) Next UpdateWorld ;**** Perform Ball-on-Ball Physics **** CheckCollisions (Blitz) RenderWorld Text 0,5,"Press SPACE to throw another ball" Text 0,15,"Press ESC to Exit" Flip Wend End ;********************************** Function CheckCollisions (Ball.Ball_Object) For C.Ball_Object = Each Ball_Object If EntityCollided(c\Entity, BALLS) > 0 For i = 1 To CountCollisions(c\Entity) Ent=CollisionEntity (c\Entity, i) ;Get the normal of the surface which the entity collided with. Nx# = CollisionNX(c\Entity, i) Ny# = CollisionNY(c\Entity, i) Nz# = CollisionNZ(c\Entity, i) ;Compute the dot product of the entity's motion vector And the normal of the surface collided with. VdotN# = (c\dx# * Nx# + c\dy# * Ny# + c\dz# * Nz#) ;Calculate the normal force. NFx# = -2.0 * Nx# * VdotN# NFy# = -2.0 * Ny# * VdotN# NFz# = -2.0 * Nz# * VdotN# ;Add the normal force to the direction vector. c\dx# = c\dx# + NFx#/2 c\dy# = c\dy# + NFy#/2 ;Force /2 assumes balls equal in mass c\dz# = c\dz# + NFz#/2 For Hit.Ball_Object = Each Ball_Object If Hit\Entity = Ent Then ;Add negative force to collision entity vector Hit\dx# = Hit\dx# - NFx#/2 Hit\dy# = Hit\dy# - NFy#/2 ;Force /2 assumes balls equal in mass Hit\dz# = Hit\dz# - NFz#/2 End If Next Next Else If EntityCollided(c\Entity, GROUND) >0 For i = 1 To CountCollisions(c\Entity) Ent=CollisionEntity (c\Entity, i) ;Get the normal of the surface which the entity collided with. Nx# = CollisionNX(c\Entity, 1) Ny# = CollisionNY(c\Entity, 1) Nz# = CollisionNZ(c\Entity, 1) ;Compute the dot product of the entity's motion vector And the normal of the surface collided with. VdotN# = (c\dx# * Nx# + c\dy# * Ny# + c\dz# * Nz#) ;Calculate the normal force. NFx# = -2.0 * Nx# * VdotN# NFy# = -2.0 * Ny# * VdotN# NFz# = -2.0 * Nz# * VdotN# ;Add the normal force to the direction vector. c\dx# = c\dx# + NFx# c\dy# = c\dy# + NFy# c\dz# = c\dz# + NFz# Next End If End If Next End Function ;********************************** Function InitBallVars(Ball.Ball_Object) ;Create Ball Ball\Entity=CreateSphere(16) ScaleEntity Ball\Entity, 1,1,1 EntityType Ball\Entity, BALLS txt=LoadTexture("blitzlogo.bmp") EntityTexture Ball\Entity, txt ;Create Pivot Ball\Pivot=CreatePivot() ;*** Variables for Ball *** Ball\x#=0 Ball\y#=20 ;set ball 20 units above floor Ball\z#=0 Ball\dx#=Rand(10-5) Ball\dy#=0 ;at rest Ball\dz#=Rand(10-5) Ball\yMin#=1 Ball\yMax#=9999 Ball\xMin#=-32 Ball\xMax#=32 Ball\zMin#=-32 Ball\zMax#=32 Ball\elasticity#=.85 ;value from >0 to <1 (1=pure elastic collision) Ball\friction#=.01 ;************************** End Function ;********************************** Function BallPhysics (Ball.Ball_Object) If ball\y =< Ball\yMin# Then Ball\y = Ball\yMin# Ball\dy = -Ball\dy Ball\dy = Ball\dy * Ball\elasticity End If If Ball\x =< Ball\xMin# Then Ball\x = Ball\xMin# Ball\dx = -Ball\dx Ball\dx = Ball\dx * Ball\elasticity UpdatePivot (Ball) End If If Ball\x >= Ball\xMax# Then Ball\x = Ball\xMax# Ball\dx = -Ball\dx Ball\dx = Ball\dx * Ball\elasticity UpdatePivot (Ball) End If If Ball\z =< Ball\zMin# Then Ball\z = Ball\zMin# Ball\dz = -Ball\dz Ball\dz = Ball\dz * Ball\elasticity UpdatePivot (Ball) End If If Ball\z >= Ball\zMax# Then Ball\z = Ball\zMax# Ball\dz = -Ball\dz Ball\dz = Ball\dz * Ball\elasticity UpdatePivot (Ball) End If If Ball\y >= Ball\yMin# Then Ball\dy = Ball\dy + GRAVITY End If Ball\x = Ball\x + Ball\dx Ball\z = Ball\z + Ball\dz Ball\y = Ball\y + Ball\dy Ball\dx = Ball\dx - (Ball\dx*Ball\friction) Ball\dz = Ball\dz - (Ball\dz*Ball\friction) ;Move ball to new coords PositionEntity Ball\Entity, Ball\x, Ball\y, Ball\z, 0 ;Rotate mesh to give appearance of rolling TurnEntity Ball\Entity, Ball\dz*50,0,-Ball\Dx*50, 1 End Function Function UpdatePivot (Ball.Ball_Object) ;Move pivot to coords + deltas PositionEntity Ball\Pivot, Ball\x+Ball\dx, Ball\y+Ball\dy, Ball\z+Ball\dz PointEntity Ball\Entity, Ball\Pivot, 0 End Function PS: You need the file Blitzlogo.bmp as the ball texture. |
| ||
What you need to do is add a collision test for the floor or scenery, then during the collision check, if the collision in not with another ball, skip over the section that applies negative force back to the colliding entity (since it will be the wall), and make sure you give 100% of the positive force back to the ball instead of Force/2. I will try to modify the code to deal with your situation. |
| ||
heavy objects will have a higher terminal velocity than light objects. Therefore, heavy objects will fall faster in air than light objects. I think you're slightly misguided, it's nothing to do with the objects weight it's to do with the amount of drag it causes. If you could have a feather that is the size of a football pitch that weighed over a tonne and a bowling ball... the bowling ball would fall faster. |