Jump to content

Disposed meshes still colliding


TechSlave
 Share

Recommended Posts

Hey there!

I'm making a game based on Megamania (Atari 2600) for my end of graduation work and i'm having problems with the Dispose function.

When i click the mouse, the ship shot a bullet, then it "intersectsmesh" with a box, the box and the bullet are disposed, but "something" invisible stays in the place, if i shoot at that place again the bullet is destroyed even if technically nothing is there.

this is the function:

window.addEventListener("click", function(e) {
      console.log(score);
      scene.registerBeforeRender(function() {
        bullet.position.y = bullet.position.y + 10;
      })

      var bullet = BABYLON.Mesh.CreateCylinder("bullet", 5, 1, 1, 6, 1, scene);

      var BstartPos = ship.position;
      var posVec = new BABYLON.Vector3(BstartPos.x, BstartPos.y + 17, BstartPos.z);
      bullet.position = posVec;


      scene.registerBeforeRender(function shot() {
        for(var i1 = 0; i1 < enemy1.length; i1++) {
          if(enemy1[i1].intersectsMesh(bullet, true)) {
            bullet.dispose();
            enemy1[i1].dispose();

            score = score + 1;
          scene.unregisterBeforeRender(shot);

}
        }
        for(var i2 = 0; i1 < enemy2.length; i2++) {
          if(enemy2[i2].intersectsMesh(bullet, true)) {
            bullet.dispose();
            enemy2[i2].dispose();
            scene.unregisterBeforeRender(shot);
            score = score + 1;
          }
        }
         for(var i3 = 0; i3 < enemy3.length; i3++) {
          if(enemy3[i3].intersectsMesh(bullet, true)) {
            bullet.dispose();
            enemy3[i3].dispose();
            scene.unregisterBeforeRender(shot);
            score = score + 1;
          }
        }

        if(bullet.position.y < -250 || bullet.position.y > 250) {
          bullet.dispose();
          scene.unregisterBeforeRender(shot);
        }
      });

    });

 

i've tried "enemy3[i3].intersectsMesh(bullet, true)" and "bullet.intersectsMesh(enemy3[i3], true)", the results are the same.

if you check the score in the console, you'll see that the numbers doesn't makes sense too, they grow exponentially...

here's the code: http://techslave.com.br/games/dispose/js/core.js

and here's the game: http://techslave.com.br/games/dispose/

 

not in the playground because there's a lot of files

 

can someone help me?

Link to comment
Share on other sites

I'm no expert but I don't think this is a bug. When you dispose a mesh, BJS removes it from various lists and whatnot, but it doesn't destroy it or zero out all its properties. If you then ask BJS to do a collision check with it, I think BJS does the right thing if it does a normal collision check.

(If you were just registering for collision events and leaving BJS to do the checking, I'd expect a disposed mesh to stop issuing events, but since you're specifically asking for a collision check between two meshes, I think BJS is doing the right thing.)

So I think the fix here is that when an enemy gets destroyed, you should remove it from the list of things you do collision checks against.

Link to comment
Share on other sites

I'm doind the collision check with "intersectsmesh", which just check against everything, because i have a lot of things to check collision...

I'm searching for a way of remove the collision check with one mesh only, let's see if i find it out, thank you!

 

but still, is there any way of remove a mesh of the stage leaving no traces behind?

Link to comment
Share on other sites

Ohhh, I see, so each "enemies" object that you're testing against is a whole row of enemies, right? The code sample doesn't include the createEnemy function so it's hard to tell what's going on.

Are the individual enemies child meshes of the row, or how do they get added?

Link to comment
Share on other sites

They are arrays, this:

 

 var enemy1 = createEnemy(scene);
    var enemy2 = createEnemy2(scene);
    var enemy3 = createEnemy3(scene);
   

then enemy.js:

 

