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