I ported a simple billiards game I had made to chipmunk
http://www.blitzbasic.com/Community/posts.php?topic=73636
Everything is working except freeing shapes and bodies.
I realize you have to free shapes before freeing objects but this does not solve it. Some reference still sticks around in the space which is referenced in EachBody(). I noticed there was a destroy() function associated with bodies in the c api which is not in the wrapper. Any ideas??
http://www.blitzbasic.com/Community/posts.php?topic=73636
Everything is working except freeing shapes and bodies.
I realize you have to free shapes before freeing objects but this does not solve it. Some reference still sticks around in the space which is referenced in EachBody(). I noticed there was a destroy() function associated with bodies in the c api which is not in the wrapper. Any ideas??
Strict Import BaH.Chipmunk Const FRICTION:Float=.99 Const COLLISION:Float=.99 Const MAXSPEED:Float=15 Const BALLSIZE:Float=20 Const HOLESIZE:Float=50 Const POWERUP:Float=.5 Const TABLEW:Int=800 Const TABLEH:Int=500 Global game:Tgame=New Tgame game.Rack() '''------- classes Type TBody Extends CPBody Field x:Float,y:Float Method New() Create(10,1) EndMethod Method sync() Local v:CPVect=GetPosition() x=v.GetX() y=v.GetY() EndMethod Method setXY(_x,_y) x=_x y=_y SetPosition(Vec2(x,y)) EndMethod Method stop() SetVelocity(Vec2(0,0)) EndMethod Method move(a:Float,s:Float) SetVelocity(Vec2(s*Sin(a),-s*Cos(a))) EndMethod Method ato:Float(b:TBody) Local n:Float=b.x-x If n=0 n=.0001 ''dont divide by 0 Local a2:Float=ATan((b.y-y)/n) If (b.x-x)<0 a2:+180 Return a2+90 EndMethod Method dto:Float(b:TBody) Local _h:Float = Abs(x-b.x) Local _w:Float = Abs(y-b.y) Return Sqr((_w*_w)+(_h*_h)) EndMethod Method draw() Plot(x,y) EndMethod EndType Type Tmouse Extends TBody Method setXY(_x,_y) x=_x y=_y EndMethod EndType Type Tbumper Extends TBody Field w,h Field shape:CPPolyShape Method New() Create(INFINITY,INFINITY) EndMethod Method draw() SetColor(0,45,0) DrawRect(x-(w/2),y-(h/2),w,h) SetColor(255,255,255) EndMethod EndType Type Thole Extends TBody Field d Method New() d=HOLESIZE EndMethod Method setXY(_x,_y) ''no need to setPosition - this isnt a real physics object x=_x y=_y EndMethod Method draw() SetColor(0,0,0) DrawOval(x-(d/2),y-(d/2),d,d) SetColor(255,255,255) EndMethod EndType Type Tball Extends TBody Field number Field shape:CPCircleShape Field d:Float Method New() Create(10,1) d=BALLSIZE EndMethod Method Free() 'ARAAGGHH!! If shape shape.Free() EndIf If cpObjectPtr Then cpBodyFree(cpObjectPtr) cpObjectPtr = Null End If EndMethod Method color() Select number Case 1 SetColor(230,200,0) Case 2 SetColor(0,0,190) Case 3 SetColor(200,0,0) Case 4 SetColor(100,0,100) Case 5 SetColor(0,200,0) Case 6 SetColor(200,100,0) Case 7 SetColor(100,0,0) Case 8 SetColor(0,0,0) Case 9 SetColor(230,200,0) Case 10 SetColor(0,0,190) Case 11 SetColor(200,0,0) Case 12 SetColor(100,0,100) Case 13 SetColor(0,200,0) Case 14 SetColor(200,100,0) Case 15 SetColor(100,0,0) EndSelect EndMethod Method draw() sync() If number > 8 DrawOval(x-(d/2),y-(d/2),d,d) color() DrawRect(x-(d/2)+2,y-6,d-4,12) SetColor(255,255,255) DrawOval(x-(d/4),y-(d/4),d/2,d/2) SetColor(0,0,0) If number=9 DrawText(number,x-(d/4),y-(d/4)-1) Else DrawText(number,x-(d/4)-3,y-(d/4)-1) EndIf SetColor(255,255,255) ElseIf number color() DrawOval(x-(d/2),y-(d/2),d,d) SetColor(255,255,255) DrawOval(x-(d/4),y-(d/4),d/2,d/2) SetColor(0,0,0) DrawText(number,x-(d/4),y-(d/4)-1) SetColor(255,255,255) Else DrawOval(x-(d/2),y-(d/2),d,d) EndIf EndMethod EndType Type Tgame Field space:CPSpace Field maxCuePower:Float=MAXSPEED Field cuePower:Float Field cue:Tball Field mouse:Tmouse Field placing,placed Field texta:Float Field holes:TList Method New() InitChipmunk() space=New CPSpace space.Create() space.setDamping(FRICTION) holes=New TList cue=New Tball placing=True texta=2.0 mouse=New Tmouse EndMethod Method Rack() newBumper(TABLEH-HOLESIZE,HOLESIZE/2,TABLEW,HOLESIZE) newBumper(HOLESIZE/2,TABLEH/2,HOLESIZE,TABLEH) newBumper(TABLEW-HOLESIZE/2,TABLEH/2,HOLESIZE,TABLEH) newBumper(TABLEH-HOLESIZE,TABLEH-HOLESIZE/2,TABLEW,HOLESIZE) newHole(HOLESIZE,HOLESIZE) newHole(HOLESIZE,TABLEH-HOLESIZE) newHole(TABLEW-HOLESIZE,HOLESIZE) newHole(TABLEW-HOLESIZE,TABLEH-HOLESIZE) newHole(TABLEW/2,HOLESIZE) newHole(TABLEW/2,TABLEH-HOLESIZE) cue=newBall(0,600,250) newBall(1,300,250) newBall(2,279,240) newBall(9,279,261) newBall(10,258,230) newBall(8,258,251) newBall(4,258,272) newBall(7,237,220) newBall(13,237,241) newBall(3,237,262) newBall(11,237,283) newBall(15,216,210) newBall(12,216,231) newBall(5,216,252) newBall(14,216,273) newBall(6,216,294) EndMethod Method updateUI() If placing cue.setXY(MouseX(),MouseY()) If MouseX()>TABLEW-HOLESIZE Or MouseX()<HOLESIZE FlushMouse() ElseIf MouseY()>TABLEH-HOLESIZE Or MouseY()<HOLESIZE FlushMouse() ElseIf MouseHit(1) cue.stop() placing=False placed=True EndIf Else If MouseDown(1) And placed=False If cuePower<maxCuePower cuePower:+POWERUP ElseIf placed=True And MouseDown(1)=False placed=False ElseIf cuePower>0 And Not placed mouse.setXY(MouseX(),MouseY()) cue.move(cue.ato(mouse)-180,cuePower) cuePower=0 EndIf EndIf EndMethod Method drawUI() SetAlpha(texta) DrawText("[SPACE] to see angle",12,2) DrawText("[ESC] to rack balls",12,14) DrawText("[Q] to quit game",12,26) If texta > .01 texta:-.005 Else texta=0 EndIf SetAlpha(1) If MouseDown(1) And Not placed Local n:Int=Min(Int((cuePower/maxcuepower)*100),100) SetColor(Min(500.0*Float(n)/100.0,255.0)-30.0,Min(500.0-(500.0*Float(n)/100.0),255.0)-30.0,0) DrawText(n+"%",MouseX()+12,MouseY()+18) ElseIf KeyDown(KEY_SPACE) DrawLine(MouseX(),MouseY(),cue.x,cue.y) EndIf SetColor(255,255,255) EndMethod Function doBalls(o:Object, data:Object) If Tball(o) Local b:Tball=Tball(o) b.draw() For Local h:Thole=EachIn game.holes If b.dto(h) < h.d/2 If b=game.cue game.placing=True FlushMouse() Else 'this creates a memory disaster 'b.Free() b.setXY(-10000,-10000) EndIf EndIf Next EndIf EndFunction Function doBumpers(o:Object, data:Object) If Tbumper(CPshape(o).GetBody()) Tbumper(CPshape(o).GetBody()).draw() EndIf EndFunction Method run() space.GetStaticShapes().ForEach(doBumpers) For Local h:Thole=EachIn holes h.draw() Next space.EachBody(doBalls) space.DoStep(1) updateUI() drawUI() EndMethod EndType '''------- helper functions Function newBall:Tball(n,x,y) Local b:Tball=New Tball b.number=n b.shape=New CPCircleShape b.shape.Create(b,b.d/2,Vec2(0,0)) b.shape.SetElasticity(COLLISION) b.setXY(x,y) game.space.AddShape(b.shape) game.space.AddBody(b) Return b EndFunction Function newBumper:Tbumper(x,y,w,h) Local br:Tbumper=New Tbumper br.w=w br.h=h br.shape=New CPPolyShape br.shape.Create(br, [Vec2(x-w/2,y-h/2),Vec2(x-w/2,y+h/2),Vec2(x+w/2,y+h/2),Vec2(x+w/2,y-h/2)], Vec2(0,0)) br.shape.SetElasticity(COLLISION) br.setXY(x,y) game.space.AddStaticShape(br.shape) Return br EndFunction Function newHole:Thole(x,y) Local h:Thole=New Thole h.setXY(x,y) game.holes.AddLast(h) Return h EndFunction '''------- main procedure Graphics(TABLEW,TABLEH) SetClsColor(0,60,0) SetBlend(ALPHABLEND) While Not AppTerminate() Cls game.run() If KeyHit(KEY_ESCAPE) game.space.Free() game=New Tgame game.Rack() FlushMouse() ElseIf KeyHit(KEY_Q) Exit EndIf Flip Wend