Ball Falls Through Ground

Official forum for the Chipmunk2D Physics Library.
Post Reply
Leftyguitar
Posts: 3
Joined: Fri Mar 31, 2017 11:52 pm
Contact:

Ball Falls Through Ground

Post by Leftyguitar »

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();
}
viblo
Posts: 206
Joined: Tue Aug 21, 2007 3:12 pm
Contact:

Re: Ball Falls Through Ground

Post by viblo »

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
Leftyguitar
Posts: 3
Joined: Fri Mar 31, 2017 11:52 pm
Contact:

Re: Ball Falls Through Ground

Post by Leftyguitar »

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;
aisman
Posts: 145
Joined: Tue Mar 04, 2008 2:21 am
Contact:

Re: Ball Falls Through Ground

Post by aisman »

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.
Leftyguitar
Posts: 3
Joined: Fri Mar 31, 2017 11:52 pm
Contact:

Re: Ball Falls Through Ground

Post by Leftyguitar »

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));
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Heise IT-Markt [Crawler] and 13 guests