This site requires JavaScript, please enable it in your browser!
Greenfoot back
Steven.Z.
Steven.Z. wrote ...

2015/1/8

spawned actors should not touch each other

Steven.Z. Steven.Z.

2015/1/8

#
my objects spawn with a certain probability on the right side of the screen and move to the left side. the problem is that they touch each other very often, i.e.. the images intersect and i don't want that so i added a code, that a object should check the space before it and when its empty it can be spawned; unfortunately it doesn't work my code looks like this:
if (Greenfoot.getRandomNumber(200) <1)
  {
  if (getObjectsAt(450, Greenfoot.getRandomNumber(400), Enemy.class).isEmpty())
     {
       addObject(new Enemy(), 600, Greenfoot.getRandomNumber(400));
     }
   }
any suggestions how else it could work? or maybe a different solution?
danpost danpost

2015/1/8

#
The problem with the code given above is that the World object method 'getObjectsAt' only returns a list of actors that are currently at the coordinates given -- that is, actors whose 'getX' and 'getY' methods return those exact coordinates. Another problem with what was given is you would not be placing the enemy at the location initially checked (the value returned from 'getRandomNumber(400)' on line 3 will be different from the value return from the same code on line 5 pretty much all the time). One way to avoid spawning on top of another object is by making use of the Actor class method 'addedToWorld(World)'. You can have the new enemy check for intersectors and remove itself if any are found. The world can check to see if the actor stayed in the world or not and continually attempt to add it at different locations until it stays.
if (Greenfoot.getRandomNumber(200)<1)
{
    Actor enemy = new Enemy();
    while (enemy.getWorld() == null)
        addObject(enemy, 600, Greenfoot.getRandomNumber(400));
}
You can use any number of collision checking methods from the Actor class in the 'addedToWorld' method. The 'isTouching' method would be fine if you do not mind that they are occasionally quite close, but not touching; the 'getObjectsInRange' method would be good for giving some extra space.
Steven.Z. Steven.Z.

2015/1/8

#
ok, thanks so i used the getobjectsinrange command but i still dent work; solution is probably quiet simple my code looks like this when i wanted that some kind of actors should only spawn as long the player is not game over and it perfectly works
if (Greenfoot.getRandomNumber(200) <1)
        {
           if ( ! getObjects(GameOver.class).isEmpty())
           {
                addObject(new MonsterEnemies(), 600, 299);
               }
           }
     
so i used now to use your suggested solution like this:
if (Greenfoot.getRandomNumber(200) <1)
{
               if(! getObjectsInRange(100, Enemies.class).isEmpty())
               {
                addObject(new Enemies(), 600, 299);
               }
}
       
and that doesn't work; i just don't want them to touch each other an none of them are taller than 150 pixels so a radius of 100 pixels should actually work
danpost danpost

2015/1/9

#
Line 3 in the first snippet says to add enemies when the list of game over objects in the world is not empty. I think you want the opposite of that:
if ( getObjects(GameOver.class).isEmpty() )
would add enemies only if no game over object was in the world. You have the same basic problem with the second snippet. At any rate, the code snippet I supplied above should suffice in the world class. In other words, these snippets you just posted are not needed at all; just use what I gave above, as is. What you need at this point is an 'addedToWorld' method in the Enemy class:
protected void addedToWorld(World world)
{
    if ( ! getObjectsInRange(107, Enemies.class).isEmpty() )
    {
        world.removeObject(this);
    }
}
One hundred times one-half the square root of two is slightly more than one hundred six (106.06).
Steven.Z. Steven.Z.

2015/1/9

#
thanks so much for that, it works! yeah, you are right about the other thing; i copied the "!" from an older version, without it it worked the way i wanted to; so now i used this code but still have a tiny problem: the enemies don't touch each other but sometimes, actually quite seldom they touch something from the background class, so i wanted to do the that for this class as well in the enemies.class
protected void addedToWorld(World world)    
{
      if ( ! getObjectsInRange(107, Enemies.class, Background.class).isEmpty())
      {
        world.removeObject(this);
      }
}
or i just copy this if condition in the addedToWorld command, but still not working
danpost danpost

2015/1/9

#
You can only use one specified class in the 'getObjectsInRange' method. If you want to specify any and all classes, you can use 'null' instead of a class. If you only want the two classes as you suggest above, you need to check each one individually:
if ( ! getObjectsInRange(107, Enemies.class).isEmpty() || ! getObjectsInRange(107, Background.class).isEmpty() )
Seems a bit strange to have an Actor subclass named Background; but, that is what you have?
Steven.Z. Steven.Z.

2015/1/9

#
yep, now it works thanks i got a subclass called background in this there are some actors how are just supposed to be in the background but i don't want them to intersect with the rest thanks again!
You need to login to post a reply.