Dynamic passes Static Body if velocity is high

I tried Dynamic Physics Body passes through a static physics body after little resistance but it didn’t work for me.

Here’s my code

I have a static wall

auto spriteBody = PEShapeCache::getInstance()->getPhysicsBodyByName(physicsSTR);
wall->setPhysicsBody(spriteBody);
spriteBody->setRotationEnable(true);
spriteBody->setDynamic(false);
spriteBody->setCollisionBitmask(2);
spriteBody->setCategoryBitmask(1);
spriteBody->setContactTestBitmask(2);

and the dynamic object

auto physicsBodyTemp = PhysicsBody::createCircle(spawnedMonster->getContentSize().width / 2, PhysicsMaterial(100.0f, 0, 100.0f));
physicsBodyTemp->setGravityEnable(false);
physicsBodyTemp->setRotationEnable(false);
physicsBodyTemp->setCollisionBitmask(1);
physicsBodyTemp->setCategoryBitmask(2);
physicsBodyTemp->setContactTestBitmask(1);

You’ll need to look into using “continuous collision” instead of the standard collision since your dynamic body must be moving across the static body in a single step. This will check for collisions using a ray instead of single position.

Hi thank you for replying. Where can i find continous collision?

Look for PhysicsFixedUpdate test in PhysicsTest.cpp class provided with Cpp-Test demo, This test simulates physics world with more precise collision detection, ideally search for The secend ball should not run across the wall inside PhysicsTest.Cpp file.

is it in chipmunk?

…Found it. Will try to implement :slight_smile: thanks!

Hi I followed the test but still, objects passes through the wall :cry:

can you please post your code, so that we can understand your issue state better? what you have implemented from that test etc?

I Think OP is using internal Physics(Chipmunk wrapper), and AFAIK chipmunk doesn’t allow out of the box solution like Box2D for continuous collision detection(correct me if i am wrong).

here it is, I actually have shorten them. If you need more details on how I created the bodies I have posted it in my OP

**in my INIT**    
 {
    .....
    ..
    ....
    spawnMainEntities(); //including player
    wallAndtilesCreation(); 
    DungeonSpawning(); //spawns monsters
        
    scheduleOnce(CC_SCHEDULE_SELECTOR(DungeonScene::updateReady_dg), 2);
        
    return true;
}

void DungeonScene::updateReady_dg(float delta)
{
	this->getScene()->getPhysicsWorld()->setAutoStep(false);
	this->scheduleUpdate();
}

void DungeonScene::update(float delta)
{
  	for (int i = 0; i < 3; ++i)
  	{
  		this->getScene()->getPhysicsWorld()->step(1 / 180.0f);
   	}
   	GameUpdate(); //other logical operations in the game
}

yes @Lazy_Gamer is right.

also Im using CodeandWeb’s physics editor so that I don’t have to manually create the physics shape.

If you want your physics world to update 3 times faster then call scheduleUpdate() in your init() method of gamePlay scene/layer. you can safely ditch these lines safely
void DungeonScene::updateReady_dg(float delta) { this->getScene()->getPhysicsWorld()->setAutoStep(false); }

are you setting your sprite positions manually or setting velocity on bodies manually? if yes then avoid it as setting positions/ velocity on physics sprites will over ride collision data. are your bodies moving way too fast or they are slow, please explain what is exatly happening when they approach wall, are they swiftly crossing walls or is there any resistance involved?

Hi, thanks again. Do I still have to do
for (int i = 0; i < 3; ++i)
{
this->getScene()->getPhysicsWorld()->step(1 / 180.0f);
}

At the beginning of my update?

Sorry but I didn’t get this, can you explain further
“are you setting your sprite positions manually or setting velocity on bodies manually?”

As what I have observed. There is actually a resistance but when they try to (dynamic objects) move again at that moment they are already so close to the wall/static object) they will pass through. The dynamic objects that I am referring to is the enemies, they will always try to move towards if they can detect the player nearby, because that is how I coded them.

Another case, the player has a dash skill. This dash skill will increase the player’s velocity towards a certain direction by using MoveTo. High velocity is also the cause.

Well then you can look up how to integrate and use Box2D instead of chipmunk, wait for the new open source chipmunk pro 7.0 to be integrated, or look up the details of calculating collisions using continuous detection or ray based collisions. Or have every object move at no more than a maximum velocity limit that makes sure no body can pass through a wall. Or increase the size of your walls.

Running multiple steps of the simulation per frame will just increase the maximum velocity your objects can travel without tunneling through walls.

