Ball Falls Through Ground

Official forum for the Chipmunk2D Physics Library.

Ball Falls Through Ground

Postby Leftyguitar » Sat Apr 01, 2017 12:00 am

Hello,

I have managed to get Chipmunk Physics and SDL to work... to a degree. I managed to get it where a ball can bounce off the ground, however if I try to make the ball's x position any number greater than 1, it falls through the ground. Chipmunk also brings up the debugger after I close the program. It says Chipmunk has triggered a breakpoint. I've posted the code and the debugger info. I don't know why it throws a breakpoint after the program
closes when the code itself seems to run fine.

EDIT: I figured out the debugger issue. I commented out the delete keyState command, and no more breakpoint
comes up. Still can't figure out the other issue.

I'm using SDL 2.0.5 and C++, Microsoft Visual Studio 2017

Debugger info:
- &groundRect 0x0108d218 {SDLChipmunk.exe!SDL_Rect groundRect} {x=0x00000001 y=0x0000024e w=0x00000320 ...} SDL_Rect *
x 0x00000001 int
y 0x0000024e int
w 0x00000320 int
h 0x0000000a int
GameRen 0x00e64478 {...} SDL_Renderer *
groundTex 0x00e6a2a0 {...} SDL_Texture *

Code: Select all
#include <iostream>

#include "SDL.h"

#include "chipmunk\chipmunk.h"
#include "chipmunk\chipmunk_private.h"

using namespace std;

void Init();
void Gameloop();
void Update();
void Draw();
void Shutdown();

const int MAX_TICKS = 1000;

int Width = 800, Height = 600;
bool GameRunning = true;

SDL_Window* GameWin = NULL;
SDL_Renderer* GameRen = NULL;
SDL_Event event;

SDL_Color yellow = { 255,255,0 };
SDL_Color red = { 255,0,0 };
SDL_Color green = { 0,255,0 };
SDL_Color blue = { 0,0,255 };

long lastTick = 0, curTick = 0;
float deltaTime = 0.0f;

int mx = 0, my = 0; //mouse x & y pos

//for using keyboard input inside update method
const Uint8* keyState = SDL_GetKeyboardState(NULL);
//for state of mouse
Uint32 mState = SDL_GetMouseState(&mx, &my);

bool Physics_Paused = true;

cpVect gravity;
cpSpace* space;

cpShape* groundShape;
cpBody* groundBody;

cpFloat timeStep;

SDL_Surface* ground;
SDL_Texture* groundTex;
SDL_Rect groundRect;

SDL_Surface* ball;
SDL_Texture* ballTex;
SDL_Rect ballRect;

cpBody* ballBody;
cpShape* ballshape;

int ground_x = 1, ground_y = 590;
int ground_w = Width, ground_h = 10;

int ball_x = 1 //if I make this value bigger than 1, the ball falls through , ball_y = 15;
int ball_w = 10, ball_h = 10;

cpFloat radius = 10;
cpFloat mass = 1;

cpFloat angle;

SDL_RendererFlip flip = SDL_FLIP_NONE;

int main(int argc, char* argv[])
{
   Init();

   Gameloop();

   Shutdown();

   return 0;
}

void Init()
{
   if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
   {
      exit(0);
   }

   GameWin = SDL_CreateWindow("SDL Physics", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_WINDOW_SHOWN);
   GameRen = SDL_CreateRenderer(GameWin, -1, SDL_RENDERER_PRESENTVSYNC);

   ground = SDL_LoadBMP("ground.bmp");
   groundTex = SDL_CreateTextureFromSurface(GameRen, ground);
   groundRect.x = ground_x;
   groundRect.y = ground_y;
   groundRect.w = ground_w;
   groundRect.h = ground_h;

   ball = SDL_LoadBMP("ball.bmp");
   SDL_SetColorKey(ball, SDL_TRUE, SDL_MapRGB(ball->format, 255, 255, 255));
   ballTex = SDL_CreateTextureFromSurface(GameRen, ball);
   ballRect.x = ball_x;
   ballRect.y = ball_y;
   ballRect.w = ball_w;
   ballRect.h = ball_h;

   gravity = cpv(0, 100);

   space = cpSpaceNew();
   cpSpaceSetGravity(space, gravity);

   groundShape = cpSegmentShapeNew(space->staticBody, cpv(-groundRect.x, groundRect.y), cpv(groundRect.x, groundRect.y), 0);
   cpShapeSetFriction(groundShape, 1.0f);
   cpSpaceAddShape(space, groundShape);

   groundBody = cpSpaceAddBody(space, cpBodyNew(groundRect.w, groundRect.h));

   cpVect groundPos = cpBodyGetPosition(groundBody);

   cpBodySetPosition(groundBody, groundPos);

   groundBody->userData = &ground;

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

   ballBody = cpSpaceAddBody(space, cpBodyNew(mass, moment));
   cpBodySetPosition(ballBody, cpv(ballRect.x, ballRect.y));
   ballshape = cpSpaceAddShape(space, cpCircleShapeNew(ballBody, radius, cpvzero));
   cpShapeSetFriction(ballshape, 1.0f);
   cpShapeSetElasticity(ballshape, 0.5f);

   cpShapeSetElasticity(groundShape, 1.0f);

   ballBody->userData = &ball;

   timeStep = 1.0f / 60.0f;
}

