Physics collision cause program to abort

Hi. I am working on learning Cocos2d-x (v3.17.2) by programming the classic artillery game (2 cannons fire shells in hyperbolic arc at given angle and force - simple but covers basics of IO, sprites, etc.).

When my falling sprite’s edge (gravity physics) hits edge I placed on view, program aborts in source ccPhysicsBody.cpp L376:

void PhysicsBody::setPosition(float positionX, float positionY)
{
    cpVect tt;

    tt.x = positionX + _positionOffset.x;
    tt.y = positionY + _positionOffset.y;

    cpBodySetPosition(_cpBody, tt); // <--ABORT HERE
}

Based on test cpp and internet I have:

  1. Created scene and a sprite
  2. Added physic and gravity to scene and sprite - which now convincingly start falling and accelerating.
  3. Added an edge box to view like test cpp, and edge box to sprite
  4. Enabled debugging for physics and edges - I see box around sprite and view as expected.
  5. When sprite hits view edge, the sprite edge box goes a few pixels across view edge, and I get a program abort in void PhysicsBody::setPosition(float positionX, float positionY)

Can anyone offer suggestions to why collision leads to abort in physics code? What I missed / should change?
Note, if I remove the edge from sprite physics body it falls off screen as expected without crash, so I think problem is about physics and edges, not going off-screen.

My Code in scene init (some removed for clarity):

initWithPhysics();
getPhysicsWorld()->setGravity(Vec2(0, -980));

//Create edge around view
auto node = Node::create();
	node->addComponent(PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size));
	node->setPosition(VisibleRect::center());
	this->addChild(node);

getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); //show collision boxes

//add cannon class' sprite to scene
this->addChild(_cannon1.Sprite(), 2);

//add physics to sprite
auto pb = PhysicsBody::create();
pb->addShape(PhysicsShapeEdgeBox::create(_cannon1.Sprite()->getContentSize()));
_cannon1.Sprite()->setPhysicsBody(pb); //need edge or cannon falls through ground - if not here no crash

//place in center to fall
_cannon1.Sprite()->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));

this->scheduleUpdate();

return true;

You found where it happens, but you need to dig deeper to find out what is triggering it. Is _cpBody valid? Follow it in a debugger, or add a conditional breakpoint etc. You need to go into that cpBodySetPosition() method and find out what is causing the issue.

Thanks for reply R101.

I am not able to step into “cpBodySetPosition”, it is part of the chipmunk library AFAIK.

It does get called as sprite is falling, without problem, until hitting edge.
While falling tt has “reasonable” values. I have no idea if _cpBody is valid - it is not null. When abort happens tt=(0.0,0.0) which may be reasonable or not, no sign if cpBody is valid or not, but is not null.

By the way, how to you do markup for code? From welcome note I tried “…” and “’’’” but neither seem to work.

Use backticks!

1 Like

You could try Box2D instead of Chipmunk, or alternatively, add the Chipmunk source code to your project, and build it from there. That way you can step into the source code of Chipmunk. I think the source that is used may be the one from here: https://github.com/cocos2d/cocos2d-x-external

You would have to disable the Chipmunk library that comes with Cocos2d-x in order to get this working. You can do that by setting this in your game CMakeLists.txt before the include(CocosBuildSet) line:

set(BUILD_EXT_CHIPMUNK OFF CACHE BOOL "Build with internal chipmunk support" FORCE)

You can then add the steps to build and link the Chipmunk library with something like this:

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/path/to/chipmunk ${PROJECT_BINARY_DIR}/chipmunk)
get_target_property(chipmunk_INCLUDE_DIRS chipmunk INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(cocos2d PRIVATE ${chipmunk_INCLUDE_DIRS}) #cocos2d lib needs the path too
target_link_libraries(${APP_NAME} chipmunk)
target_include_directories(${APP_NAME} PRIVATE ${chipmunk_INCLUDE_DIRS})

I use something similar to the above CMake script section for building Box2D, since I don’t use the one that is included within Cocos2d.

Thanks
Is there any way to edit my old posts to “fix” this?

Thanks R101 - it is good to have instructions if I need to do this in the future.

Luckily I managed to solve problem by experimenting before needing to include Chipmunk library source (not sure why my approach was bad but as long as it works now).

I examined some of test cpp code in more details, and copied pertinent parts into my scene - and they worked. I then modified my code to match - and it worked!

Adding edges to a plain physics object seems to cause crash, whereas using createBox works.

In case this helps someone else, this is the 3 lines that cause crash (making plain body and adding edges), and 2 lines that work (using createBox)

// This way leads to crash on edge collision
auto pb1 = PhysicsBody::create(); // Seems OK (sprite falls as expected but does not hit edge)...
pb1->addShape(PhysicsShapeEdgeBox::create(_cannon1.Sprite()->getContentSize())); // BUT adding edge leads to crash on collision
_cannon1.Sprite()->setPhysicsBody(pb1);

// This way does not lead to crash
auto pb2 = PhysicsBody::createBox(_cannon2.Sprite()->getContentSize());
_cannon2.Sprite()->addComponent(pb2);  // Wonder how setPhysicsBody above differs addComponent - both seem to work here
1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.