Simple Two Dimensional Physics
Author |
Message |
xAXISx
|
Posted: Wed Jun 28, 2006 11:57 am Post subject: Simple Two Dimensional Physics |
|
|
Simple Physics Engine features:
- Static Collision Detection (that is, collision with immovable objects)
- Gravity and Friction in an optional "Decay" process, disable that to make objects fly around.
- Seperate Force variables for realism, eg parabolic gravity.
Move around with the arrow keys, and to reset the force to 0, hit 'R'. The units used are of no particular measure. Feel free to post modifications or use it in anything you're programming.
code: |
/* Simple Physics Engine, Attempt 2. (c) Joey Robert */
const Major : array 1 .. 3 of real := init (0.50, 0.25, 2) % ( Added per turn, friction, gravity )
const Scene : array 1 .. 6 of int := init (400, 300, 400, 200, 0, 0) % ( MaxX, MaxY, BoxX, BoxY, MinX, MinY )
var Force : array 1 .. 2 of real := init (0, 0) % ( Force Up, Force Right )
var Position : array 1 .. 2 of real := init (0, 0) % ( X, Y )
var Item : int := Pic.FileNew ("1.bmp")
procedure DrawItem (Item : int, x, y : real)
cls
Pic.Draw (Item, round (x), round (y), picMerge)
end DrawItem
function Switch (Value, One, Two : real) : real
if round(Value) = round(One) then
result Two
elsif round(Value) = round(Two )then
result One
end if
end Switch
process InputKeys
var chars : array char of boolean
loop
Input.KeyDown (chars)
if chars (KEY_UP_ARROW) then
Force (1) := Force (1) + Major (1)
end if
if chars (KEY_DOWN_ARROW) then
Force (1) := Force (1) - Major (1)
end if
if chars (KEY_RIGHT_ARROW) then
Force (2) := Force (2) + Major (1)
end if
if chars (KEY_LEFT_ARROW) then
Force (2) := Force (2) - Major (1)
end if
if chars ('r') then
Force (1) := 0
Force (2) := 0
end if
delay (100)
end loop
end InputKeys
process Decay
loop
% FRICTION
for i : 1 .. 2
if Force (i) > 0 and Force (i) > Major (2) / 100 then
Force (i) := Force (i) - Major (2) / 100
elsif Force (i) < 0 and Force (i) < -Major (2) / 100 then
Force (i) := Force (i) + Major (2) / 100
else
Force (i) := 0
end if
end for
% GRAVITY
if Position (1) > Scene (5) and Position (1) > Major (3) / 100 then
Force (1) := Force (1) - Major (3) / 100
elsif Position (1) > Scene (5) and Position (1) > Major (3) / 100 then
Position (1) := 0
end if
delay (10)
end loop
end Decay
process DrawThing
loop
Position (1) := Position (1) + Force (1)
Position (2) := Position (2) + Force (2)
DrawItem (Item, Position (2), Position (1))
if (Position (2) < Scene (5) and Force (2) < 0) or (Position (2) > Scene (3) - Pic.Width (Item) and Force (2) > 0) then
Force (2) := Switch (Force (2), Force (2), -Force (2))
end if
if (Position (1) < Scene (6) and Force (1) < 0) or (Position (1) > Scene (4) and Force (1) > 0) then
Force (1) := Switch (Force (1), Force (1), -Force (1))
end if
locate (1, 1)
put "X : ", Position (2) : 6 : 2, " Press R to Stop"
put "Y : ", Position (1) : 6 : 2
put "UP : ", Force (1) : 6 : 2
put "RIGHT : ", Force (2) : 6 : 2
delay (10)
end loop
end DrawThing
setscreen ("graphics:400;300,noecho,nocursor,nobuttonbar")
fork Decay
fork InputKeys
fork DrawThing
|
Description: |
|
Filesize: |
3.17 KB |
Viewed: |
2289 Time(s) |

|
|
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
Cervantes

