# Box2D with SDL2 not working properly (Collision without rotation and problems with MKS)

I already have some expirience using SDL2 so I thought I will add a Physic Engine to my game - I chose Box2D.

I managed to setup everything and to build a small program using SDL2 and Box2D. But now I have come along on two problems I am not able solve:

Firstly, somehow I am not able to convert my pixels to the MKS unit - I always get nearly no output or the collision detection doesn't work anymore. I have commented out the parts where I would normally use the translation to MKS, maybe someone has a clue why it is'nt working.

Secondly, my collision detection doesn't work proberly if an object collides in an angle (e.g. spinned to 45 degrees):

This is how the Box collides without any angle - this works.

But as said if I rotate the box, it doesn't collide properly e.g. it keeps "standing" like this and sometimes even "glitches" forward a little bit:

I guess this isn't normal? Shouldn't the box "stand up"? I think this is due the fact I am not able to convert to MKS? Also I set my gravity to 100.81 since with 9.81 everything is so slow.

Thanks for any help! Here is my code:

#include "GameLoop.h"
#include "Assets.h"
#include "EventHandler.h"

#include <iostream>
#include <iomanip>
#include <Box2D/Box2D.h>

#define FAILED_TO_CREATE_TEXTURE 0x05

using namespace std;

const float P2M = 30;
const float M2P = 1 / P2M;

b2World* world;

int gameLoop(SDL_Window *window, SDL_Renderer *renderer)
{
SDL_Surface* tmp_sprites;
if(!tmp_sprites)
return FAILED_TO_CREATE_TEXTURE;

SDL_Texture* texture_box = SDL_CreateTextureFromSurface(renderer, tmp_sprites);
SDL_FreeSurface(tmp_sprites);

bool close_game = false;
SDL_Event event;

// parameters of the ground platform rectangle (in pixels)
float x_pos_rect = 0.0f;
float y_pos_rect = 219.9f;
float width_rect = 320;
float height_rect = 5;

// parameters of the falling box (in pixels)
float x_pos_box = 0;
float y_pos_box = 0;
float width_box = 10
float height_box = 10;

// Rect to draw platform
SDL_Rect ground;
ground.x = x_pos_rect;
ground.y = y_pos_rect;
ground.w = width_rect;
ground.h = height_rect;

// Rect for a small box to spawn
SDL_Rect box;
SDL_Point center;
box.x = x_pos_box;
box.y = y_pos_box;
box.w = width_box;
box.h = height_box;
center.x = (box.w * 0.5f);// P2M * (box.w * 0.5f);
center.y = (box.h - (box.w * 0.5)); // P2M * (box.h - (box.w * 0.5));

world = new b2World(b2Vec2(0.0f, 9.81f));
world->SetAllowSleeping(false);

b2Body *groundBody;

b2BodyDef groundBodyDef;
groundBodyDef.type = b2_staticBody;
groundBodyDef.position.Set(x_pos_rect, y_pos_rect);// groundBodyDef.position.Set(x_pos_rect * P2M, y_pos_rect * P2M);
groundBodyDef.angle = 0;
groundBody = world->CreateBody(&groundBodyDef);

b2PolygonShape groundBox;
groundBox.SetAsBox(width_rect, 5); // groundBox.SetAsBox(P2M * (width_rect / 2), P2M * (height_rect / 2));

b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundBox;
boxShapeDef.density = 0.0f;
groundBody->CreateFixture(&groundBox, 0);

b2Body* Body;

b2BodyDef ballBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.angle = 0.0f;
ballBodyDef.position.Set(200, 40); // ballBodyDef.position.Set(200 * P2M, 40 * P2M);

Body = world->CreateBody(&ballBodyDef);

b2PolygonShape dynamicBox;
dynamicBox.SetAsBox((width_box / 2), (height_box / 2));// dynamicBox.SetAsBox((width_box / 2) * P2M, (height_box / 2) * P2M);

b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1;
fixtureDef.friction = 0.3f;
fixtureDef.restitution = 0.5f;
Body->CreateFixture(&fixtureDef);

while(close_game != true)
{
keyboardEventHandler(character, close_game, event, Body);

b2Vec2 pos = Body->GetPosition(); // Body = Body from box
float angle = Body->GetAngle();

box.x = pos.x; // * M2P;
box.y = pos.y; // * M2P;
//box.w *= M2P;
//box.h *= M2P;

//ground.x *= M2P;
//ground.y *= M2P;
//ground.w *= M2P;
//ground.h *= M2P;

//center.x *= M2P;
//center.y *= M2P;

SDL_RenderClear(renderer);

// Draws our little box                             rotate
//                                                    |
SDL_RenderCopyEx(renderer, texture_box, NULL, &box, angle, &center, SDL_FLIP_NONE);

// Draws ground platform
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 0);
SDL_RenderFillRect(renderer, &ground);

// Show everything
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderPresent(renderer);

world->Step(1.0f / 60.0f, 6, 2.0f); // update

}

delete world;

return 1;
}


I googled a lot but I couldn't find any useful information. I was going through the tutorial by iforce2d and read the documentation but I couldn't figure it out..

• Your question may need a bit of work. But, as a general guideline, I would suggest getting the Box2D test bed to run on your machine. Have a look at the code there. I also find that implementing a Debug Drawer to be most helpful in these kind of situations. – Willem Sep 17 at 14:11