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

2018/12/20

Placing Multiple Objects randomly

GreenfootGreenhorn GreenfootGreenhorn

2018/12/20

#
I've been trying to work out how to add a random number of the same object in a world class, so that each time refresh is hit a different number of the object is placed randomly around the world. The random number has to be within set parameters, for example, it should place 1-10 objects in different places around the world whenever the world is loaded up or the refresh button is hit. I also need to set the areas of the world it is allowed to be placed in, however I'm unsure how to do this because it's not as simple as just between x1 and x100 and y1 and y100 for example, as there is also an area in the centre of the world in which they cannot be placed, as well as the edge. I know this is pretty vague, but I'm trying to avoid plagiarism, so really I'm looking for a solution that will work when I implement it myself adding the values myself. Sorry if this is confusing, and thanks in advance for trying to help
davmac davmac

2018/12/20

#
it's not as simple as just between x1 and x100 and y1 and y100 for example
So are you saying that you know how to do it for a simple "x and y between 2 values scenario"? In that case, the simplest solution is probably to do that, but check for the co-ordinates being inside the disallowed center region and keep choosing new co-ordinates until they are not inside that region. You could have a loop while the co-ordinates are invalid which picks some new co-ordinates.
davmac wrote...
it's not as simple as just between x1 and x100 and y1 and y100 for example
So are you saying that you know how to do it for a simple "x and y between 2 values scenario"? In that case, the simplest solution is probably to do that, but check for the co-ordinates being inside the disallowed center region and keep choosing new co-ordinates until they are not inside that region. You could have a loop while the co-ordinates are invalid which picks some new co-ordinates.
Yes, I've got it working in that sense, as it stays in the x and y parameters, the problem is, there is an area in the middle of those coordinates that it also cannot be placed it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void createWalls()
    {
        Wall2[] walls = new Wall2[Greenfoot.getRandomNumber(5) +2];
        for(int i=0; i<walls.length; i++)
        {
            walls[i] = new Wall2();
            int x1 = 135;
            int x2 = 690;
            int y1 = 120;
            int y2 = 725;
            int x = x1 + Greenfoot.getRandomNumber(1+(x2-x1));
            int y = y1 + Greenfoot.getRandomNumber(1+(y2-y1));
            addObject(walls[i], x, y);
 
        }
    }
That's my code for creating them in the worl class atm. How would the loop work? and where would I put it Thanks and Happy New Year :)
danpost danpost

2019/1/2

#
What are the rectangular coordinates of the inner area where you do not want them to spawn?
danpost wrote...
What are the rectangular coordinates of the inner area where you do not want them to spawn?
x215 to x690 and y230 to y615
danpost danpost

2019/1/2

#
GreenfootGreenhorn wrote...
danpost wrote...
What are the rectangular coordinates of the inner area where you do not want them to spawn?
x215 to x690 and y230 to y615
So, no spawning along center-right area (both rectangle have a max x of 690?).
danpost wrote...
GreenfootGreenhorn wrote...
danpost wrote...
What are the rectangular coordinates of the inner area where you do not want them to spawn?
x215 to x690 and y230 to y615
So, no spawning along center-right area (both rectangle have a max x of 690?).
Yeah because the way the track is set up, the right hand side of the track is too narrow for objects to be spawning in there :)
danpost danpost

2019/1/2

#
Will get back to you. Need to go now.
danpost danpost

2019/1/2

#
So you can break the spawning area into 3 rectangles -- 2 of size 555x110 (acrosss top and bottom) and 1 of size 120x385 (the central left area). Pick a random number of 2*555*110+1*120*385 choices. If random value is less than 2*550*110, then if less than 555*110, the value is for top rectangle; if not, the value is for bottom rectangle. The remainder after dividing by 555*110 will correspond to a specific point in the rectangle. In the rectangle, value%555 is the x and value/555 is the y. If the original value was not less than 2*555*110, then the value, after subtracting 2*555*110, refers to a point in the left center rectangle. In this rectangle, value%120 is the x and value%120 is the y. Any and all spawning points will have an equal chance of being picked using this method.
danpost wrote...
So you can break the spawning area into 3 rectangles -- 2 of size 555x110 (acrosss top and bottom) and 1 of size 120x385 (the central left area). Pick a random number of 2*550*110+1*120*385 choices. If random value is less than 2*550*110, then if less than 550*110, the value is for top rectangle; if not, the value is for bottom rectangle. The remainder after dividing by 550*110 will correspond to a specific point in the rectangle. In the rectangle, value%550 is the x and value/550 is the y. If the original value was not less than 2*550*110, then the value, after subtracting 2*550*110, refers to a point in the left center rectangle. In this rectangle, value%120 is the x and value%120 is the y. Any and all spawning points will have an equal chance of being picked using this method.
It's amazing that you've worked that out, but I haven't any idea how to implement that lol
I've been trying to just check that there are no objects in the netherzone (zone I can't place objects into xD) and then if there is an object in there, just set the location elsewhere, but I can't for the life of me work it out, I'm spending hours on this and getting nowhere :(
danpost danpost

2019/1/2

#
GreenfootGreenhorn wrote...
It's amazing that you've worked that out, but I haven't any idea how to implement that lol
Follow what I wrote with the code below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int rand = Greenfoot.getRandomNumber(2*555*110+1*80*385);
int x = 0, y = 0; // initialize world coordinate variables
if (rand < 2*555*110) // top or bottom rect
{
    if (rand < 555*110) // top rect
    {
        x = 135; // x of top-left corner of rect
        y = 120; // y of top-left corner of rect
        int dx = rand%555; // x in rect
        int dy = rand/555; // y in rect
        x = x+dx; // final x
        y = y+dy; // final y
    }
    else // bottom rect
    {
        rand = rand-555*110; // not top rect
        x = 135; // x of top-left corner of rect
        y = 615; // y of top-left corner of rect
        int dx = rand%555; // x in rect
        int dy = rand/555; // y in rect
        x = x+dx; // final x
        y = y+dy; // final y
    }
}
else // left side rect
{
    rand = rand-2*555*110; // not top or bottom rect
    x = 135; // x of top-left corner of rect
    y = 230; // y of top-left corner of rect
    int dx = rand%80; // x in rect
    int dy = rand/80; // y in rect
    x = x+dx; // final x
    y = y+dy; // final y
}
addObject(walls[i], x, y);
Taking advantage of a few things, the code above can be simplified to this:
1
2
3
4
int rand = Greenfoot.getRandomNumber(2*555*110+80*385);
int rectNum = rand/(555*110); // 0 = top; 1 = bottom; and 2 = side
rand = rand-rectNum*555*110; // point in specific rect
addObject(walls[i], 135+rand%(rectNum < 2 ? 555 : 80), (new int[] { 120, 615, 230 })[rectNum]+rand/(rectNum < 2 ? 555 : 80));
I think I did that right.
You need to login to post a reply.