[Solved] Does an instance of a Control interfere with other instances?

Hello!

So I am building a 2d top-down game and right now I am at an impasse because for some reason, spawning multiple mobs with new instances of a specific control (a custom collision detection) breaks the way the previous mobs are handled.

My current flow is as follows:

In the main simpleInitApp() I call

maker = new charMaker(assetManager, settings, stateManager, battleNode);
maker.createSpatial(“Player”);
maker.createSpatial(“Player2”);
maker.createSpatial(“Mob1”);
maker.createSpatial(“Mob2”);

everything gets attached to a battleNode (a child of guiNode). charMaker keeps my simpleInitApp neat

the createSpatial method in the charMaker class has

node.addControl(new CollideCont(bNode));

so every character that gets made has a collision control on it. It is fairly basic and only uses AABB (all spatials are rectangular and on the same plane) The collision control works like this

protected void controlUpdate(float tpf) {
for (int i = 0; i < battleNode.getQuantity(); i++) {
Spatial curChild = battleNode.getChild(i); //spatial to test against
if (!curChild.equals(spatial) ) { //not self
int val = satTest(spatial, curChild);
if (val > 0) {
switch (val) {
case 1: //no left
spatial.setUserData(“canL”, false);
break;

… and continues for the other cases. satTest is the Separating Axis Theorem. But basically I use flags to tell the game if player can move or not.

Finally, the movement control

protected void controlUpdate(float tpf) {
if(keyLeft){
if((Boolean) spatial.getUserData(“canL”)){
moveLeft();
}
}

keyLeft is set by an actionListener.

Where I am, the collideCont works perfectly fine and will report collisions in every case. My problem is that the movement control will let the player pass through player2 and mob1 but NOT mob2, even though collisions are reported for player2 and mob1. If I got rid of the code to spawn mob2, player can pass through player2 but will stop moving when it bumps into mob1, and so on if I removed mob1. I want it so that player will stop moving when it collides with any object on battleNode. Is this a gotcha in the way Controls are handled or…?

Let me know if I need to do anything else to explain. Thanks in advance!

Well, unless it’s a bug in the code we can’t see, it’s most likely an ordering issue.

…that is the weird (and bad) thing about about handling player input in a control instead of an app state.

What you said was interesting so I refactored the movement control into an AppState but no dice. It’s also true that there is an ordering issue as spawning mob1 and mob2 before player2 makes player2 collidable but not the mobs.

What I don’t understand is why that would be the case. Is there something in the handling of the update loop for the collideCont vs. moveAppState that makes one or the other ignore certain inputs?

I also considered multithreading for awhile before I realized that the issue wasn’t in my collideCont (it will report collisions but still let me pass through). But do you think that might help at all?

Thanks for your reply!

It’s likely there is some issue in your collision routine that seems to be sensitive to object ordering. We can’t see that code. Either that or there is some issue with battleNode management. It is a little weird that you make every control loop through all of the either objects when even this might be more easily managed centrally (and you can avoid the n^2 runtime in favor of n * (n - 1) / 2 runtime or whatever.)

AppState.update is run first. Then all control updates are run in scene graph order. This now seems unlikely to be a JME infrastructure related problem now. You should debug your loops to see what collisions are being missed. (which would also be easier if you only had one loop and not one-per-control)

1 Like

Thanks for your input. After taking a good 40-50 minutes figuring out the debugger I found it actually is an error in the collision loop. After registering a collision, the for loop that checks all objects keeps going which will reset the flags that were raised on the previous collision. That’s why only the last spatial added to battleNode actually stops movement even though all the other spatials register collisions.

I’ll mark this as solved, having nothing to do with controls (although it was interesting to know appstates go before controls). Thank you so much!