Home > Mobile >  I am trying to re-randomize location of my rectangles when they spawn on top of eachother
I am trying to re-randomize location of my rectangles when they spawn on top of eachother

Time:06-08

I am creating a game where boulders spawn from the sky and the player needs to use the 'a' and 'd' keys to dodge the boulders. Here is my code:

private void moveBoulder(GameTime gameTime)
    {
        for (int i = 0; i <= boulderRec.Length - 1; i  )
        {
            // Update the speed of the boulder
            speed.Y = boulderDirY * (boulderSpeed * (float)(gameTime.ElapsedGameTime.TotalSeconds));

            // Move the boulder back to the top of the screen and randomize its x location when it goes under the screen
            if (boulderPos[i].Y > 1080)
            {
                // Randomize its location above the screen
                boulderPos[i].Y = -200;
                boulderRec[i].X = rng.Next(1, 1700);
            }

            // Subtract 100 points from the players initial score. Move the boulder back to the top and randomize its location
            if (boulderRec[i].Contains(testrec))
            {
                // Subtract 100 points from the players score
                playerScore = playerScore   boulderHit;

                // Randomize its location above the screen
                boulderPos[i].Y = -200;
                boulderRec[i].X = rng.Next(1, 1700);
            }

            // Update the boulders true position
            boulderPos[i].Y = boulderPos[i].Y - speed.Y;
            boulderRec[i].Y = (int)boulderPos[i].Y;

            // Respawn boulder if it spawns on top of another one
            while (boulderRec[i].Contains(boulderRec[i]))
            {
                boulderRec[i].X = rng.Next(1, 1720);
            }
        }

So everything works fine up the the while loop, where I tell the system to respawn the position of the boulder when it is on top of another one. I'm sure I can do this by using a while loop, but I'm not sure how. If anyone is able to help me that would be great. Thanks

CodePudding user response:

while (boulderRec[i].Contains(boulderRec[i])) looks like it will always evaluate to true, getting you stuck in an infinite loop.

You're checking if the boulder contains itself, which it always will. Perhaps you need to compare two different boulders.

Alternatively, you could store the boulder's position coordinates in a variable, and compare against that as you change the boulder's position.

Perhaps this will help:

            // Respawn boulder if it spawns on top of another one
            // capture X value to compare in the loop
            var lastX = boulderRec[i].X;

            // while boulder X is equal to our lastX
            while (boulderRec[i].X == lastX)
            {
                // try setting a new X
                boulderRec[i].X = rng.Next(1, 1720);
            }

CodePudding user response:

In this part while (boulderRec[i].Contains(boulderRec[i])) you only check if your the current boulder is intersecting with itself. (Which should always be true)

What you need to do, is to check if the current boulder boulderRec[i] intersects with any other existing boulder.

Lets recreate your collision check for that.

// Respawn boulder if it spawns on top of another one
int safetyCounter = 0; //To prevent endless loops, in case we are unable to create a non-colliding boulder

bool doesNotIntersect = false;
while(doesNotIntersect == false)
{
  safetyCounter  ;
  doesNotIntersect = true; //Assume we do not hit any other boulder

  //Now check for each **other** boulder if the current one collides with it
  for(int otherBoulderIndex = 0; otherBoulderIndex < boulderRec.Length; i  )
  {
    if(boulderRec[i] != boulderRec[otherBoulderIndex]  //Do not compare position with itself
       && boulderRec[i].Contains(boulderRec[otherBoulderIndex])
    {
      doesNotIntersect = false; //Collision, reposition and re-check
      boulderRec[i].X = rng.Next(1, 1720);
    }
  }
  if(safetyCounter > 5000)
  {
    //Could not create a boulder that does not collide with any other boulder
    
    //Todo: Delete this boulder
    doesNotIntersect = true;
  }
}

Coded in a texteditor, may contain typo-errors.

You could extract this logic into a method and save some time if you stop collision checking once you have found one. (Or even use something like a quadtree), but I assume this should fit your current requirements.

  • Related