# Beginner 2D Physics Engine Help

This topic is 2600 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, I have been attempting for some time now to program a 2d Physics engine from which i will make a 3d engine. But Iv finally gotten some collision detection in along with pointmass physics like particles and such.

Im using Blitz 3D as the language and I understand it is not the most efficient but i would rather learn with something simple like blitz before i move to a c++ engine.
I have ran into a few problems
for one after about 300 pointmasses are on screen doing collision checking along with simple verlet-euler integration and after more than 300 are spawned it begins to slow down, and objects at the bottom of a stack of objects get shoved into eachother.

Honestly im sure there are quite a few things i need help with and i dont exactly know what they all are but here is the code in my engine file. The vector type and functions are in a seperate file and if anyone would like to see it i can post that also

Include "Vectors.bb" Graphics 800,600,32,2 SetBuffer BackBuffer() FPStimer= CreateTimer(60) Global dt#=.5 Global pointmasscount = 0 Global G.Vector = New Vector ;Vector for Gravity G\x=0 G\y=100 ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;; ;Pointmass Type; Type Pointmass Field P.Vector ;Current Position Vector Field V.Vector ;Velocity Vector Field A.Vector ;Acceleration Vector Field F.Vector ;Force Vector Field imass# Field mousedrag# End Type ;;;;;;;;;;;;;;;;;;;;;;;;; ;Create Some Pointmasses; ;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;; ;Main Loop; While Not KeyHit(1) WaitTimer FPStimer Cls Text 0,0,pointmasscount CheckMouse() CheckKeyboard() CollisionsCheck() UpdatePointmasses() DrawPointmasses() ;DrawPointmassVector(P1,P1\F) Flip Wend ;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;Pointmass Functions; Function CreatePointmass.Pointmass(x#,y#,fx#,fy#,imass#) pointmasscount=pointmasscount+1 N.Pointmass = New Pointmass n\P=New Vector n\V=New Vector n\A=New Vector n\F=New Vector N\P\x=x N\P\y=y N\F\x=fx N\F\y=fy N\imass=imass N\mousedrag=False Return N End Function Function UpdatePointmasses() For n.Pointmass = Each Pointmass G=VScalarmultiply(G,GetMassPointmass(n)) If Not n\imass = 0 n\F=Vadd(n\F,G) EndIf R.Vector = New Vector R=n\A R=Vadd(R,VScalarmultiply(n\F,n\imass)) n\V=Vadd(n\V,VScalarmultiply(R,dt)) n\V=VScalarmultiply(n\V,.94^dt) n\F=VScalarmultiply(n\F,0) n\P=Vadd(n\P,VScalarmultiply(n\V,dt)) Text 0,40,n\V\x Text 0,50,n\V\y Next End Function Function GetMassPointmass(F.Pointmass) mass#=F\imass*(1/F\imass) Return mass End Function Function DrawPointmasses() For n.Pointmass = Each Pointmass Color 255,0,0 Oval n\P\x-15,n\P\y-15,30,30 Color 255,255,255 Oval n\P\x-16,n\P\y-16,31,31,0 Next End Function Function ApplyForce(P.Pointmass,magnitude#,angle#) Tf.Vector = New Vector ;Temporary force vector Tf\x = magnitude*Cos(angle) Tf\y = magnitude*Sin(angle) P\F = Vadd(P\F,Tf) End Function ;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;; ;Collision Checking; Function CollisionsCheck() For n.Pointmass = Each Pointmass For p.Pointmass = Each pointmass If Not p=n R.Vector = New Vector R\x=p\P\x-n\P\x R\y=p\P\y-n\P\y If Vmagnitude(R)<50 If Vmagnitude(R)<31 ;Vinvert(p\V) ;Vinvert(n\V) p\V=VScalarmultiply(n\V,.1) OverlapDist#=32-Vmagnitude(R) EachOverlapDist#=OverlapDist/2 p\P\x=p\P\x-EachOverlapDist*Cos(Vangle(R)) p\P\y=p\P\y-EachOverlapDist*Sin(Vangle(R)) n\P\x=n\P\x+EachOverlapDist*Cos(Vangle(R)) n\P\y=n\P\y+EachOverlapDist*Sin(Vangle(R)) EndIf EndIf EndIf Next If n\P\x <= 10 Vinvert(n\V) n\P\x = 10+1 EndIf If n\P\x >= GraphicsWidth()-10 Vinvert(n\V) n\P\x = GraphicsWidth()-10-1 EndIf If n\P\y <= 10 Vinvert(n\V) n\P\y = 10+1 EndIf If n\P\y >= GraphicsHeight()-14 Vinvert(n\V) n\P\y = GraphicsHeight()-14-1 EndIf Next End Function ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;; ;Input Functions; Function CheckMouse() If MouseHit(1) For n.Pointmass = Each Pointmass If MouseX()>n\P\x-20 And MouseX()<n\P\x+20 If MouseY()>n\P\y-20 And MouseY()<n\P\y+20 If n\mousedrag=0 n\mousedrag=1 EndIf EndIf EndIf Next EndIf If MouseHit(2) For n.Pointmass = Each Pointmass If MouseX()>n\P\x-20 And MouseX()<n\P\x+20 If MouseY()>n\P\y-20 And MouseY()<n\P\y+20 n\F=VScalarmultiply(n\F,0) EndIf EndIf Next EndIf For n.Pointmass = Each Pointmass If n\mousedrag = 1 If Not MouseDown(1) n\mousedrag = 0 EndIf R.Vector = New Vector R\x=MouseX()-n\P\x R\y=MouseY()-n\P\y ApplyForce(n,-Vmagnitude(R)*2,Vangle(R)) EndIf Next End Function Function CheckKeyboard() If KeyDown(31) CreatePointmass(MouseX(),MouseY(),Rand(-900,900),-2000,.05) EndIf If KeyHit(32) Vinvert(G) EndIf End Function ;;;;;;;;;;;;;;;;;;;;;;;;;; ;Vector Drawing Functions; Function DrawPointmassVector(R.Pointmass,F.Vector) N.Vector = New Vector N = Vadd(R\P,F) Line R\P\x,R\P\y,N\x,N\y End Function Function DrawOriginVector(F.Vector) Line 0,0,F\x,F\y End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;

