GML Visual Spawning at set random positions

I

imp2662

Guest
Hello GameMaker people!

I've got an idea for a 2D memory match game and I'd like to spawn the tiles (objects) into a given level at random set positions in the grid I've got set up on the background, but I can't quite seem to get it to work. Eventually, I'd like to have them all spawn in random grid positions without any repeats, but for now, I can't even seem to get one tile to spawn properly.

I do have the tiniest idea of how to code as I tried to program my idea on Unity before I found my way to GameMaker Studio 2.

Thanks for any help you can give!
 

Yal

šŸ§ *penguin noises*
GMC Elder
This is a programming question instead of a design question, chances are you'd gotten a reply faster if you'd posted it in the Programming sub-forum instead. I'll report it and request it to be moved.

Here's how I'd do it:
  • In the room editor, check what the coordinates of the top left and bottom right cell in the grid are. Let's say the top left corner is 320,480 and the bottom right corner is 640,960.
  • Also take note of what the grid size (aka the size of a single grid cell in pixels) is. Let's assume it's 32x32.
  • Compute (rightX - leftX)/gridSize and (bottomY - topY)/gridSize, that's the size of the grid in cells, gridW and gridH... in our exaple case 10 x 15 cells.
  • Have a control object select random positions in this rectangle: the x value would be leftX + gridSize*irandom(gridW), in our example case 320 + 32*irandom(10). The Y case is analogous. (irandom is the function for a random integer). Check if this position is free of collisions with the tiles (using position_meeting() to check for the tile parent object, unless they're all the same object in which case checking for that is enough)
  • If you'd like the entire grid filled, it's probably better to use a nested for loop to fill every cell with a tile, but select a random type of tile each time instead.
 
I

imp2662

Guest
This is a programming question instead of a design question, chances are you'd gotten a reply faster if you'd posted it in the Programming sub-forum instead. I'll report it and request it to be moved.

Here's how I'd do it:
  • In the room editor, check what the coordinates of the top left and bottom right cell in the grid are. Let's say the top left corner is 320,480 and the bottom right corner is 640,960.
  • Also take note of what the grid size (aka the size of a single grid cell in pixels) is. Let's assume it's 32x32.
  • Compute (rightX - leftX)/gridSize and (bottomY - topY)/gridSize, that's the size of the grid in cells, gridW and gridH... in our exaple case 10 x 15 cells.
  • Have a control object select random positions in this rectangle: the x value would be leftX + gridSize*irandom(gridW), in our example case 320 + 32*irandom(10). The Y case is analogous. (irandom is the function for a random integer). Check if this position is free of collisions with the tiles (using position_meeting() to check for the tile parent object, unless they're all the same object in which case checking for that is enough)
  • If you'd like the entire grid filled, it's probably better to use a nested for loop to fill every cell with a tile, but select a random type of tile each time instead.
Thanks for the reply Yal! I apologize about posting in the wrong spot. I'll give your solution a try.
 
I

imp2662

Guest
This is a programming question instead of a design question, chances are you'd gotten a reply faster if you'd posted it in the Programming sub-forum instead. I'll report it and request it to be moved.

Here's how I'd do it:
  • In the room editor, check what the coordinates of the top left and bottom right cell in the grid are. Let's say the top left corner is 320,480 and the bottom right corner is 640,960.
  • Also take note of what the grid size (aka the size of a single grid cell in pixels) is. Let's assume it's 32x32.
  • Compute (rightX - leftX)/gridSize and (bottomY - topY)/gridSize, that's the size of the grid in cells, gridW and gridH... in our exaple case 10 x 15 cells.
  • Have a control object select random positions in this rectangle: the x value would be leftX + gridSize*irandom(gridW), in our example case 320 + 32*irandom(10). The Y case is analogous. (irandom is the function for a random integer). Check if this position is free of collisions with the tiles (using position_meeting() to check for the tile parent object, unless they're all the same object in which case checking for that is enough)
  • If you'd like the entire grid filled, it's probably better to use a nested for loop to fill every cell with a tile, but select a random type of tile each time instead.

So, I'm having a little trouble with the nested for loop suggestion. I definitely want every cell to be filled, but I'm not sure how to implement the for loop.

It seems like it might be easier for me to spawn them individually at random in set locations, but then I have the problem of spawning repeats, which I don't want.

I've thought about adding the object to a list once it's spawned and then having the program check against the list before spawning the next tile, but I'm not sure how to implement that either.
 

Electros

Member
On a mobile puzzle game I created, I had to "deathmark" grid position based counters which were a) not already marked, and b) not when all counters were marked. I suppose a similar method could be used for yours to fill up a grid of tiles, placing in random free positions until full.

In pseudo terms, you would want:

-the tile spawner to be run x number of terms (either by calculating the height x width of the desired grid and repeating the spawn code based on that, or running it in a nested for loop, based on the height and width of the grid)
-the individual tile spawner itself should be something along the lines of the below (Note: The do loop is very powerful, but should only be run when you know there is a free position (either because you have calculated how many times to repeat it initially, or checking the grid is not full before running it) to avoid hanging the game.)

Code:
do  {
    //Generate values to check a random position on the grid
    var checkX = irandom_range(0, rowCount);
    var checkY = irandom_range(0, columnCount);
    
    //Check whether the position in the grid is free using the random values, and whatever method you use to mark grid position
    if(positionFree(using checkX & checkY) = true)
        {
        //Place the tile
        creation code etc...
        
        //Mark the grid position as taken
        grid update at checkX checkY to not free...
        
        //Exit the do loop
        tilePlaced = true;
        
        }
    else
        {
        //Position not free
        tilePlaced = false;
        }       

    }
    
until
    {
    tilePlaced = true;
    }

Simulator Screen Shot 16 Feb 2017, 15.32.33.png
 
Top