This site requires JavaScript, please enable it in your browser!
Greenfoot back
ye-roon
ye-roon wrote ...

2013/10/23

Can isTouching(class) be used in a constructor for world?

ye-roon ye-roon

2013/10/23

#
Hello, For a project i'm making i'm currently trying to let the enemies spawn at random locations. But letting them spawn via a contructor in the world class i can only make them not spawn exactly on top of each other. But not completly apart from one another. Wich would be fixed if i could just use the isTouching(i think). Since they need to spawn in a certain area of the world i am using x and y values for that. However there are other objects, like walls and they cannot spawn on them aswell. I tried making a list with Actor.class instead of Jock.class but that didnt work either, as the constructor could still place them slighty off center from the walls. This has resulted in 3 sets of code within one method where i think i can make it 1 set of code. (losing the o and u integers). The code is below. Any help is appreciated.
    /**
     * Spawns 6 jocks at random locations within the 3 hallways of the school
     */
    private void createJocks()
    {
        int i = 0;
        int o = 0;
        int u = 0;
      
        while (i < 2)
        {
            Jock jock = new Jock();
            int x = 245 + Greenfoot.getRandomNumber(455);
            int y = 310 + Greenfoot.getRandomNumber(50);
            boolean spaceTaken = false;
            
            
          List<Jock> jocks = (List<Jock>)getObjects(Jock.class);
        
          for (Jock evilJocks : jocks)
          {
            if (evilJocks.getX()== x && evilJocks.getY()== y) 
            spaceTaken = true;
          }

          if (!spaceTaken)
            addObject(jock, x  ,y );
            i++;
        }
        
                while (o < 2)
        {
            Jock jock = new Jock();
            int x = 245 + Greenfoot.getRandomNumber(455);
            int y = 410 + Greenfoot.getRandomNumber(50);
            boolean spaceTaken = false;
            
            
          List<Jock> jocks = (List<Jock>)getObjects(Jock.class);
        
          for (Jock evilJocks : jocks)
          {
            if (evilJocks.getX()== x && evilJocks.getY()== y) 
            spaceTaken = true;
          }

          if (!spaceTaken)
            addObject(jock, x  ,y );
            o++;
        }
        
                while (u < 2)
        {
            Jock jock = new Jock();
            int x = 245 + Greenfoot.getRandomNumber(455);
            int y = 510 + Greenfoot.getRandomNumber(50);
            boolean spaceTaken = false;
            
            
          List<Jock> jocks = (List<Jock>)getObjects(Jock.class);
        
          for (Jock evilJocks : jocks)
          {
            if (evilJocks.getX()== x && evilJocks.getY()== y) 
            spaceTaken = true;
          }

          if (!spaceTaken)
            addObject(jock, x  ,y );
            u++;
        } 
    }
danpost danpost

2013/10/23

#
There is no problem with using 'isTouching' in the constructor of the world. The super call in the world class is what actually creates the world; everything after it is building upon that newly created world. Once you add actors into the world in the constructor (or anywhere else), then you can use collision checking methods on those actors.
public void createJocks()
{
    for (int i=0; i<6; i++)
    {
        Actor jock = new Jock();
        addObject(jock, 0, 0);
        while (jock.getX() == 0 || jock.isTouching(Jock.class))
        {
            int x = 245 + Greenfoot.getRandomNumber(455);
            int y = 310 + 100 * (j / 2) + Greenfoot.getRandomNumber(50);
            jock.setLocation(x, y);
        }
    }
}
ye-roon ye-roon

2013/10/23

#
Thanks for the reply, but i'm getting the same compile error as when i tried using it before. The error is: isTouching(java.lang.Class) has protected access in greenfoot.Actor This error is a bit more clear then the one i previously got, but it sums up my question in a short sentence lol :)
danpost danpost

2013/10/23

#
That is right. I forgot it was 'protected'. In fact all collision detection is. Alright, try this:
// in the world class
public void createJocks()
{
    for (int i=0; i<6; i++)
    {
        int x = 245+Greenfoot.getRandomNumber(455);
        int y = 310 + 100*(i / 2) + Greenfoot.getRandomNumber(50);
        addObject(new Jock(), x, y);
    }
}

// in the Jock class, add this method
public void addedToWorld(World w)
{
    int yBase = (getY()-310)/100;
    while (isTouching(Jock.class)
    {
        int x = 245 + Greenfoot.getRandomNumber(455);
        int y = 10+100*yBase + Greenfoot.getRandomNumber(50);
        setLocation(x, y);
    }
}
This method will be called automatically when a Jock object is placed into a world (you do not code a call to this method yourself).
ye-roon ye-roon

2013/10/24

#
Thanks! That works. But can you explain why it works? Especially the addedToWorld method? Because i do not call on it anywhere in the code.
danpost danpost

2013/10/24

#
ye-roon wrote...
Thanks! That works. But can you explain why it works? Especially the addedToWorld method? Because i do not call on it anywhere in the code.
Well, you do not call the 'act' method either. They are called by the system at specific times. The 'act' method is called on the active world and all actors in that world while the scenario is running. The 'addedToWorld' method is called by the system one time immediately upon an actor being entered into a world. These are both methods in the Actor class. While the 'act' method is also included in the World class, it has two other methods that are called by the system: the 'started' and 'stopped' methods. These are called by the system when the 'Run' and 'Pause' buttons are clicked. The 'started' method is also called when 'Greenfoot.start()' is executed (which performs like the 'Run' button is being pressed.
You need to login to post a reply.