void Gameloop()
{
   while (GameRunning)
   {
      while (SDL_PollEvent(&event))
      {
         if (event.type == SDL_QUIT)
         {
            GameRunning = false;
         }

         if (event.type == SDL_KEYDOWN)
         {
            if (event.key.keysym.sym == SDLK_ESCAPE)
            {
               GameRunning = false;
            }

            if (event.key.keysym.sym == SDLK_p && Physics_Paused == true)
            {
               Physics_Paused = false;
            }
            else if (event.key.keysym.sym == SDLK_p && Physics_Paused == false)
            {
               Physics_Paused = true;
            }
         }

         if (event.type == SDL_MOUSEMOTION)
         {
            mx = event.motion.x;
            my = event.motion.y;
         }
      }

      Update();

      Draw();
   }
}

void Update()
{
   curTick = SDL_GetTicks();
   deltaTime = (float)(curTick - lastTick) / MAX_TICKS;
   lastTick = curTick;

   if (!Physics_Paused)
   {
      cpVect pos = cpBodyGetPosition(ballBody);
      cpVect vel = cpBodyGetVelocity(ballBody);
      angle = cpBodyGetAngle(ballBody);

      ballRect.x = pos.x;
      ballRect.y = pos.y;

      cpSpaceStep(space, timeStep);
   }
}

void Draw()
{
   SDL_RenderClear(GameRen);

   SDL_RenderCopyEx(GameRen, ballTex, NULL, &ballRect, angle, NULL, flip);

   SDL_RenderCopy(GameRen, groundTex, NULL, &groundRect);

   SDL_RenderPresent(GameRen); //debugger comes up after I close the app on this line
}

void Shutdown()
{
   //delete keyState;

   cpShapeFree(groundShape);
   cpBodyFree(groundBody);

   cpShapeFree(ballshape);
   cpBodyFree(ballBody);

   SDL_FreeSurface(ground);
   SDL_DestroyTexture(groundTex);

   SDL_FreeSurface(ball);
   SDL_DestroyTexture(ballTex);

   SDL_Quit();
}
Leftyguitar
 
Posts: 3
Joined: Fri Mar 31, 2017 11:52 pm

Re: Ball Falls Through Ground

Postby viblo » Sat May 20, 2017 5:30 am

You have several problems.

1. You create a ground body after you create the ground shape, and you make the shape using space->staticBody instead of the groundBody

2. The ground body is made wrong:
Code: Select all
groundBody = cpSpaceAddBody(space, cpBodyNew(groundRect.w, groundRect.h));

Here you create a body and add it to shape. But the input parameters to cpBodyNew should be mass and moment, now width and height!

3. The ground segment is created to go from (-1, -590) to (1,590). I dont think this is what you wanted:
Code: Select all
groundShape = cpSegmentShapeNew(space->staticBody, cpv(-groundRect.x, groundRect.y), cpv(groundRect.x, groundRect.y), 0);







I think what you want to do is
1. Create ground body.
http://www.pymunk.org - A python library built on top of Chipmunk to let you easily get cool 2d physics in your python game/app
viblo
 
Posts: 205
Joined: Tue Aug 21, 2007 3:12 pm

Re: Ball Falls Through Ground

Postby Leftyguitar » Fri Sep 08, 2017 10:01 pm

Thanks for the tip. I've changed the code a little, but I'm still having the same problem.

Code: Select all

   groundShape = cpSegmentShapeNew(space->staticBody, cpv(-groundRect.w, groundRect.h), cpv(-groundRect.x, groundRect.y),1);
   cpShapeSetFriction(groundShape, 1.0f);
   cpSpaceAddShape(space, groundShape);

   groundBody = cpSpaceAddBody(space, cpBodyNewStatic());

   cpVect groundPos = cpBodyGetPosition(groundBody);

   cpBodySetPosition(groundBody, groundPos);

   groundBody->userData = &ground;
Leftyguitar
 
Posts: 3
Joined: Fri Mar 31, 2017 11:52 pm

Re: Ball Falls Through Ground

Postby aisman » Sun Sep 10, 2017 4:50 am

Leftyguitar wrote:Thanks for the tip. I've changed the code a little, but I'm still having the same problem.

Code: Select all
   groundBody = cpSpaceAddBody(space, cpBodyNewStatic());
   cpVect groundPos = cpBodyGetPosition(groundBody);
        cpBodySetPosition(groundBody, groundPos);

Tell me what this code is doing.

Please look on the demo source example too. That's be good for beginners.
Chipmunk4PB: The fastest way to write games together with PureBasic and the Chipmunk physics engine.
User avatar
aisman
 
Posts: 140
Joined: Tue Mar 04, 2008 2:21 am

Re: Ball Falls Through Ground

Postby Leftyguitar » Wed Sep 13, 2017 9:32 pm

I figured it out. After looking at the player.c example in the Chipmunk pacakage. I changed the code to this.

Code: Select all
groundBody = cpSpaceGetStaticBody(space);

   groundShape = cpSpaceAddShape(space, cpSegmentShapeNew(groundBody, cpv(groundRect.x, groundRect.y), cpv(groundRect.x, groundRect.y), 0.0f));
Leftyguitar
 
Posts: 3
Joined: Fri Mar 31, 2017 11:52 pm


Return to Chipmunk2D Physics

Who is online

Users browsing this forum: No registered users and 4 guests