function createEnemy(scene){
  this.scene = scene;
  var nomeCons = "enemy1";
  var enemy1 = new Array(11);
  var nome;
  var stPos = startPos[0]-250;
  j = 0;
  for(i = 0; i < 11; i++) {
    if(i==0){
      enemy1[0] = BABYLON.Mesh.CreateBox(enemy1, 10.0, scene);
      enemy1[0].position.y = row[0];
      enemy1[0].position.x = stPos;
      j=i+1;

    }
    else{
      j=i-1;
      nomeInv = nomeCons + i;
      enemy1 = BABYLON.Mesh.CreateBox(nomeInv, 10.0, scene);
      enemy1.position.y = row[0];
      enemy1.position.x = enemy1[j].position.x + 31;
      //enemy.position.x = col;

    }
  }
  return enemy1;
}

 

then i check the collision like this:

for(var i1 = 0; i1 < enemy1.length; i1++) {
          if(enemy1[i1].intersectsMesh(bullet, true)) {
            bullet.setEnabled(false);
            bullet.dispose();
            enemy1[i1].setEnabled(false);
            enemy1[i1].dispose();

            score = score + 1;
            scene.unregisterBeforeRender(shot);

          }

 

 basically i create each enemy in a n array then i use a For to check collision against each of the enemies individually.

Link to comment
Share on other sites

Okay, thanks. I think you should probably just remove the enemy object from the enemy array when you destroy it.

for(var i=0; i<enemy.length; i++) {
    if(enemy[i].intersectsMesh(bullet, true)) {
        enemy[i].dispose()
        enemy.splice(i, 1)
        i--

        // ...
    }
}

The issue here is, intersectsMesh just tells you whether two meshes have positions that overlap. When you dispose something it is "removed" from the scene, in the sense that it no longer renders, etc. But its position and size don't change, so intersectsMesh still works as before, and I think that's probably the correct behavior.

Link to comment
Share on other sites

just from a quick glance that is because you are using the same bullet, use an array of bullets and make sure you are disposing the correct one.  Handle the bullets just like you would and enemy.

What im assuming is happening is you are disposing the bullet and then reusing it but not updating its bounding information or something like that...

Link to comment
Share on other sites


The correct structure would be to just fire a function from inside the mouseclick and have the bullet defined outside of the scope of it and have hit responses. also arrays on a single before register loop to control everything.

I thought there was another closure there.
Im going to bed, this is set up really loopy, ill help tomorrow.

Link to comment
Share on other sites

good morning!

 

I'm at work now but just quickly tried 2 things:

bullet = null

after every other sets when the bullet hits, it crashes the game, console shows something in babylon.js being null

 

removing bullet.dispose()

the bullet will pass through everything, but won't create that piece of nothing that is making me crazy, but one shot can destroy 3 enemies that way, it's not the purpose :(

but i think knowing this helps in some way

Link to comment
Share on other sites

Whoa, just looked at the script lets go over a few things:
1- You are calling multiple nested functions and they all have their own registers and scopes.

2- Your arrays should be constructed on the main loop and referenced in a single before scene register.
3- There is never a time to add this much nested stuff on a click.

Ok lets do this up for you... give me like a hour or something.

Link to comment
Share on other sites

http://www.babylonjs-playground.com/#24D4QT#0

here you go bro, I had to redo it and it does not have any of the hits or controls but fire, but this is the correct structure.

Think Arrays Arrays Array my friend... also when you add in the hit tests, only do it on the bullet, the enemys will not need it and vice versa, and just dispose the targets attached to the collision event and the bullet... make sure you splice your arrays correctly when it happens though.

Also with a set up like this it is way easier to tailor it, you now can do shot speeds (and upgrades), new spawn points for enemy's, different enemy's, different bullet types, faster spawn times (levels) ect.

this would be the right way to structure a retro shooter, and it took like what 20 mins? So the structure is definitely choice.

Link to comment
Share on other sites

no problem, if you need anymore help feel free to tag me in questions... I'm around and am more then willing to help.  I am super impressed with anyone who learns JavaScript just to do a project so don't feel bad this is all a learning process and 16 years ago I was going through what you are now.

Link to comment
Share on other sites

yea i did not script in anything for collisions, I was just showing you the correct structure, I was gonna leave it for you to develop the whole system though, but given the new model you should be able to figure it out.

Just at a listener on the enemy or the bullet when you spawn it for a collision and then output the event to your console and see what your working with.  Should be able to figure it out from there ^_^. I could give you a fully deployed system but whats the fun in that? and then you wont learn.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...