Thought I'd post this to see if anyone more experienced can tell what's wrong here because I've been trying to figure it out for days and I'm getting nowhere. I've taken elements of the Chipmunk and HGE examples and tried to recreate the physics example from neotoma's HGE wrapper (which uses the much better IMO Box2d physics). This is only because the Chipmunk wrapper for PB is much more complete and I had an idea for something I wanted to use physics for.
People might want to take the debug statements out of the functions that get called every loop because obviously it's silly to have them in there but they were just to check if anything was changing (and it appears they aren't). On the first draw everything appears as it should do, in the correct places. After this it just goes all over the place. Anyone who wants to compile it will need both the HGE wrapper from neotoma
http://www.purebasic.fr/english/viewtop ... 43&start=0
and the Chipmunk wrapper from eddy
http://www.purebasic.fr/english/viewtopic.php?t=31022
I'd LOVE if someone made a wrapper of some sort for Box2d, especially since it appears more stable, more functional and more advanced... paired with HGE (which I hope is maintained!) I think some pretty impressive things could be made... pretty quickly too!
I apologise for the code being mostly hacked together and uncommented but I've literally torn it to pieces and rearranged it what feels like a thousand times in the last few days...
Cheers
Code: Select all
; // Include the HGEWrapper + CHIPMUNK include file
XIncludeFile #PB_Compiler_Home + "Includes\HGEWrapper_include.pbi"
XIncludeFile #PB_Compiler_Home + "Includes\chipmunk_include.pbi"
; // Constants
#SCREEN_WIDTH = 1024
#SCREEN_HEIGHT = 768
#SCREEN_BPP = 32
#SCREEN_WINDOWED = #True
#FRAME_ITERATIONS = 10 ; // Physics iterations
#MATH_PI = 3.141592653589
; // Macros
Macro DegToRad(_D_) ; // _D_ = Degrees
( (#MATH_PI / 180.0) * _D_ )
EndMacro
Macro RadToDeg(_R_) ; // _R_ = Radians
( (180.0 / #MATH_PI) * _R_ )
EndMacro
; // Declares
Declare UpdatePhObj()
; // Structures
Structure sPh
*spr ; // hge sprite pointer
*body.cpBody ; // physics body pointer
pos.cpVect ; // x and y position vector
*shape.cpShape ; // shape struct
w.f ; // width
h.f ; // height
a.f ; // angle
col.f ; // colour
EndStructure
; // Global variables
Global Dim PhObj.sPh(1)
Global numPhObj.l = 0
Global *phSpace
Global *StaticBody
Global *shape
Global INFINITY.f = 1e1000
Global vx.f, vy.f
Global dt.f
ProcedureCDLL FrameFunc()
; // Delata time variable - keeps everything at the correct speed
; // [Time elapsed since last call of FrameFunc()]
Shared dt.f
Shared vx.f, vy.f
Shared numPhObj.l
Shared phObj.sPh()
dt.f = hge_Timer_GetDelta()
For i = 0 To #FRAME_ITERATIONS
wcpSpaceStep(*phSpace,dt)
Next
; // If the escape key is pressed, exit the function
Select(hge_Input_GetKey())
;Case #HGEK_UP :
;Case #HGEK_DOWN :
;Case #HGEK_LEFT :
;Case #HGEK_RIGHT : vx = vx + 1.0 * dt
Case #HGEK_ESCAPE : ProcedureReturn #True
;Case #HGEK_LBUTTON : hge_Input_GetMousePos(@vx,@vy)
Default
EndSelect
For n = 0 To numPhObj - 1
If hge_Input_GetKey() = #HGEK_SPACE
Debug "Object "+Str(n)+" X: "+Str(phObj(i)\pos\x)+", Y: "+Str(phObj(i)\pos\y)+", A: "+Str(phObj(i)\a)
EndIf
Next n
; // FrameFunc should always return FALSE
ProcedureReturn #False
EndProcedure
ProcedureCDLL RenderFunc()
; // Begin rendering - this MUST be called before any rendering occurs
hge_Gfx_BeginScene(#Null)
; / Clear screen with black
hge_Gfx_Clear(0)
; */
; // CODE GOES HERE
; /*
UpdatePhObj()
; End rendering and update screen
hge_Gfx_EndScene()
; // RenderFunc should always return FALSE
ProcedureReturn #False
EndProcedure
Procedure CreatePhObjBox(tex.l, ScaleX.f, ScaleY.f, PosX.f, PosY.f, Col.l, Angle.f, Mass.f=0, Restitution.f=0, friction.f=0)
Shared *phSpace
Shared phObj.sPh()
Protected pos.cpVect
Protected a.f
ReDim phObj.sPh(NumPhObj)
phObj(NumPhObj)\spr = hge_Sprite(tex, PosX, PosY, ScaleX, ScaleY)
hge_Sprite_SetColor(phObj(NumPhObj)\spr, Col)
hge_Sprite_SetHotSpot(phObj(NumPhObj)\spr, (ScaleX * 0.5), (ScaleY * 0.5))
;////
num.l = 4
Protected Dim verts.cpVect(4)
verts(0)\x = -(ScaleX * 0.5): verts(0)\y = -(ScaleY * 0.5)
verts(1)\x = -(ScaleX * 0.5): verts(1)\y = (ScaleY * 0.5)
verts(2)\x = (ScaleX * 0.5): verts(2)\y = (ScaleY * 0.5)
verts(3)\x = (ScaleX * 0.5): verts(3)\y = -(ScaleY * 0.5)
_cpv(zv, (ScaleX * 0.5), (ScaleY * 0.5))
wcpMomentForPoly(1.0, num, @verts(), @zv, @mom_pols.f)
Debug("mom_pols="+StrF(mom_pols))
phObj(NumPhObj)\body = wcpBodyNew(1.0, mom_pols)
phObj(NumPhObj)\pos\x = PosX
phObj(NumPhObj)\pos\y = PosY
phObj(NumPhObj)\a = Angle
phObj(NumPhObj)\w = ScaleX
phObj(NumPhObj)\h = ScaleY
Debug "CrObj()X : " + Str(phObj(NumPhObj)\pos\x)
Debug "CrObj()Y : " + Str(phObj(NumPhObj)\pos\y)
Debug "CrObj()A : " + Str(phObj(NumPhObj)\a)
Debug "CrObj()W : " + Str(phObj(NumPhObj)\w)
Debug "CrObj()H : " + Str(phObj(NumPhObj)\h)
;_cpv(pos, phObj(NumPhObj)\pos\x, phObj(NumPhObj)\pos\y)
pos\x = phObj(NumPhObj)\pos\x
pos\y = phObj(NumPhObj)\pos\y
wcpBodySetPosition(phObj(NumPhObj)\body, @pos.cpVect)
; //////// EVERYTHING IS FINE AT THIS POINT
a = phObj(NumPhObj)\a
wcpBodySetAngle(phObj(NumPhObj)\body, @a.f)
;Debug "Angle we set = " + Str(a)
;wcpBodySetPosition(phObj(NumPhObj)\body, @pos); pb_cpbody_setposition(*body, @pos )
wcpSpaceAddBody(*phSpace,phObj(NumPhObj)\body); pb_cpspace_addbody(*space,*body)
phObj(NumPhObj)\shape = wcpPolyShapeNew(phObj(NumPhObj)\body, @verts(),num, @zv); *shape = pb_cppolyshape_create(*body, @verts(),num, @zv)
wcpShapeSetElasticity(phObj(NumPhObj)\shape,restitution) ;pb_cpshape_setelasticity(*shape,0)
wcpShapeSetFriction(phObj(NumPhObj)\shape,friction) ;pb_cpshape_setfriction(*shape,1.5)
wcpSpaceAddShape(*phSpace, phObj(NumPhObj)\shape) ;pb_cpspace_addshape(*space, *shape)
; ////
NumPhObj = NumPhObj + 1
ProcedureReturn phObj(NumPhObj-1)\body
EndProcedure
Procedure CreatePhStaticObjBox(tex.l, ScaleX.f, ScaleY.f, PosX.f, PosY.f, Col.l, Angle.f, Restitution.f=0, Friction.f=0)
Shared *StaticBody
Shared *phSpace
Shared phObj.sPh()
Protected pos.cpVect
Protected a.f
ReDim phObj.sPh(NumPhObj)
phObj(NumPhObj)\spr = hge_Sprite(tex, PosX, PosY, ScaleX, ScaleY)
hge_Sprite_SetColor(phObj(NumPhObj)\spr, Col)
hge_Sprite_SetHotSpot(phObj(NumPhObj)\spr, (ScaleX * 0.5), (ScaleY * 0.5))
;////
num.l = 4
Protected Dim verts.cpVect(4)
verts(0)\x = -(ScaleX * 0.5): verts(0)\y = -(ScaleY * 0.5)
verts(1)\x = -(ScaleX * 0.5): verts(1)\y = (ScaleY * 0.5)
verts(2)\x = (ScaleX * 0.5): verts(2)\y = (ScaleY * 0.5)
verts(3)\x = (ScaleX * 0.5): verts(3)\y = -(ScaleY * 0.5)
;_cpv(zv, (ScaleX * 0.5), (ScaleX * 0.5))
phObj(NumPhObj)\body = *StaticBody
phObj(NumPhObj)\pos\x = PosX
phObj(NumPhObj)\pos\y = PosY
phObj(NumPhObj)\a = Angle
phObj(NumPhObj)\w = ScaleX
phObj(NumPhObj)\h = ScaleY
Debug "CrStObj()X : " + Str(phObj(NumPhObj)\pos\x)
Debug "CrStObj()Y : " + Str(phObj(NumPhObj)\pos\y)
Debug "CrStObj()A : " + Str(phObj(NumPhObj)\a)
Debug "CrStObj()W : " + Str(phObj(NumPhObj)\w)
Debug "CrStObj()H : " + Str(phObj(NumPhObj)\h)
;_cpv(pos, phObj(NumPhObj)\pos\x, phObj(NumPhObj)\pos\y)
pos\x = phObj(NumPhObj)\pos\x
pos\y = phObj(NumPhObj)\pos\y
wcpBodySetPosition(phObj(NumPhObj)\body, @pos)
a = phObj(NumPhObj)\a
wcpBodySetAngle(phObj(NumPhObj)\body, @a.f)
Debug "Angle we set = " + Str(a)
; //////// EVERYTHING IS FINE AT THIS POINT
phObj(NumPhObj)\shape = wcpPolyShapeNew(phObj(NumPhObj)\body, @verts(), num, @zv); *shape = pb_cppolyshape_create(*body, @verts(),num, @zv)
wcpShapeSetElasticity(phObj(NumPhObj)\shape, Restitution) ;pb_cpshape_setelasticity(*shape,0)
wcpShapeSetFriction(phObj(NumPhObj)\shape, Friction) ;pb_cpshape_setfriction(*shape,1.5)
wcpSpaceAddStaticShape(*phSpace, phObj(NumPhObj)\shape) ;pb_cpspace_addshape(*space, *shape
; //////// EVERYTHING IS FINE AT THIS POINT
NumPhObj = NumPhObj + 1
ProcedureReturn phObj(NumPhObj-1)\body
EndProcedure
Procedure UpdatePhObj()
Protected pos.cpVect
Protected a.f
Shared phObj.sPh()
For i = 0 To NumPhObj-1
hge_Sprite_RenderEx(phObj(i)\spr, phObj(i)\pos\x, phObj(i)\pos\y, phObj(i)\a)
wcpBodyGetPosition(phObj(i)\body, @pos.cpVect)
phObj(i)\pos\x = pos\x
phObj(i)\pos\y = pos\y
Debug "UpdatePhObj() = x: " + Str(phObj(i)\pos\x) + " y: " + Str(phObj(i)\pos\x)
wcpBodyGetAngle(phObj(i)\body, @a.f)
phObj(i)\a = DegToRad(a)
Debug "UpdatePhObj() = angle: " + Str(phObj(i)\a)
Next
EndProcedure
Procedure Main()
Shared INFINITY.f
Shared *phSpace
Shared *StaticBody
; // Create instance of HGE
hge_Create(#HGE_VERSION)
; // System setup
hge_System_SetStateFunc(#HGE_FRAMEFUNC, @FrameFunc())
hge_System_SetStateFunc(#hge_RENDERFUNC, @RenderFunc())
hge_System_SetStateString(#HGE_TITLE, "Chipmunk Physics test")
hge_System_SetStateBool(#HGE_SHOWSPLASH, #False)
hge_System_SetStateBool(#HGE_HIDEMOUSE, #False)
hge_System_SetStateInt(#HGE_FPS, 100)
; // Video setup
hge_System_SetStateBool(#HGE_WINDOWED, #SCREEN_WINDOWED)
hge_System_SetStateInt(#HGE_SCREENWIDTH, #SCREEN_WIDTH)
hge_System_SetStateInt(#HGE_SCREENHEIGHT, #SCREEN_HEIGHT)
hge_System_SetStateInt(#HGE_SCREENBPP, #SCREEN_BPP)
; // Disable sound
hge_System_SetStateBool(#HGE_USESOUND, #False)
; Initiate system
If hge_System_Initiate()
; */
; // LOAD RESOURCES, CREATE OBJECTS ETC...
; /*
wcpInitChipmunk()
wcpResetShapeIdCounter()
*phSpace = wcpSpaceNew()
wcpSpaceSetIterations(*phSpace, #FRAME_ITERATIONS)
wcpSpaceSetDamping(*phSpace, 0.9)
_cpv(vec, 0, 10)
wcpSpaceSetGravity(*phSpace, @vec);
wcpSpaceResizeStaticHash(*phSpace, 20.0, 999) ; // Max 999 Static Objects
wcpSpaceResizeActiveHash(*phSpace, 20.0, 999) ; // Max 999 Moving Objects
; // Init static body
*StaticBody = wcpBodyNew(INFINITY, INFINITY)
CreatePhObjBox(0, 64, 128, 600.0,(#SCREEN_HEIGHT - 650.0), $FFFF0000, 0, 1, 0.5, 2)
CreatePhObjBox(0, 32, 64, 200, (#SCREEN_HEIGHT -600.0), $FFFF0000, 0, 1, 0.4, 9)
CreatePhObjBox(0, 32, 32, 100.0, (#SCREEN_HEIGHT - 108.0), $FF0000FF, 0, 1, 0.4, 9)
CreatePhStaticObjBox(0, 160, 8, 445, 730, $FF00FFAA, -0.2, 0.5, 5)
CreatePhStaticObjBox(0, 160, 8, 600, 730, $FF00FFAA, 0.2, 0.5, 5)
CreatePhStaticObjBox(0, 1024, 32, 512, 752, $FF00FFAA, 0, 0.3, 1)
CreatePhStaticObjBox(0, 1024, 32, 512, 16, $FF00FFAA, 0)
CreatePhStaticObjBox(0, 32, 704, 16, 384, $FF00FFAA, 0)
CreatePhStaticObjBox(0, 32, 704, 1008, 384, $FF00FFAA, 0)
CreatePhStaticObjBox(0, 160, 32, 230, 500, $FF00FFAA, 0)
CreatePhStaticObjBox(0, 160, 32, 800, 500, $FF00FFAA, 0)
CreatePhStaticObjBox(0, 32, 360, 320, 300, $FF00FFAA, -1.1)
CreatePhStaticObjBox(0, 32, 360, 710, 300, $FF00FFAA, 1.1)
Debug "Number of objects: " + Str(numPhObj)
Debug "Now everything has been set"
; // Start running FrameFunc()
; // At this point the execution stops and everything is handled within
; // the FrameFunc() procedure until it returns #TRUE
hge_System_Start()
Else
; // Error report
error.s = PeekS(hge_System_GetErrorMessage(), -1, #PB_Ascii)
MessageRequester("Error", error, #PB_MessageRequester_Ok)
EndIf
wcpSpaceFree(*phSpace);
wcpBodyFree(*StaticBody);
; // Restore video settings, free allocated resources and release the interface
hge_System_Shutdown()
hge_Release()
EndProcedure
; // Main function
Main()
