HGE and Chipmunk... problem

Advanced game related topics
untune
User
User
Posts: 56
Joined: Sun Jul 06, 2008 10:07 pm
Location: Bolton, UK

HGE and Chipmunk... problem

Post by untune »

Hi all,

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