I have started on a new verlet physics engine myself,... I'm about to move things into 3d right now, but here is my 2d verlets for dummies code. Note: This is based on some code from the code archives, so some things may look similar to those. When I am trying to learn something new I strip it down to the very bare essentials and start building up to where I need it. This is about as basic as I can get it.
The next phase will involve getting collisions working between different objects. There are a few extra lines of code in here dealing with the collision code I have already started on.
Edit: see my following posts for a version with collisions, and a full 3d version as well.
The next phase will involve getting collisions working between different objects. There are a few extra lines of code in here dealing with the collision code I have already started on.
Edit: see my following posts for a version with collisions, and a full 3d version as well.
Global screen_w = 640 Global screen_h = 480 Global gravity# = .25 Graphics screen_w,screen_h,0,2 SetBuffer BackBuffer() ;SeedRnd MilliSecs() timer = CreateTimer (60) ; lock game fps to this Type vector2 Field x# Field y# End Type Type Verlet Field pos.vector2 ; verlet position Field vel.vector2 ; verlet velocity Field old.vector2 ; store the previous pos here Field radius ; size of verlet Field id ;use to identify groups Field collide ; is this colliding? End Type Type constraint Field p1.verlet Field p2.verlet Field length# End Type Global circle=CreateImage (40,40) Global circlehit=CreateImage (40,40) initCircleGFX() ;create circle graphics ;For loop = 1 To 10 definebox() ;create verlet box ;Next ;CreateVerlet.verlet (xpos,ypos,size,id) Global v1.verlet = CreateVerlet (400,100,20,1) Global v2.verlet = CreateVerlet(400,150,20,1) Global v3.verlet = CreateVerlet (500,100,20,1) Global v4.verlet = CreateVerlet(500,150,20,1) ConstrainVerlet (v1,v2) ConstrainVerlet(v2,v3) ConstrainVerlet(v1,v3) ConstrainVerlet(v1,v4) ConstrainVerlet(v2,v4) ConstrainVerlet(v3,v4) While Not KeyHit(1) WaitTimer(Timer) ; Pause until the timer reaches 60 (caps the game framerate on faster systems) UpdateVerlets() UpdateConstraints() ; move verlet 1 based on arrow keys v1\pos\y = v1\pos\y + (KeyDown(208) - KeyDown(200) )*2 v1\pos\x = v1\pos\x + (KeyDown(205) - KeyDown(203) )*2 If KeyHit(57) For v.verlet = Each verlet v\pos\y = v\pos\y - Rnd(1,20) v\pos\x = v\pos\x + Rnd(-5,5) Next EndIf drawscreen() Flip() Cls() Wend End Function initCircleGFX() SetBuffer ImageBuffer(circle) Color 128,128,128 Oval 0,0,40,40 Color 0,255,0 Oval 0,0,40,40,0 MidHandle circle SetBuffer ImageBuffer(circlehit) Color 255,0,0 Oval 0,0,40,40 MidHandle circlehit SetBuffer BackBuffer() Color 255,255,255 End Function Function definebox() ; define the shape and constraints ;CreateVerlet.verlet (xpos,ypos,size,id) v1.verlet = CreateVerlet.verlet (100,100,20,num) v2.verlet = CreateVerlet.verlet (150,100,20,num) v3.verlet = CreateVerlet.verlet (100,150,20,num) v4.verlet = CreateVerlet.verlet (150,150,20,num) v5.verlet = CreateVerlet.verlet (100,200,20,num) v6.verlet = CreateVerlet.verlet (150,200,20,num) c.constraint = ConstrainVerlet (v1,v2) c.constraint = ConstrainVerlet (v2,v4) c.constraint = ConstrainVerlet (v3,v4) c.constraint = ConstrainVerlet (v3,v1) c.constraint = ConstrainVerlet (v6,v1) c.constraint = ConstrainVerlet (v2,v5) c.constraint = ConstrainVerlet (v4,v6) c.constraint = ConstrainVerlet (v5,v6) c.constraint = ConstrainVerlet (v3,v5) c.constraint = ConstrainVerlet (v3,v6) c.constraint = ConstrainVerlet (v4,v1) End Function Function CreateVerlet.verlet (xpos,ypos,size,id) v.verlet=New verlet v\pos = New vector2 v\pos\x = xpos v\pos\y = ypos v\vel = New vector2 v\vel\x = 0 v\vel\y = 0 v\old = New vector2 v\old\x = xpos v\old\y = ypos v\radius = size v\id = num Return v End Function Function ConstrainVerlet.constraint (head.verlet, tail.verlet) Local dx#,dy# ;this creates a new constraint and sets the length equal to the current distance between the verlets c.constraint = New constraint c\p1.verlet = head.verlet c\p2.verlet = tail.verlet dx = c\p1\pos\x - c\p2\pos\x dy = c\p1\pos\y - c\p2\pos\y c\length = Sqr ( dx*dx + dy*dy ) ;DebugLog c\length Return c End Function Function UpdateVerlets() Local tx#,ty# For v.verlet = Each verlet v\collide = False v\vel\x = (v\pos\x - v\old\x)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction v\vel\y = (v\pos\y - v\old\y)*.985 v\old\x = v\pos\x ; store position in "old" v\old\y = v\pos\y v\pos\x = v\pos\x + v\vel\x ;store new postion based on velocity v\pos\y = v\pos\y + v\vel\y + gravity ;check screen bounds If v\pos\x > screen_w - v\radius v\pos\x=screen_w - v\radius v\collide = True ElseIf v\pos\x < v\radius v\pos\x = v\radius v\collide = True EndIf If v\pos\y > screen_h - v\radius v\pos\y=screen_h - v\radius v\collide = True ElseIf v\pos\y < v\radius v\pos\y= v\radius v\collide = True EndIf Next End Function Function UpdateConstraints() Local dx#,dy#,length#,diff#;,nx#,ny#,tx#,ty# For loop = 1 To 5 ;iterations For c.constraint = Each constraint dx=c\p2\pos\x - c\p1\pos\x dy=c\p2\pos\y - c\p1\pos\y length=Sqr(dx*dx+dy*dy) ; distance between p1 and p2 If length<>0 ;avoid divide by 0, then normalize the vector diff = (length - c\length) / length ; vector length minus constraint length EndIf dx = dx * .5 ;find the midpoint dy = dy * .5 c\p1\pos\x = c\p1\pos\x + diff * dx c\p1\pos\y = c\p1\pos\y + diff * dy c\p2\pos\x = c\p2\pos\x - diff * dx c\p2\pos\y = c\p2\pos\y - diff * dy Next ;constraints Next ;iterations End Function Function DrawScreen() For v.verlet=Each verlet If v\collide = False DrawImage circle,v\pos\x,v\pos\y ; draw circle ;Oval v\pos\x-v\radius,v\pos\y-v\radius,v\radius*2,v\radius*2,0 ;draw the actual radius (slow) Else DrawImage circlehit,v\pos\x,v\pos\y ; draw red circle if colliding EndIf Next For c.constraint = Each constraint Line c\p1\pos\x,c\p1\pos\y,c\p2\pos\x,c\p2\pos\y Next Text 10,10,"Use arrow keys to move V1, space bar for earthquake" Text v1\pos\x,v1\pos\y,"V1" End Function