|
Posted: Wed Jun 28, 2006 4:15 pm Post subject: (No subject) |
|
|
The physics ain't bad, but I have one problem with the structure of your code:
Processes!!(?)!
Yossarian!!(?)!
Processes are not handled very well in Turing. They are a pain in most any language, in fact. You should only use them when you actually have to. For example, you have to use processes to play music (or use the Music.PlayFile commands, but internally that's still using a process), and you have to use a process if you want to do something while sitting on a socket with the Net module. But for this, there's no reason to use a process.
First, read the article on why you should avoid processes for a more indepth analysis. Then, try modifying your program so that it doesn't use processes. In this case, it's really easy. You'll basically just change each process to a procedure, take out the loop and the delay from each of them, and call each of them in a main loop at the end of the program.
|
|
|
|
|
 |
MysticVegeta

|
Posted: Wed Jun 28, 2006 7:04 pm Post subject: (No subject) |
|
|
Why is it that if I hold the up key, I never come down? Gravity should be focused more on the program...
|
|
|
|
|
 |
xAXISx
|
Posted: Wed Jun 28, 2006 7:16 pm Post subject: (No subject) |
|
|
Thanks for the help, but that article didn't explain much and then suddenly concludes with stating processes are evil.
Anyways, the InputKeys process you see above is pretty necessary, I don't want to put 'delay(100)' in the main loop, but I only want to use to be able to input stuff every 100ms. If I put a delay in the main loop, it would halt everything by 100ms and the frame rate would be terrible. Without the delay, it would add way more force then it needs to because there is nothing slowing it down.
As for the others, I could just compile into one procedure I suppose.
Gravity works, I'm assuming Yoshi has thrust, if you want to replace the picture so it makes more sense, go ahead. Plus staying on the ground in a small 400 x 200 box is no fun .
Edit: If you feel like it, comment out 'fork Decay', and just fly around without gravity or friction.
|
|
|
|
|
 |
Cervantes

|
Posted: Thu Jun 29, 2006 6:54 am Post subject: (No subject) |
|
|
xAXISx wrote:
Anyways, the InputKeys process you see above is pretty necessary, I don't want to put 'delay(100)' in the main loop, but I only want to use to be able to input stuff every 100ms. If I put a delay in the main loop, it would halt everything by 100ms and the frame rate would be terrible. Without the delay, it would add way more force then it needs to because there is nothing slowing it down.
No, it's still not necessary.
Put the Input.KeyDown code into your main loop, but make the size of the force applied one tenth what it was before. And Presto!
This has the added bonus of making the controls more act more frequently, which is closer to reality.
xAXISx wrote:
Thanks for the help, but that article didn't explain much and then suddenly concludes with stating processes are evil.
What didn't you understand? Ideally, you should read the whole article, by the way.
|
|
|
|
|
 |
xAXISx
|
Posted: Thu Jun 29, 2006 2:55 pm Post subject: (No subject) |
|
|
Quote: Put the Input.KeyDown code into your main loop, but make the size of the force applied one tenth what it was before. And Presto!
Good thinking, that's what I was planning on doing last night, thought of it right before I was about to sleep.
Also, I didn't say I didn't understand anything in the article and I did read it all. I just didn't find it very informative.
|
|
|
|
|
 |
BenLi

|
Posted: Thu Jun 29, 2006 4:56 pm Post subject: (No subject) |
|
|
very nice,
now concerning physics, i know how to do vectors, but how would you program air viscosity and perhaps wind into it. Wouldn't the movement depend on the surface are and stuff being affected?
|
|
|
|
|
 |
Clayton

|
Posted: Thu Jun 29, 2006 5:12 pm Post subject: (No subject) |
|
|
ya, you would have to calculate surface area exposed to wind, the thing being affected itself etc. you would have to have some sort of algorithm in your program to determine the "surface area" facing the wind (i say "surface area" because you are probably doing this in 2D graphics), properties of that object etc. so in the end it could be a fairly difficult thing to do depending on the amount of realisticness (is that a word?) you want in your program
|
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
xAXISx
|
Posted: Thu Jun 29, 2006 5:57 pm Post subject: (No subject) |
|
|
If it is just 2D, you could make a static air resistance value like I've done and add a seperate value for collision with surfaces.
code: |
if touchingWall() then
activePhysics := 0.5
else
activePhysics := 0.25
end if
|
or something like that, but that is very basic.
|
|
|
|
|
 |
Clayton

|
Posted: Thu Jun 29, 2006 7:07 pm Post subject: (No subject) |
|
|
yes but he wants to make it more realistic, now in the real world, everything doesnt travel through the air the same way (take a flat piece of paper and a bowling ball for example). In order to actually figure out how they would move through the air in a real-life situation, you would have to take into account: surface area, terminal velocity (for falling) etc. so you would therefore have to have a complex algorithm of some sort to figure out the "exact" path the object would travel, you cant just add some magic constant and truly make it look realistic, which was the point i was trying to make in my last post
|
|
|
|
|
 |
xAXISx
|
Posted: Thu Jun 29, 2006 9:56 pm Post subject: (No subject) |
|
|
I know, I was just trying to make things simpler since it's only simple 2D physics. If you wanted you could factor in weight, surface area and air resistance to get terminal velocity. You could also just multiply surface area by air resistance per unit to get the total and resistance and then minus that from the current force but as I said, this was a simplified model. To be honest, this would more of a programming test, not a test to simulate real world physics. Notice how gravity is not 9.81 m / s / s. If you want to, you can modify it to act like real world physics and post that.
|
|
|
|
|
 |
|
|