Hey guys, I couldnt figure out how to calculate the advances dirction in pixels for the chain links, so i just settled on horizontal chains.
I must say, i'm impressed with Chipmunk, but the only major problem it gives me is when you try to stack elastic ships, (they cant hold still) other then that, i'm amazed at how fast it actually is
If anyone is interested, here is the little physics sandbox source-
SuperStrict
Import Bah.chipmunk
'types
'---
'---
'---
'FUNCTIONS
'---
'---
'---
'makes a box
Function Box:CPBody(p:CPVect, a:Float, w:Float,WIDTH:Int,HEIGHT:Int,r:Int = False)
Local verts:CPVect[] = [ ..
Vec2(-WIDTH/2,-HEIGHT/2.0), ..
Vec2(-WIDTH/2, HEIGHT/2.0), ..
Vec2( WIDTH/2, HEIGHT/2.0), ..
Vec2( WIDTH/2,-HEIGHT/2.0) ]
Local body:CPBody = New CPBody.Create(1.0, MomentForPoly(1.0, verts, CPVZero))
body.SetPosition(p)
body.SetAngle(a)
body.SetAngularVelocity(w)
space.AddBody(body)
Local shape:CPShape = New CPPolyShape.Create(body, verts, CPVZero)
shape.SetElasticity(0)
shape.SetFriction(0.5)
space.AddShape(shape)
If r = True Return body
End Function
'makes a circle
Function Circle:CPBody(p:CPVect,d:Float,r:Int = False,m:Float = 1)
Local radius:Float = d/2
Local body:CPBody = New CPBody.Create(m, MomentForCircle(10.0, 0.0, radius, Vec2(0,0)))
body.SetPosition(p)
space.AddBody(body)
Local shape:CPShape = New CPCircleShape.Create(body, radius, Vec2(0,0))
shape.SetElasticity(0)
shape.SetFriction(0.1)
space.AddShape(shape)
If r=True Return body
End Function
'makes a chain with a specified amount of diameter 10 circles
Function Chain(p:CPVect,length:Int,a_a:Int = False,a_b:Int = False)
Local body1:CPBody
Local body2:CPBody
Local joint:CPPivotJoint
Local body1pos:CPVect
Local body2pos:CPVect
Local px:Float = p.GetX()
Local py:Float = p.Gety()
For Local i:Int = 1 To length
body1 = Circle(Vec2( (px-((length/2)*12)-12) + (i * 12), py),10,True)
body1pos = body1.GetPosition()
If body2 <> Null
joint = New CPPivotJoint.Create(body1, body2, Vec2( (body1pos.x + body2pos.x)/2, py ) )
space.AddJoint(joint)
End If
body2 = Circle(Vec2(body1pos.GetX() + 12, py),10,True)
body2pos = body2.GetPosition()
joint = New CPPivotJoint.Create(body1, body2, Vec2( (body1pos.x + body2pos.x)/2, py ) )
space.AddJoint(joint)
Next
End Function
' The draw callback
Function drawObject(shape:Object, data:Object)
If CPPolyShape(shape) Then
drawPolyShape(CPPolyShape(shape))
ElseIf CPSegmentShape(shape) Then
drawSegmentShape(CPSegmentShape(shape))
ElseIf CPCircleShape(shape) Then
drawCircleShape(CPCircleShape(shape))
End If
End Function
' Draw a segment (line)
Function drawSegmentShape(shape:CPSegmentShape)
SetRotation 0
Local body:CPBody = shape.GetBody()
Local pos:CPVect = body.GetPosition()
Local a:CPVect = pos.Add(shape.GetEndPointA().Rotate(body.GetRot()))
Local b:CPVect = pos.Add(shape.GetEndPointB().Rotate(body.GetRot()))
DrawLine a.x, a.y, b.x, b.y
End Function
' Draw a poly
Function drawPolyShape(shape:CPPolyShape)
Local body:CPBody = shape.GetBody()
Local pos:CPVect = body.GetPosition()
Local verts:CPVect[] = shape.GetVerts()
Local First:CPVect
Local last:CPVect
For Local i:Int = 0 Until verts.length
Local v:CPVect = pos.Add(verts[i].Rotate(body.GetRot()))
If Not First Then
First = v
End If
If last Then
DrawLine last.x, last.y, v.x, v.y
End If
last = v
Next
DrawLine last.x, last.y, First.x, First.y
End Function
Function drawCircleShape(shape:CPCircleShape)
Local body:CPBody = shape.GetBody()
Local center:CPVect = shape.GetTransformedCenter()
Local radius:Float = shape.GetRadius()
DrawOval center.x - radius, center.y - radius, radius*2, radius*2
End Function
'make the walls
Function Makewalls()
' create a static segment (line)
Local shape:CPShape = New CPSegmentShape.Create(staticBody, Vec2(0,599), Vec2(800,599), 0)
shape.SetElasticity(0)
shape.SetFriction(1.0)
space.AddStaticShape(shape)
' create a static segment (line)
shape = New CPSegmentShape.Create(staticBody, Vec2(0,599), Vec2(0,0), 0)
shape.SetElasticity(0)
shape.SetFriction(1.0)
space.AddStaticShape(shape)
' create a static segment (line)
shape = New CPSegmentShape.Create(staticBody, Vec2(800,599), Vec2(800,0), 0)
shape.SetElasticity(0)
shape.SetFriction(1.0)
space.AddStaticShape(shape)
' create a static segment (line)
shape = New CPSegmentShape.Create(staticBody, Vec2(0,0), Vec2(800,0), 0)
shape.SetElasticity(0)
shape.SetFriction(1.0)
space.AddStaticShape(shape)
shape = New CPSegmentShape.Create(staticBody, Vec2(200,200), Vec2(600,200), 0)
shape.SetElasticity(0)
shape.SetFriction(1.0)
space.AddStaticShape(shape)
shape = New CPSegmentShape.Create(staticBody, Vec2(500,200), Vec2(200,50), 0)
shape.SetElasticity(0)
shape.SetFriction(1.0)
space.AddStaticShape(shape)
Local seasaw:CPBody = Box(Vec2(400,400),0,0,200,2,True)
Local joint:CPPivotJoint = New CPPivotJoint.Create(seasaw, staticBody, seasaw.GetPosition() )
space.AddJoint(joint)
End Function
'Check for user input
Function CheckInput()
If KeyDown(KEY_RIGHT) box1.applyimpulse(Vec2(50,0),Vec2(50,0))
If KeyDown(KEY_LEFT) box1.applyimpulse(Vec2(-50,0),Vec2(-50,0))
If KeyDown(KEY_UP) box1.applyimpulse(Vec2(0,-50),Vec2(0,-50))
If KeyDown(KEY_DOWN) box1.applyimpulse(Vec2(0,50),Vec2(0,50))
If KeyHit(KEY_P) play = Not play
If KeyHit(KEY_1) Circle(Vec2(MouseX(),MouseY()),20)
If KeyHit(KEY_2) Box(Vec2(MouseX(),MouseY()),0,0,20,20)
If KeyHit(KEY_3) Box(Vec2(MouseX(),MouseY()),0,0,150,5)
If KeyHit(KEY_4) Chain(Vec2(MouseX(),MouseY()),16)
End Function
AppTitle = "Untitled Physics Project"
Graphics 800,600
InitChipmunk()
Global staticBody:CPBody = New CPBody.Create(INFINITY, INFINITY)
ResetShapeIdCounter()
Global space:CPSpace = New CPSpace.Create()
space.ResizeStaticHash(150, 999)
space.ResizeActiveHash(150, 999)
space.SetGravity(Vec2(0, 1000))
Global box1:CPBody = Circle(Vec2(400,300),50,True,5)
MakeWalls()
Global play:Int = False
'fps stuff
Local FPS_TICK:Int
Local FPS:Int
Local FPS_TIMER:Int
'physics logic timing
Local steps:Float = 3
Local dt:Float = 1.0/60.0/steps
While Not AppTerminate()
Cls
'update everything
space.GetActiveShapes().ForEach(drawObject)
space.GetStaticShapes().ForEach(drawObject)
If play=True
space.DoStep(dt)
End If
CheckInput()
'Get FPS
If MilliSecs() > FPS_TIMER+1000
FPS = FPS_TICK
FPS_TIMER = MilliSecs()
FPS_TICK = 0
End If
FPS_TICK:+1
SetColor 70,153,255
DrawText "FPS: "+FPS,10,60
DrawText "Controls:",10,0
DrawText "[1] - Circle | [2] - Box | [3] - Plank | [4] - Chain",10,20
DrawText "[Arrow Keys] - Move ball | [P] Pause/Play simulation",10,40
If play=False
DrawText "Paused",740,10
Else
DrawText "Playing",740,10
End If
SetColor 255,255,255
Flip
Wend
End
instructions will be printed at the top, but incase you cant read them:
[1]-[4] makes shapes
[>][<][^][v] (arrow/cursor keys) move the player circle
[P] pauses and plays the simulation, (allowing you to place objects then start)