Random image placement? [Array]

I am trying to achieve random image placement with just for loops. The code I was using is:


for (int tx = 0; tx <= roomWidth; tx += 80) {
	for (int ty = 0; ty <= roomHeight; ty += 80) {
		if (tx < roomWidth && ty < roomHeight) {
			g.drawImage(tree, (int) Math.round(Math.random() * tx), (int) Math.round(Math.random() * ty), null);
		}
	}
}

That obviously has a few complications,
a) when I use more then 1 random value create an instance of Random and use that instead of Math.random()
b) might result in drawing trees on top of each other
c) it will be different on every redraw (bad)

I’ve thought of doing it a different way using arrays but I’m not sure how to approach it. I think I’ll use a random object and place a different position on each element (maybe), but I don’t know. So if anyone can explain this to me it would be much appreciated.

Shazer2

Just create an array and generate some random X and Y values into it. If you want them to be different, check them against each earlier X and Y.

Create an object that has the image and location, only set it when you initialize.

Also your first tree will currently always be at 0, 0.

I personally wouldnt draw image to random locations, but make an nD-array and have the numbers be randomly generated into those. Then draw the images from that. Just have it populate the array once, so that way it wont keep regenerating and recalculating new random variables every loop/redraw. You can still manually choose to randomize it later by recalling the randomizer/repopulate/regenerate function

I personally feel that this gives you more control.

Since you said trees, I’d assume that each image is a tree, and this is a forest?

Do you want it 100% random location? Do you want minimum distance from each other or grouping/clustering (or avoidance of clustering)

you may use a grid placement to avoid two object to overlap and a stack of pos and maybe a PRNG to avoid different generation, not very optimised but should work well until you use very small object on very big area.

something like :

Vector freePos=new Vector();
int nbPosX = screenWidth / objectWidth;
int nbPosY = screenHeight / objectHeight;
 
//fill free pos
for(int cx=0;cx<nbPosX :cx++)
 for(int cy=0;cy<nbPosY :cy++)
  freePos.addElement(new Point(cx,cy));

for(int n=0;n<nbObject;n++)
{
 int pos=(int)(pseudoRandom()*freePos.size());
 Point gridPos=(Point)freePos.elementAt(n);
 object[n].pos=gridPos;
 freePos.removeElementAt(n); 
}

It sounds good. sample code maybe?

I’d do something like this

//Screen size 800x600
    public int treeCount = 30;
    public int[] treeLoc = new int[2*treeCount];
    Random r = new Random();
    
    public void RandomizeTreeLocs(){ //needs to be called once, during init
        for(int i=0; i<(2*treeCount);i+=2){
            treeLoc[i] = r.nextInt(800); // X location
            treeLoc[i+1] = r.nextInt(600); // Y Location
        }
    }
    
    public void drawTrees(){
        //blah blah portion
        for(int i=0; i<(2*treeCount);i+=2){
        g.drawImage( treePicture, treeLoc[i], treeLoc[i+1],null);
        }
    }
    
    //Main Loop
    if(keyPressed == R){
        RandomizeTreeLocs();
    }

another method, although in my opinion, less efficient.

    //Screen size 800x600
    public int tree = 30;
    public int[][] treeLoc = new int[800][600];
    Random r = new Random();
    //treePicture array contains an array of different image types for different trees/rocks/grass
    
    public void RandomizeTreeLocs(){ //needs to be called once, during init
        for(int i=0; i<tree;i++){
            treeLoc[r.nextInt(800)][r.nextInt(600)] = 1; 
            // use different numbers for different "types of trees"
        }
    }
    
    public void drawTrees(){
        //blah blah portion
        for(int i=0; i<800;i++){
            for(int j=0; j<600;j++){
                if( treeLoc[i][j] > 0){
                    //g.drawImage( treePicture[ treeLoc[i][j] ], i, j,null);
                }
            }
        }
    }
    
    
    //Main Loop
    /*if(keyPressed == R){
        RandomizeTreeLocs();
    }

There are better ways to write the above, these are just some quickly thrown together ideas.
Depending on the type of game and what all you need/want from it.

I think making the tree an entity, with x/y coordinates inside of it, perhaps with other variables and functions.

Then just maintaining a EntityList of all the trees, You could also with entities, have them check for distance to other trees and remove themselves if they are too close, or perhaps change the type of tree,(i.e. if 1 tree has 5 trees close to it, make itself a baby tiny tree) if the tree has nothing close to it, make it a bigger/older tree?