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

2021/3/28

How to spawn Actors outside of the boundary

hernry2812 hernry2812

2021/3/28

#
I would like to know how you can spawn actors off of the visible screen. In my case, the actors (not my main actor) are spawning only in the scrolling window, but not outside of the boundary. Here is danposts idea from another discussion(2016):
// instead of
super(1000, 600, 1);
// you would use
super(1000, 600, 1, false);
I am using danposts Scrolling Super World with 5 parameters, so my super call looks like this:
super(800, 800, 1, 1920, 1440);
Because of the 5 parameters, I cant add false at the end. How can I spawn my actors outside of the boundary?
danpost danpost

2021/3/29

#
hernry2812 wrote...
Because of the 5 parameters, I cant add false at the end. How can I spawn my actors outside of the boundary?
No worry. All of the SWorld constructors take care of that for you. You can put actors outside of the boundary, no problem. Of course they would need to be within your scrolling area (0, 0) - (1920, 1440) to appear in your scrolling world.
hernry2812 hernry2812

2021/3/29

#
This is my RaceWorld class:
public class RaceWorld extends SWorld 
{
    
    static int speed = 5;
    
    public RaceWorld()
    {    

        super(800, 800, 1, 1920, 1440); // scroll world constructor call; last parameter is scroll width
        
        addObject(new StartLine(), 150,-77, true);
        
        setMainActor(new Car(), 1, 1);
        mainActor.setLocation(280, -80);
        
        GreenfootImage bg = new GreenfootImage("World.png");
        setScrollingBackground(bg);
        
    }
    
    public void act()
    {
        erschaffeMaulwurf();
        
        super.act();
        
    }
    
    public void erschaffeMaulwurf()
    {
        while (getObjects(Mole.class).size() < 2) //Solange weniger als 2 Maulwürfe da sind
        {
            int xPos = Greenfoot.getRandomNumber(1920) ;  //Zufällige Koordinate
            int yPos = Greenfoot.getRandomNumber(1440);  
            Color color = (this).getColorAt(xPos, yPos);    
            if (color.getRed() == 77 && color.getGreen() == 77 && color.getBlue() == 77)
            {
                Mole mole = new Mole();    
                addObject(mole,xPos,yPos, true);
            }
        }
    }
Trying to start this im getting the following error code:
java.lang.IndexOutOfBoundsException: The y-coordinate is: 1375. It must be smaller than: 800
	at greenfoot.World.ensureWithinYBounds(World.java:904)
	at greenfoot.World.getColorAt(World.java:261)
	at RaceWorld.erschaffeMaulwurf(RaceWorld.java:48)
	at RaceWorld.act(RaceWorld.java:36)
	at greenfoot.core.Simulation.actWorld(Simulation.java:573)
	at greenfoot.core.Simulation.runOneLoop(Simulation.java:506)
	at greenfoot.core.Simulation.runContent(Simulation.java:193)
	at greenfoot.core.Simulation.run(Simulation.java:183)
Using 800 and 800 to calculate the random number worked perfectly fine, but using 1920 and 1440 doesn't work for me. But when I was adding some of my actors to my world (static ones) I realized that coordinates out of the window are negative in some cases. Hope you can help me. Thanks in advance :)
danpost danpost

2021/3/29

#
The getColorAt method uses the world background image, which is 800 by 800. You want a color from the scrolling background image. Add the following method to the SWorld class:
/**
 * Returns the background image of the full scrolling area
 *
 * @return the scrolling background image
 */
public GreenfootImage getScrollingBackground()
{
    return background;
}
Then change line 35 to:
Color color = getScrollingBackground().getColorAt(xPos, yPos);
In line 39, you will need to adjust xPos and yPos by scrolled amounts to place the actor at the correct location.
hernry2812 hernry2812

2021/3/29

#
Okay, just added your method to my SWorld class. This is what my method looks like now:
public void erschaffeMaulwurf()
    {
        while (getObjects(Mole.class).size() < 50) //Solange weniger als 2 Maulwürfe da sind
        {
            int xPos = Greenfoot.getRandomNumber(1920);  //Zufällige Koordinate
            int yPos = Greenfoot.getRandomNumber(1440);
            int scrolledX = getScrolledX();
            int scrolledY = getScrolledY();
            Color color = getScrollingBackground().getColorAt(xPos, yPos);    
            if (color.getRed() == 77 && color.getGreen() == 77 && color.getBlue() == 77)
            {
                Mole mole = new Mole();
                addObject(mole,xPos + scrolledX,yPos + scrolledY, true);
            }
        }
    }
Now my actors aren't spawning on the track anymore. Do I have to put something else for "background" in your SWorld class method maybe?
danpost danpost

2021/3/29

#
Your adjustment is wrong:
danpost wrote...
you will need to adjust xPos and yPos by scrolled amounts to place the actor at the correct location.
hernry2812 hernry2812

2021/3/29

#
Sorry for not getting it, but I tested a few things and I still don't realize how to correctly adjust xPos and yPos to let them spawn at the correct location. As you can obviously see, im very new to Greenfoot, so again thanks a lot for your help @danpost!
danpost danpost

2021/3/29

#
hernry2812 wrote...
Sorry for not getting it, but I tested a few things and I still don't realize how to correctly adjust xPos and yPos to let them spawn at the correct location. As you can obviously see, im very new to Greenfoot, so again thanks a lot for your help @danpost!
Try subtracting instead of adding.
hernry2812 hernry2812

2021/3/30

#
This is the method now (with subtracting):
public void erschaffeMaulwurf()
    {
        while (getObjects(Mole.class).size() < 50) 
        {
            int xPos = Greenfoot.getRandomNumber(1920);  //Zufällige Koordinate
            int yPos = Greenfoot.getRandomNumber(1440);
            int scrolledX = getScrolledX();
            int scrolledY = getScrolledY();
            Color color = getScrollingBackground().getColorAt(xPos, yPos);    
            if (color.getRed() == 77 && color.getGreen() == 77 && color.getBlue() == 77)
            {
                Mole mole = new Mole();
                addObject(mole,xPos - scrolledX, yPos - scrolledY, true);
            }
        }
    }
This still doesn't work. My moles are still spawning on grass and not on the track anymore. Are you sure that this has nothing to do with the background? The getScrollingBackground method in SWorld still looks like this:
public GreenfootImage getScrollingBackground()
    {
        return background;
    }
But still no Idea why the moles aren't spawning on the track.. But atleast they spawn outside of the scrolling window. For testing I set Mole class size to 50, most of them are spawning in the middle to bottom right corner. To set my Actors in the right place (for example the start line) I sometimes had to use negative coordinates. Hope you can help me
danpost danpost

2021/3/30

#
Maybe it has something to do with the order of steps taken in setting up your world. Try this order: (1) set background image; (2) add non-main actors; (3) set main actor.
hernry2812 hernry2812

2021/3/30

#
Can do that because my method to create the moles needs to be in act() :/
public class RaceWorld extends SWorld 
{
    
