[SOLVED]Update and Iterate or onContactBegin and Bitmasks for Collision Detection?

In my game that I’m making I have asteroids spawning and going across the screen. The player can then shoot them with their ship and destroy the asteroid. The asteroid breaks apart into smaller asteroids and so on.

Right now I use physics bodies to apply velocity to the asteroids to move them across the screen. I have a bitmask on the physics bodies that I use in the onContactBegin method to test collision with the edgeNode, other asteroids, bullets, and the ship. If the asteroid is hit by the bullet, the asteroid is removed using nodeA(orB)->removeFromParentAndCleanup(true);.

I want to update my game to have health as a factor of gameplay. I want the asteroids to have a set amount of health and the bullets inflict damage until the asteroids break apart into smaller asteroids. But how can I do that in onContactBegin? All you get from that method is the cocos2d::PhysicsContact &contact. How can I decrement health using this?

This is where I thought of using the update(float dt) method to iterate through a vector of asteroids and check if they are colliding and then decrementing the health by accessing a variable in the asteroids class. This would work, but wouldn’t that completely remove the purpose of using bitmasks for collision and onContactBegin?

I need to know if there is a way to do this without having to use the update method.

You can attach a ComAttribute to your asteroid node.

An example would be:

Initialization of asteroid:

auto attributeComponent = ComAttribute::create();
attributeComponent->setInt("health", 10);
attributeComponent->setName("AttributeController"); //an identifier for us to get the component when we need it.
asteroidNode->setComponent(attributeComponent);

When the asteroids collided in your onContactBegin:

auto attributeController = static_cast<ComAttribute*>(nodeA->getComponent("AttributeController"));
int health = attributeController->getInt("health");
health--;
if (health == 0)
{
    //do your cleanup
}
else
{
    attributeController->setInt("health", health);
}
1 Like

Thank you duracellrabbid!! I will try out your solution and get back to you in a bit. It seems like this will work.

You’re welcomed, the code was actually adapted from one of the examples in cpp_test, so it should be able to work in any method which you use to detect collision.

When I tried adding the header file for ComAttribute using this page http://www.cocos2d-x.org/reference/native-cpp/V3.5/db/d5b/classcocostudio_1_1_com_attribute.html with <CCComAttribute.h> it said the file was not found. What header files do I need to add for it? I noticed that the on the bottom of the page it said
The documentation for this class was generated from the following file: /Users/minggo/SourceCode/cocos2d-x/cocos/editor-support/cocostudio/CCComAttribute.h
Does this mean I need to install cocostudio? I also updated cocos2d-x from 3.2 to 3.6 just to make sure I didn’t need to update. Sorry for the questions if they seem dumb. I’m still learning.

I created a new cocos Project and tried the CCComAttribute header file and tried your example, but it still doesn’t recognize the header file?

I found the header file at /Applications/Cocos/frameworks/cocos2d-x-3.6/cocos/editor-support so why can it not find the header file?

I’ve figured it out. So you have to include this at the top

#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"

#include "cocostudio/CCComAttribute.h"
using namespace cocostudio::timeline;
using namespace cocostudio;

Then I got confused at the part

It’s actually supposed to be asteroidNode->addComponent(attributeComponent);

Thank you duracellrabbid for helping me out. I really appreciate it a ton.

ha ha ha, sorry for the wrong code. the convention tends to be set rather than add.

It’s fine. I figured it out in the end. Thanks for your help