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

2012/1/15

Unlimited random placing of objects

Oneshot Oneshot

2012/1/15

#
//
Duta Duta

2012/1/15

#
Yes, of course! - just see my scenario http://www.greenfoot.org/scenarios/3927 for an example of randomly spawning enemies :) (however mine has a limit of how many enemies can be in the world at any one time - i have it so that if the number of enemies in the world is less than the limit, it spawns a zombie in a random location) You just do something like
if(Greenfoot.getRandomNumber(50) < 1) addObject(new Zombie(), x, y)
obviously if you want them spawning in different (random) places, you have to do another getRandomNumber() call for the x, and y co-ordinates - here's an example:
if(Greenfoot.getRandomNumber(50) < 1)
    addObject(new Zombie(), Greenfoot.getRandomNumber(getWorld.getWidth()), Greenfoot.getRandomNumber(getWorld.getHeight()))
By the way, if you're not used to using Greenfoot.getRandomNumber(int limit) you can see here. Basically if you do Greenfoot.getRandomNumber(50), what you're getting is a random number between 0 and 49 inclusive - so my statement
if(Greenfoot.getRandomNumber(50) < 1)
means if(a 1 in 50 chance). Also if you want the rate of spawning to increase with time, then you'll want to have 2 fields, like the following:
private int rate = 50, timer = 0;
(which means you'd change the statement to
if(Greenfoot.getRandomNumber(rate) < 1) addObject(new Zombie(), x, y)
and then in the act method of the class in which you have the 2 fields (and, presumably, the statement - so I'm going to assume you're putting this in your world class) you add the following:
public void act()
{
    //Whatever else is in your act method


    if(Greenfoot.getRandomNumber(rate) < 1) addObject(new Zombie(), x, y) //1 in (rate) chance of spawning a zombie

    timer++; //increase the timer by 1
    if(timer%100 == 0 && rate > 2) //when timer is 100, 200, 300, 400 etc, and the rate is more than 10
        rate--; //decrease the rate variable by 1
}
The reason I added an extra && rate > 2 check is because otherwise eventually the rate would go negative, and you can't do Greenfoot.getRandomNumber(negative number). If I'm not making any sense, give me a heads up about what you're unclear about and I'll go over it again, but better - hopefully this should suffice though. Oh and a final note, you'll want to fiddle with the 100 in timer%100 and the 50 in int rate = 50; to get the spawn rate you're looking for :) Oh and another thing - if you get any errors tell me what they are - I've written this code straight into the text box so I haven't got greenfoot to error-check it
Oneshot Oneshot

2012/1/15

#
//
danpost danpost

2012/1/15

#
The 'addObject(Actor, int, int)' method is a world class method, and also the x and y need to be integers, so line 49 should be
       if(Greenfoot.getRandomNumber(rate) < 1) ((ZombieWorld) getWorld()).addObject(new Zombie(), (int) Math.round(x), (int) Math.round(y));
Of course, ZombieWorld should be replaced with the name of your world (unless that IS the name of your world).
davmac davmac

2012/1/15

#
Even just:
    if(Greenfoot.getRandomNumber(rate) < 1) getWorld().addObject(new Zombie(), (int) Math.round(x), (int) Math.round(y));
... should be fine. No need for the cast here.
danpost danpost

2012/1/15

#
I did not think it was needed, as the method is an inherited one (just trying to be a little more on the cautious side, as I never had taken any classes that were anywhere near Java-related).
Oneshot Oneshot

2012/1/15

#
//
danpost danpost

2012/1/15

#
If you wanted them to spawn from any border
int spawnX = 0;
int spawnY = 0;
if (Greenfoot.getRandomNumber(2) == 0) // determines which axis to use
{ // spawns along top or bottom border
    spawnY = Greenfoot.getRandomNumber(2) * (getWorld().getHeight() - 1); // determines which side (top or bottom)
    spawnX = Greenfoot.getRandomNumber(getWorld().getWidth()); // determines where on that side to spawn Zombie at
}
else
{ // spawns along left or right border

    spawnX = Greenfoot.getRandomNumber(2) * (getWorld().getWidth() - 1);
    spawnY = Greenfoot.getRandomNumber(getWorld().getHeight());
}
getWorld().addObject(new Zombie(), spawnX, spawnY);
Oneshot Oneshot

2012/1/15

#
//
davmac davmac

2012/1/15

#
Oneshot, you need to think a little bit about what the code is doing rather than just blindly copy-pasting it. The code that danpost gave you adds in a zombie at a random location. If you just paste that into the "act" method, then you'll add another zombie every time that act() is called - that is a pretty high rate. In the code before that, you had an "if" statement to control the rate. So, you need to combine the two parts!
    if ( /* rate control check */ ) {
        // add zombie here
    }
(fill in the proper code).
Oneshot Oneshot

2012/1/15

#
//
davmac davmac

2012/1/15

#
Yes, the way you have it written each zombie will spawn more zombies. If that's not how you want it, you should spawn the zombies from a different class - probably the world. Also, it's not clear what the purpose of lines 27-29 are. Perhaps you are trying to have the bullets "kick" the zombie back, however, you never initialise 'x' and 'y' to anything so they do not represent the zombie's current position and instead they are usually at 0,0 - this is probably why zombies appear to "spawn" in the top left. Perhaps you need to call getX() and getY() in order to get the current zombie position.
Oneshot Oneshot

2012/1/15

#
Thanks for your answer! I had to put in in the Player class. World doesn´t know the method "getWorld" ...
davmac davmac

2012/1/15

#
You don't need to call getWorld() from the world class, because you are in the world already. So: getWorld().addObject(...) becomes just addObejct(...)
Oneshot Oneshot

2012/1/15

#
//
You need to login to post a reply.