Ball Does not Fall (Raylib & Chipmunk Physics)

Started by
6 comments, last by voidptr_t 1 year, 8 months ago

Hello,

I am trying to make the ball fall down the screen and bounce once it hits the ground. However the ball does not move at all.

#include "raylib.h"

#include "chipmunk/chipmunk.h"

const int WIDTH = 1024;

const int HEIGHT = 720;

cpSpace* space;

cpBody* groundBody;

cpShape* groundShape;

Vector2 groundSize = { 1000,10 };

cpVect groundPos;

cpBody* ballBody;

cpShape* ballShape;

float ballRad = 10.0f; //Radius of ball

cpVect ballPos;

bool Paused = false;

int main()

{

InitWindow(WIDTH, HEIGHT, "Raylib & Chipmunk Physics");

SetTargetFPS(60);

//Setup chipmunk physics world

cpVect gravity = cpv(0, -100);

space = cpSpaceNew();

cpSpaceGetGravity(space);

//setup and add ground body to world, ground is static (doesn't move)

groundBody = cpSpaceAddBody(space, cpBodyNew(0, 0));

groundShape = cpSpaceAddShape(space, cpBoxShapeNew(groundBody, groundSize.x, groundSize.y, 0));

cpShapeSetFriction(groundShape, 0.1f);

cpShapeSetMass(groundShape, 8);

//set position of ground and get ground position

groundPos.x = 1;

groundPos.y = 700;

cpBodySetPosition(groundBody, groundPos);

groundPos = cpBodyGetPosition(groundBody);

ballBody = cpSpaceAddBody(space, cpBodyNew(0, 0));

ballShape = cpSpaceAddShape(space, cpCircleShapeNew(ballBody, ballRad, ballPos));

cpShapeSetFriction(ballShape, 0.5f);

cpShapeSetMass(ballShape, 8);

cpShapeSetElasticity(ballShape, 0.5f);

ballPos.x = 10;

ballPos.y = 10;

cpBodySetPosition(ballBody, ballPos);

cpMomentForCircle(1, 0, ballRad, cpvzero);

while (!WindowShouldClose())

{

if (IsKeyPressed(KEY_P)) Paused = !Paused;

cpSpaceStep(space, 1.0 / 60.0f); //step the simulation

cpVect pos = cpBodyGetPosition(ballBody);

cpVect vel = cpBodyGetVelocity(ballBody);

BeginDrawing();

DrawRectangle(groundPos.x, groundPos.y, groundSize.x, groundSize.y, BROWN);

DrawCircle(ballPos.x, ballPos.y, ballRad, RED);

EndDrawing();

}

cpShapeFree(ballShape);

cpBodyFree(ballBody);

cpShapeFree(groundShape);

cpBodyFree(groundBody);

cpSpaceFree(space);

CloseWindow();

return 0;

}

Advertisement

