Rock Control affects all rocks

I have this code that generates my level and I am not sure I am applying my control correctly because when there is a collision with one rock all of them disappear. This is my code that places the rock into the scene.
[java]private void rndLevel(int Min, int Max, int count) {
int n = 0;
while (n < count) {
n++;
Spatial rock01 = assetManager.loadModel("/Models/rock01/rock01.j3o");
int x = Min + (int)(Math.random() * ((Max - Min) + 1));
int y = Min + (int)(Math.random() * ((Max - Min) + 1));
int z = Min + (int)(Math.random() * ((Max - Min) + 1));
rock01.setLocalTranslation(x, y, z);
rock01.setLocalScale((float) Math.random() * 10);

        CollisionShape rockShape;
        rockShape = CollisionShapeFactory.createDynamicMeshShape(rock01);
        RigidBodyControl rockC = new RockControl(rockShape, 10f);
        rock01.addControl(rockC);
        bulletAppState.getPhysicsSpace().add(rockC);
        
        rootNode.attachChild(rock01);
    }
}[/java] Soo how can I do this so when there is a collision with one rock only that rock explodes and disappears.  

oh and here is the contents of my rock control. [java]public class RockControl extends RigidBodyControl implements PhysicsCollisionListener {
//Any local variables should be encapsulated by getters/setters so they
//appear in the SDK properties window and can be edited.
//Right-click a local variable to encapsulate it with getters and setters.

public RockControl(CollisionShape shape, float mass) {
    super(shape, mass);
}

public RockControl(AssetManager manager, CollisionShape shape, float mass) {
    super(shape, mass);
    //prepareEffect(manager);
}

@Override
public void setPhysicsSpace(PhysicsSpace space) {
    super.setPhysicsSpace(space);
    if (space != null) {
        space.addCollisionListener(this);
    }
}

public void collision(PhysicsCollisionEvent event) {
    if (space == null) {
        return;
    }
    //System.err.println(event.getNodeA().getName());
    //System.err.println(event.getNodeB().getName());
    if (event.getNodeA().getName().contains(&quot;laser&quot;) || event.getNodeB().getName().contains(&quot;laser&quot;)) {
        /**if (effect != null &amp;&amp; spatial.getParent() != null) {
            curTime = 0;
            effect.setLocalTranslation(spatial.getLocalTranslation());
            spatial.getParent().attachChild(effect);
            effect.emitAllParticles();
        }*/
        
        space.remove(this);
        spatial.removeFromParent();
    }
}[/java]

You should read about the PhysicsCollisionListener:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:physics_listeners#physics_collision_listener

Whenever there is a collision ALL listeners registered to the PhysicsSpace will be called. Since every RockControl registers itself as listener everyone of them will be called on the first collision => all rocks is removing themselves from the PhysicsSpace.

2 Likes

I don’t see where you are getting this information from. I read the document and don’t see anything about that in it. If this is the case how should I go about treating rocks individually. It seems like using getNode for the removal makes the most sense.

Hmm, you are right… that page probably needs an update…

[java]
(event.getNodeA().getName().contains(“laser”) && event.getNodeB() == this) || (event.getNodeB().getName().contains(“laser”) && event.getNodeA() == this)
[/java]

That condition should work™… =)

@enigma101 said: I don't see where you are getting this information from. I read the document and don't see anything about that in it. If this is the case how should I go about treating rocks individually. It seems like using getNode for the removal makes the most sense.

Yeah, and it means you only need one listener overall, not one per rock.