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-
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)
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)