##### Share on other sites
Are you testing collisions for every object against all other objects? If so you could try splitting your world into areas like a quadtree. And only test objects against objects within the same grid, or if close enough to another grid... that one as well. Or if you don't need perfect collision, you don't have to check collisions every frame, you could just check them every other frame.

##### Share on other sites
I am checking them all against eachother, But only if they are within a certain range of any other object. not exactly using a grid but each object has a radius that is checked and once another object intersects it begins to check for collisions

##### Share on other sites

I am checking them all against eachother, But only if they are within a certain range of any other object. not exactly using a grid but each object has a radius that is checked and once another object intersects it begins to check for collisions

Using the quadtree, would also eliminate the radius check, which is basically check every object against every object... also have you profiled the app?

I'm not familiar with blitz, It would help me and maybe others if you could explain in short what your doing. ie
- loop through object
- loop through possible objects checking if they are in range
- test collision...
etc.

oh and one other thing, once you've checked an object against all others, you never have to check that object again. So when you go to test the next object, don't test against the previous one... hopefully that made sense.

##### Share on other sites
ok so collisions go like this
some crazy pseudocode

 for n= each pointmass for p= each pointmass make a vector between the two if the magnitude of the vector is less than both the radii of the pointmass objects combined there is a collision correct the pointmasses preventing overlapping swap velocities of pointmasses next next 
hopefully that makes sense!

EDIT: And no i havent profiled it. I will work on that

##### Share on other sites

ok so collisions go like this
some crazy pseudocode

 for n= each pointmass for p= each pointmass make a vector between the two if the magnitude of the vector is less than both the radii of the pointmass objects combined there is a collision correct the pointmasses preventing overlapping swap velocities of pointmasses next next 
hopefully that makes sense!

EDIT: And no i havent profiled it. I will work on that

well for starters, instead of doing " for p= each pointmass", you could make it so it starts at n+1. Once again I'm not familiar with blitz syntax, but here is a psuedo C loop to show what I'm talking about.

 for (n = 0 to maxObjects-1) { for (p = n+1 to maxObjects) { } } 

This way you're not having to every object over and over again, even though you've dealt with it's collision already.

##### Share on other sites
I get what your saying, Im going to try and change that around and ill get back with what i get

• 15
• 10
• 9
• 49
• 12
• ### Forum Statistics

• Total Topics
631389
• Total Posts
2999726
×