It looks like you forgot to set gravity. (You get it, but don't set it.)

After that i guess the ground body should have a mass of zero to make it static.

Well I changed it to cpSetGravity and changed the mass of the ground, but still nothing happens. Maybe I'm overlooking something here?

#include "raylib.h"

#include "chipmunk/chipmunk.h"

const int WIDTH = 1024;

const int HEIGHT = 720;

cpSpace* space;

cpBody* groundBody;

cpShape* groundShape;

Vector2 groundSize = { 1000,10 };

cpVect groundPos;

cpBody* ballBody;

cpShape* ballShape;

float ballRad = 10.0f; //Radius of ball

cpVect ballPos;

bool Paused = false;

int main()

{

InitWindow(WIDTH, HEIGHT, "Raylib & Chipmunk Physics");

SetTargetFPS(60);

//Setup chipmunk physics world

cpVect gravity = cpv(0, 100);

space = cpSpaceNew();

cpSpaceSetGravity(space, gravity);

//setup and add ground body to world, ground is static (doesn't move)

groundBody = cpSpaceAddBody(space, cpBodyNew(0, 0));

groundShape = cpSpaceAddShape(space, cpBoxShapeNew(groundBody, groundSize.x, groundSize.y, 0));

cpShapeSetFriction(groundShape, 0.1f);

cpShapeSetMass(groundShape, 1);

//set position of ground and get ground position

groundPos.x = 1;

groundPos.y = 700;

cpBodySetPosition(groundBody, groundPos);

groundPos = cpBodyGetPosition(groundBody);

ballBody = cpSpaceAddBody(space, cpBodyNew(0, 0));

ballShape = cpSpaceAddShape(space, cpCircleShapeNew(ballBody, ballRad, ballPos));

cpShapeSetFriction(ballShape, 0.5f);

cpShapeSetMass(ballShape, 8);

cpShapeSetElasticity(ballShape, 0.5f);

ballPos.x = 10;

ballPos.y = 10;

cpBodySetPosition(ballBody, ballPos);

cpMomentForCircle(1, 0, ballRad, cpvzero);

while (!WindowShouldClose())

{

if (IsKeyPressed(KEY_P)) Paused = !Paused;

cpSpaceStep(space, 1.0 / 60.0f); //step the simulation

cpVect pos = cpBodyGetPosition(ballBody);

cpVect vel = cpBodyGetVelocity(ballBody);

BeginDrawing();

DrawRectangle(groundPos.x, groundPos.y, groundSize.x, groundSize.y, BROWN);

DrawCircle(ballPos.x, ballPos.y, ballRad, RED);

EndDrawing();

}

cpShapeFree(groundShape);

cpBodyFree(groundBody);

cpShapeFree(ballShape);

cpBodyFree(ballBody);

cpSpaceFree(space);

CloseWindow();

return 0;

}

I neither know RayLib nor Chipmunk and do not understand each line of code, but nothing wrong catches my eyes.

I'd try to give the ball some initial velocity, temporally remove the ground body to reduce sources of error, step into cpSpaceStep() with debugger to see what it does.

One thing is not yet handled for sure: Orientation of bodies.
Maybe you must set this up for the bodies on creation, but much more likely the library uses a default orientation so it should work regardless.
Later you sure need to care about that in detail, so the rendering shows something like a rotating box properly.

Usually physics engines also have some option to do a debug render of their bodies. That's some work to set up, but helpful to verify visuals match up and assumptions hold.

It looks like the position of the ball is being stored in the the loop-local variable pos, but, you're drawing with ballPos.

You could change this line:

`cpVect pos = cpBodyGetPosition(ballBody);`

to:

ballPos = cpBodyGetPosition(ballBody);

or draw with that local pos instead. I think that might be the issue, but, it's always hard to say just eyeballing.

Thanks that made the ball fall. However it appears as one long line. I'll try playing with the values and such and see if I can get it. I'll post the updated code in case anyone might see if I'm doing something that's off.

#include "raylib.h"

#include "chipmunk/chipmunk.h"

const int WIDTH = 1024;

const int HEIGHT = 720;

cpSpace* space;

cpBody* groundBody;

cpShape* groundShape;

Vector2 groundSize = { 1000,10 };

cpVect groundPos;

cpBody* ballBody;

cpShape* ballShape;

float ballRad = 10.0f; //Radius of ball

cpVect ballPos;

bool Paused = false;

int main()

{

InitWindow(WIDTH, HEIGHT, "Raylib & Chipmunk Physics");

SetTargetFPS(60);

//Setup chipmunk physics world

cpVect gravity = cpv(0, 100);

space = cpSpaceNew();

cpSpaceSetGravity(space, gravity);

//setup and add ground body to world, ground is static (doesn't move)

groundBody = cpSpaceAddBody(space, cpBodyNew(0, 0));

groundShape = cpSpaceAddShape(space, cpBoxShapeNew(groundBody, groundSize.x, groundSize.y, 0));

cpShapeSetFriction(groundShape, 0.1f);

cpShapeSetMass(groundShape, 1);

//set position of ground and get ground position

groundPos.x = 1;

groundPos.y = 700;

cpBodySetPosition(groundBody, groundPos);

groundPos = cpBodyGetPosition(groundBody);

cpFloat mass = 1.0f;

cpFloat moment = cpMomentForCircle(mass, 1, ballRad, cpvzero);

ballBody = cpSpaceAddBody(space, cpBodyNew(mass, moment));

ballShape = cpSpaceAddShape(space, cpCircleShapeNew(ballBody, ballRad,cpvzero));

cpShapeSetFriction(ballShape, 0.5f);

cpShapeSetMass(ballShape, mass);

cpShapeSetElasticity(ballShape, 0.8f);

ballPos.x = 50;

ballPos.y = 10;

cpBodySetPosition(ballBody, cpv(ballPos.x,ballPos.y));

ballPos = cpBodyGetPosition(ballBody);

cpFloat TimeStep = 1.0 / 60.0f;

while (!WindowShouldClose())

{

if (IsKeyPressed(KEY_P)) Paused = !Paused;

ballPos = cpBodyGetPosition(ballBody);

cpVect vel = cpBodyGetVelocity(ballBody);

cpFloat angle = cpBodyGetAngle(ballBody);

cpSpaceStep(space, TimeStep); //step the simulation

BeginDrawing();

DrawRectangle(groundPos.x, groundPos.y, groundSize.x, groundSize.y, BROWN);

DrawCircle(ballPos.x , ballPos.y , ballRad, RED);

EndDrawing();

}

cpShapeFree(groundShape);

cpBodyFree(groundBody);

cpShapeFree(ballShape);

cpBodyFree(ballBody);

cpSpaceFree(space);

CloseWindow();

return 0;

}

Glad it worked! for the long line, you may just need some sort of clear screen/framebuffer or something like that in raylib, sounds like BeginDraw() doesn’t clear the previous frame.

This topic is closed to new replies.

Advertisement