    static int speed = 5;
    
    public RaceWorld()
    {    

        super(800, 800, 1, 1920, 1440); // scroll world constructor call; last parameter is scroll width
        setBackground(new GreenfootImage("World.png"));
        
        addObject(new StartLine(), 150,-77, true);
        addObject(new Border(), 450, 320, true);
        
        setMainActor(new Car(), 1, 1);
        mainActor.setLocation(280, -80);
        
    
        GreenfootImage bg = new GreenfootImage("World.png");
        setScrollingBackground(bg);
        
        setPaintOrder(Car.class, Mole.class);
        
    }
    
    public void act()
    {
        erschaffeMaulwurf();
        
        super.act();
        
    }
    
    public void erschaffeMaulwurf()
    {
        while (getObjects(Mole.class).size() < 50) //Solange weniger als 2 Maulwürfe da sind
        {
            int xPos = Greenfoot.getRandomNumber(1920);  //Zufällige Koordinate
            int yPos = Greenfoot.getRandomNumber(1440);
            int scrolledX = getScrolledX();
            int scrolledY = getScrolledY();
            Color color = getScrollingBackground().getColorAt(xPos, yPos);    
            if (color.getRed() == 77 && color.getGreen() == 77 && color.getBlue() == 77)
            {
                Mole mole = new Mole();
                addObject(mole,xPos - scrolledX, yPos - scrolledY, true);
            }
        }
    }
}
Do you maybe know another way to create actors outside of the scrolling window randomly but only on a certain color (in this case the track, r= 77, g = 77, b= 77) ?
danpost danpost

2021/3/31

#
Looks like what you have should work. I can only suggest you upload it with source so it can be thoroughly looked at and tested.
hernry2812 hernry2812

2021/3/31

#
Okay, I uploaded a scenario of my game. Don't want to wait a day until this gets posted, so just go to my profile (I only have one scenario) oder look at the latest ones. On the web page it doesn't work, but if you download it and start it in Greenfoot, it will. Thanks in advance
danpost danpost

2021/3/31

#
hernry2812 wrote...
I uploaded a scenario of my game. Don't want to wait a day until this gets posted, so just go to my profile (I only have one scenario) oder look at the latest ones. On the web page it doesn't work, but if you download it and start it in Greenfoot, it will.
Okay, it has been a while since I have dealt with the SWorld class. I forgot that zero scroll was center of scrolling area.. Use:
addObject(mole, xPos-scrolledX-560, yPos-scrolledY-360);
(where 560 is (1920-800)/2 and 360 is (1440-800)/2) -- top-left corner of zero scroll
hernry2812 hernry2812

2021/3/31

#
Thank you very much, :)
You need to login to post a reply.