This isn’t a “here’s code to fix your problem” issue. It’s a fundamental component of your game’s design: how fast you want or need your entities to move and how thin you want or need your static objects (walls) to be.

Hi, so what are you suggesting. I should switch to box2d because the current chipmunk won’t solve my problem? I can’t just limit their maximun velocity all the time, because there times that they really have to move fast like what I said if the object has a dash skill

Yes. I think my main point is that bullet-velocity collision detection is usually a feature component of a game’s design where you either just fudge things to make it look good or you really need that level of fine-grained collisions. Either way it’ll probably involve a bit of work integrating code or writing it.

You could merge the PR for chipmunk into your own branch.
You could write your own physics for your needs and do the CCD yourself.
You could use Box2D.
You could fake it if your game’s physics is simple enough or if you’re really just using it for collisions.
You could bring in an open source collision-only system that supports bullet velocities.

Maybe someone else has done this before with cocos2d (i’ve only experimented with a separate box2d only test project) and will offer a more concrete solution.

Appologies for late Reply , i was out of town :relaxed: [quote=“jvfiel, post:14, topic:25684”]
Hi, thanks again. Do I still have to do for (int i = 0; i < 3; ++i) { this->getScene()->getPhysicsWorld()->step(1 / 180.0f); }

At the beginning of my update?
[/quote] Yes this code means, for each update call of your game world(cocos2d-x) we will calculate our physics world 3 times, this will ensure our physics world update 3 times faster then our game world,

[quote=“jvfiel, post:14, topic:25684”]
Sorry but I didn’t get this, can you explain further"are you setting your sprite positions manually or setting velocity on bodies manually?"
[/quote] as you already told in your reply your enemies…

[quote=“jvfiel, post:14, topic:25684”]
will always try to move towards if they can detect the player nearby, because that is how I coded them.
[/quote] i can safely assume you are calculating and setting their position/velocity manually every update or using some kind of MoveTo/MoveBy action. This needs to be changed as pointed by @stevetranby

[quote=“stevetranby, post:15, topic:25684”]
This isn’t a “here’s code to fix your problem” issue. It’s a fundamental component of your game’s design: how fast you want or need your entities to move and how thin you want or need your static objects (walls) to be.
[/quote] I can think of two three solutions/ hacks in order to solve this, but you need to test them to be sure. Real solution might lie in combination of these points.

  1. Make sure you don’t use setPosition(), setVelocity() on your enemies and player use applyImpulse() every where, for it to work properly you need to filter collision callbacks,
  2. Use Boolean flags, when player/enemies collide with walls don’t applyImpulse(), setVelocity(), setPosition() to them let physics world handle collisions, Again you need to filter Collision callbacks to keep track of which bodies collide with whom. This might get too heavy to manage eventually, if your game has more categories.
  3. Use thick walls again don’t manipulate enemies/player manually let physics world do its magic.
  4. Use Box2D and leverage continuous collision Detection from it, but i am not sure how it will behave under these circumstances where u are setting positions.
    Look into these links for info on how to filter collision for internal physics (chipmunk wrapper).
    PhysicsBody dont stop bounce

[quote=“jvfiel, post:16, topic:25684”]
I should switch to box2d because the current chipmunk won’t solve my problem?
[/quote]Chipmunk doesn’t provide out of the box solution but that doesn’t mean you can’t use hacks to code a solution for you, above approach worked for me many times.

1 Like

I do have setPosition() and setVelocity(), what should I use instead?
As of the moment I have thicken my boundaries so that they will not be able to pass through.

…Got it, found applyImpulse() will try to apply in a while. Thanks!

Sorry, I assumed wrongly based on your discussion you had very high speed projectiles (bullets). Your game may still need those, but it is probably true that most games don’t need such high velocity objects to track collisions. A shoot-em-up, for example (galaga, etc), running at 1/180s simulation steps should easily behave correctly with reasonably sized enemies where bullets only collide with enemies.

As long as all walls (including any objects that can collide) are thick enough where your bullets velocity prevents it from moving from one side of the wall (outside) to the other side (outside) then you’re good to go!

Just need to make sure that bullet can’t travel through smallest object and you can just use regular physics w/o CCD:
|max_bullet_velocity| * 1 / step_per_sec < min_wall_length
|max_bullet_velocity| = bullets top speed (units per second)
step_per_sec = 180 in your case
min_wall_length = the smallest distance (in units) that any wall or object has from one side to the other

I also stuff on the same problem.
But my game is crashed when I call the below function:
auto scene = Director::getInstance()->getRunningScene();
scene->getPhysicsWorld()->setSubsteps(3);