Creating realistic gravity
Blitz3D Forums/Blitz3D Beginners Area/Creating realistic gravity
| ||
Does any one know a way to create gravity that gradually increases in speed when you fall? I'm not very good with c++ so could you kind of explain it in detail? I asked this once before but i went to the blitzmax forums by accident. |
| ||
1) (Recommended solution) Use a third-party physics engine. ODE is OK, and both free and commercial (but stabler and supported) versions exist. 2) Use something extremely loosely based on verlet integration: (Better examples by Stevie and Nate exist, check the code archives) "Verlet integration" for the purposes of this just means store the object's old position, get the difference between that and it's current position, and move it further by that amount, less friction and plus gravity. The resulting movement looks relatively natural although it's not really possible to simulate collisions accurately if you keep it all within Blitz3D. |
| ||
The basics of gravity are simple... you have an x and y position (2d example) you also have velocity which is added to the values each iteration of the game... Gravity is just an amount added to the y velocity each iteration |
| ||
It needs to be 3D so does that mean i need an X, Y, and Z position? |
| ||
Yes... If memory serves (provided you haven't rotated everything) Y is still your vertical... so gravity would still be added to that velocity |
| ||
Objects accelerate downwards at 32 feet per second on earth. So it depends on the scale of the world, and what gravity power you want. |
| ||
So it depends on the scale of the world, and what gravity power you want. Thats the most relevant. True gravity never fits in a game world |
| ||
Can someone give me some pointers as to how im supposed to create an X Y and Z position and add velocity to the Y position? |
| ||
acceleration#=-0.5 ;put any number here that you want... repeat ;each frame x#=x#+vx# ;update velocity in x/y/z direction of your object y#=y#+vy# z#=z#+vz# vy#=vy# + acceleration# until keydown(1) |
| ||
i tried putting your example in Matty, but it wont do anything. I'm probably doing something wrong though. |
| ||
It's not going to do anything by itself, it just shows how to calculate the new x/y/z based on the velocity of the object and the acceleration due to gravity. |
| ||
ok thx |
| ||
ok here is a little example. Not exactly verlet based but this is as simple as it gets other than that. |
| ||
People usually need gravity for the player, be it a fps camera or a tps Character. Even if you could have ultrasimple Gravity by Traqnslateentity it a little down on the Y axis, in a real game there is much more stuff involved. What you can do is: test if the players feet touched the ground and then increase the falling speed if they didn't. But this leads to flipflop condition, where collision is applied every second render, resulting it jittering motion. Furthermore: Sliding collision. If you use Blitzs internal Collision, your character will slide down even the slightest slope - very unnatural, unless the game plays on ice. Doing one Linepick vs the ground and calculate the ground angle using PickedNx etc. may be an option. For myself I had to do 4 picks and calcualte the angle myself to obtain stabile functionality, however. It is really rather tricky to get good gravity and collision with Blitz3Ds internal commands. It may be a good idea to use a 3rd party physics library in the first place, but make sure it's stabile and fast (unfort. that's something rather rare in phys libs IMHO). |
| ||
I tried doing something super simple (since whenever i add any other gravity code in it screws with my whole game.)entityY#(player) = v repeat v = v + .5 TranslateEntity player,0,-v,0 if entitycollided(player,ground) then v = v until keydown(1) i tried this, but it still won't work. is there a way to make this work? |
| ||
If you don't use some kind of delta timing then your game speed and response is going to change depending on the machine you are running it on... What I use is millisecs()... use the delta since the last update as a multiplier and you can check to see if a ms has passed before processing (and if it hasn't don't run the game logic). Otherwise, I'm not sure of the nature of how your game gets "screwed" |
| ||
if entitycollided(player,ground) then v = v This line is useless, 'v' will always equal itself anyway, Not that there's any way to see what's happening as there's no rendering in that loop. Posting your actual code would really help. Anyway, try this: |
| ||
also: entitycollided(player,ground) This command checks if an entity collided with a certain entity TYPE, not with a cerain entity. As the return value it will then give you the other entity: Const TYPE_WORLD=3 Const TYPE_PLAYER=1 EntityType ground, TYPE_WORLD EntityType player, TYPE_PLAYER Collisions 1,3,2,2 ... while keyhit(1)=0 ; mainloop begin ... if entitycollided(player, TYPE_WORLD)=ground then v=0 ... Actually, in a game you would use a feet pivot for that check, to prevent the player from climbing up walls, because v would become 0 when he touches the wall. |