Libgdx and Box2D with android studio: Why isn’t the ball responding to touch inputs?

public void create () { 

. . . . . Gdx.input.setInputProcessor(new PlayerControl(camera, BallBody));


        public boolean isPointOnPlayer(float x, float y){             for(Fixture fixture : BallBody.getFixtureList())                 if(fixture.testPoint(x, y)) return true;             return false;         }      public class PlayerControl extends InputAdapter {                  private Vector3 _touchPosition;          public PlayerControl(Camera camera, Body ballBody) {             _touchPosition = new Vector3();         }          @Override         public boolean touchDown(int screenX, int screenY, int pointer, int button) {             // don't forget to unproject screen coordinates to game world               camera.unproject(_touchPosition.set(screenX, screenY, 0F));             if (isPointOnPlayer(_touchPosition.x, _touchPosition.y)) {                 // touch on the player body. Do some stuff like player jumping                 BallBody.applyForce(new Vector2(0, 100f),new Vector2(0, 10f),true);                   return true;              } else                 return super.touchDown(screenX, screenY, pointer, button);         }       } 

Box2d: High screen resolution / frequency causes high friction?

I’m using Cocos Creator with (built-in) box2d for physics.

Recently our game behaves weirdly on our new device Galaxy S20 Ultra 5G – which has screen size = 1440 x 3200 – frequency = 120Hz.

After stop pushing, all our physical bodies almost stop immediately like they has very high friction. No other device react that way.

Anyone experienced this issue can give me an advice?

Box2D simulation doesn’t work

I previously used Box2D and it always worked fine until recently I decided to test how it would work in my custom 2D game engine, I just wanted to test the physics updates without any GUI interaction, as you can see in the below code I just try to print the plain position values of the dynamic body and it just doesn’t move. All it does is print the initialisation position I set in the initialiser, afaik all I’m trying to do it print the values in a simple loop that runs more than 60 times per frame, the box2d code doesn’t interact with the rendering in anyway. IDK what’s wrong with box 2d to run fine in a simple loop. I’m really confused why the simulation isn’t happening. Let me know if you need more info about anything.


 #include <fireworks/fireworks.h>  #include <box2d/box2d.h>  using namespace fireworks;  class FreeFall : public Fireworks { private:     Window*         m_Window;     Layer*          defaultLayer;      b2Vec2          m_Gravity;     const double    m_PhysicsTimeStep = 1.0f / 60.0f;     unsigned int    m_VelocityIterations;     unsigned int    m_PositionIterations; public:     b2World* world;      b2BodyDef       groundBodyDef;     b2Body*         groundBody;     b2PolygonShape  groundShape;     b2FixtureDef    groundFixtureDef;      b2BodyDef       dynBoxBodyDef;     b2Body*         dynBoxBody;     b2PolygonShape  dynBoxShape;     b2FixtureDef    dynBoxFixtureDef;      Sprite*         ground;     Sprite*         dynBox; public:     FreeFall()         : m_Gravity(b2Vec2(0.0f, -29.81f)), m_VelocityIterations(6), m_PositionIterations(2)     {         world = new b2World(m_Gravity);         // Static ground body         groundBodyDef.position.Set(0.0f, -10.0f);         groundBody = world->CreateBody(&groundBodyDef);         groundShape.SetAsBox(20.0f, 4.0f);         groundFixtureDef.shape = &groundShape;         groundFixtureDef.density = 1.0f;         groundFixtureDef.friction = 0.3f;         groundBody->CreateFixture(&groundFixtureDef);          // Dynamic simulation box         dynBoxBodyDef.type = b2_dynamicBody;         dynBoxBodyDef.position.Set(-1.0f, 4.0f);         dynBoxBody = world->CreateBody(&dynBoxBodyDef);         dynBoxShape.SetAsBox(2.0f, 2.0f);         dynBoxFixtureDef.shape = &dynBoxShape;         groundFixtureDef.density = 1.5f;         dynBoxFixtureDef.friction = 0.25f;         dynBoxBody->CreateFixture(&dynBoxFixtureDef);     }      ~FreeFall()     {         delete defaultLayer;         delete world;     }      // Runs once per initialisation     void init() override     {         m_Window = createWindow("Freefall physics sim", 800, 600);         glClearColor(0.8, 0.8f, 0.2f, 1.0f);               }     // Runs once per second     void tick() override { }      // Runs 60 times per second     void update() override { }      // Runs as fast as possible     void render() override     {         //Physics Update         world->Step(m_PhysicsTimeStep, m_VelocityIterations, m_PositionIterations);         b2Vec2 dynPos = dynBoxBody->GetPosition();         std::cout << "dynnamic Box2d Box position X : " << dynPos.x << " and Y is : " << dynPos.y << std::endl;     } }; 


#include "physics-sims/Freefall.h"  int main() {     FreeFall game;     game.start();     return 0; } 

This is the output I get : dynnamic Box2d Box position X : -1 and Y is : 4 for as long as the loop runs, this is soo infuriating, IDK what’s breaking what.

Unable to rotate box2d body with torque if revolute joint introduced

I created a simple body (PLAYER) which, as speed increased the angle of the body increases slightly. I set the torque property based on velocity, to change the body’s angle, and it looks like the player is leaning forward as he runs. Great.

I wanted to prevent my PLAYER from flipping over (when hitting other bodies), so I created a second body and placed a revolute joint between them. The second body has rotation disabled, and is dynamic. I discovered that I did not need to apply any angle limits to prevent flipping, since the joint seemed to resist rotation. The player actually rights himself if flipped on his side. (The joint seems to want to return to 0 angle). The motor is disabled, no motor speed, no motor torque. Still, the joint returns to 0′.

The PLAYER still rotates a bit when hitting other bodies, but I can no longer rotate the body with any torque value (to make him lean forward). Why? I need to restore the leaning effect.

I don’t understand why the second body + revolute joint prevent rotation due to any torque applied. Can someone explain, and offer solution?

What would be the best way to let Box2D handle collision on different (simulated) heights?

I’m working on a 2D top-down game but we are also using a Z coordinate. This is to simulate the effect of 3D/height. Now the player can walk under a bridge and also over a bridge. The next thing I did was manage collision at these different heights. I got it working that the player collides with the bridge edge when he walks over it, but when he walks under it, he doesn’t collide. But I’m not sure if I’ve done this correctly.

The way I’m currently doing it, is using different bits for different heights:

public static final short ENTITY_Z0_BIT = 1; public static final short ENTITY_Z1_BIT = 2; public static final short ENTITY_Z2_BIT = 4; public static final short COLLISION_Z0_BIT = 8; public static final short COLLISION_Z1_BIT = 16; public static final short COLLISION_Z2_BIT = 32; 

And then a collision body on Z 1 (or second floor) will have the following filter:

fixtureDef.filter.categoryBits = COLLISION_Z1_BIT; fixtureDef.filter.maskBits = ENTITY_Z1_BIT; fixtureDef.filter.groupIndex = (short) 0; 

This will mean the wall on the second floor will only collide with an entity on the second floor, because I also change the entity’s filter depending on if their Z coordinate increases/decreases. This means I have to add more bits if I need a higher simulated Z-axis and it also doesn’t allow for dynamic z-axis handling as I will need to do a big switch-case or if-statements for every Z-axis and then set the filter accordingly.

My second option was setting the groupIndex to be the same as the collision/entity’s z-axis + 1. If a collision body and an entity body both have groupIndex 1, they will ALWAYS collide. However if the entity moves up on the z-axis, it’s groupIndex will be set to 2 and thus it won’t collide anymore. This also seemed like a nice and more dynamic idea. But then anything that needs to collide with a wall or entity, automatically also collides with all the other bodies that need the same groupIndex for the same reason. This doesn’t allow for a lot of flexibility.

Which of these 2 options is best? And if there’s another better way to handle this, do let me know!

Unexpected output from the merging of a quadtree, when that data is converted to Box2D fixtures

I’ve been staring at this code trying to troubleshoot this for the past 3 days, but I seem to have gone Code Blind. I KNOW the issue is stupidly simple, but I just can’t crack the problem.

I’m using a bastardized quadtree to store the terrain for a map. Each node is either full of children, or stores an instance of a tile (position data is saved in the tile). tile stores its AABB (x,y,w,h), and block type (1 = ground, 0 = air/nothing). Later it will store objects and entities as well. Inserting (right now) does NOT cause merging – that is a separate function call.

The darn thing renders properly if drawn to a Pixmap. Which drives me absolutely crazy.

Expected Output (image generated to PixMap from data) :

Expected output from a properly merged quadtree

Output WITHOUT merging (tile width/heigh is 8 pixels), totally as expected :

Perfectly normal representation of the above quadtree, without merging of same blocks (all data 8x8 pixel squares)

Output WITH merging (bizzare.) : The same exact quadtree in all other images, except the squares are not aligned at all.

Code which I am fairly sure is the problem (from the tile class) PPM is a constant defined elsewhere (Pixels Per Meter), set to 8. This is all rendered through LibGDX :

    public void setPhys(World w) {     if(this.block != 0) {         this.bdef = new BodyDef();         NovaLog.debug("bdef.position.set(" + (this.aabb.x / PPM) + ", " + (this.aabb.y / PPM) + ");");         bdef.position.set(this.aabb.x / PPM,this.aabb.y / PPM);         bdef.type = BodyType.StaticBody;         this.body = w.createBody(bdef);          PolygonShape shape = new PolygonShape();         NovaLog.debug("shape.setAsBox("+((this.aabb.width / PPM)/2) + ", " +  ((this.aabb.height / PPM)/2) +");");         shape.setAsBox((this.aabb.width / PPM)/2, (this.aabb.height / PPM)/2);         this.fdef = new FixtureDef();         this.fdef.shape = shape;         this.fixture = this.body.createFixture(fdef);         this.fixture.setUserData(this);     } } 

At this point, I’m a Westworld Host looking at something that could do harm to his psyche – “It doesn’t look like anything to me.” Please help – the bruise on my forehead from banging my head against the wall is growing larger.

How to differentiate between colliding objects in Box2D?

I need to differentiate between different points of contact in my racing game.

I currently have staticSensors which determine if the car is on the track or not, but I have created a second sensor to act as the ‘finish line’ but I am not sure how to differentiate the contact between the ‘checkeredFlag’ and all of the other sensors?

Any help would be appreciated! Here is my code:

include “contactListener.h”

void ContactListener::BeginContact(b2Contact* contact) { b2Body* bodyA = contact->GetFixtureA()->GetBody(); b2Body* bodyB = contact->GetFixtureB()->GetBody();

bool isSensorA = contact->GetFixtureA()->IsSensor(); bool isSensorB = contact->GetFixtureB()->IsSensor();  Wheel * wheel = (Wheel*)bodyA->GetUserData(); CheckeredFlag * flag = (CheckeredFlag*)bodyB->GetUserData();  if (isSensorA) {     StaticSensor * sensor = static_cast<StaticSensor *>(bodyA->GetUserData());     sensor->action();     Wheel * wheel = static_cast<Wheel *>(bodyB->GetUserData());     wheel->offRoad();     return; }  if (isSensorB) {     StaticSensor * sensor = static_cast<StaticSensor *>(bodyB->GetUserData());     sensor->action();     Wheel * wheel = static_cast<Wheel *>(bodyA->GetUserData());     wheel->offRoad();     return; }  if (typeid(CheckeredFlag).name() == typeid(bodyA).name()) {     if (typeid(Wheel).name() == typeid(bodyB).name())         {         flag->action();         return;         } }