Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Simulating Window-Border Collision!  (Read 10136 times)

0 Members and 1 Guest are viewing this topic.

AngelHoof

  • Newbie
  • *
  • Posts: 27
    • View Profile
Simulating Window-Border Collision!
« on: August 05, 2011, 09:02:20 pm »
Hey!

Got this tiny 'lil problem now... I'm trying to keep my moving sprite from going outside the window borders, currently using:

Code: [Select]

float KeyMove = 0.10f;

sf::FloatRect BorderColl(0, 0, 800, 600);
sf::Vector2f BlobPosition = Blob.GetPosition();
bool CheckBorderColl = BorderColl.Contains(BlobPosition);
if (CheckBorderColl == 1);
{
if (ShiftKeyDown)
KeyMove = 0.3f;

if (LeftKeyDown)
Blob.Move(-KeyMove, 0);
if (RightKeyDown)
Blob.Move(KeyMove, 0);
if (UpKeyDown)
Blob.Move(0, -KeyMove);
if (DownKeyDown)
Blob.Move(0, KeyMove);
if (GKeyDown)
Blob.Rotate(KeyMove);
if (HKeyDown)
Blob.Rotate(-KeyMove);
}

Win.Clear();
Win.Draw(Blob);
Win.Display();

}


I originally had it as
Code: [Select]
while (CheckBorderColl)

but that froze the program as soon as it executed... Umm, am I using the wrong functions for checking this, any ideas?

howderek

  • Newbie
  • *
  • Posts: 2
    • View Profile
I would do it differently
« Reply #1 on: August 05, 2011, 10:22:23 pm »
I would do that by checking each movement to the edge. I would create a function called locationAllowed like below:
Code: [Select]

bool locationAllowed(sf::Shape &shape) {
sf::Vector2f temp = shape.GetPosition();
int x = temp.x + 1;
int y = temp.y + 1;
if (x > 800 || x < 0) {
   return false;
}
if (y > 600 || y < 0) {
   return false;
}
return true;
}

That code is tested and functional. Then I would rewrite your if statements:
Code: [Select]

         if (LeftKeyDown  && locationAllowed(Blob))
            Blob.Move(-KeyMove, 0);
         if (RightKeyDown && locationAllowed(Blob))
            Blob.Move(KeyMove, 0);
         if (UpKeyDown  && locationAllowed(Blob))
            Blob.Move(0, -KeyMove);
         if (DownKeyDown  && locationAllowed(Blob))
            Blob.Move(0, KeyMove);
         if (GKeyDown  && locationAllowed(Blob))
            Blob.Rotate(KeyMove);
         if (HKeyDown  && locationAllowed(Blob))
            Blob.Rotate(-KeyMove);


I hope this helps you!

AngelHoof

  • Newbie
  • *
  • Posts: 27
    • View Profile
Simulating Window-Border Collision!
« Reply #2 on: August 05, 2011, 11:17:53 pm »
Edited:

Hmm, couldn't convert from sf::sprite to sf::shape, so I replaced the function parameter with sf::sprite instead, and removed the ampersand sign.

My sprite effectively stops at the border... But then becomes unresponsive  :(

Did i change too much?

Code: [Select]

//the function
bool locationAllowed(sf::Sprite sprite) {
sf::Vector2f temp = sprite.GetPosition();
int x = temp.x + 1;
int y = temp.y + 1;
if (x > 800 || x < 0) {
   return false;
}
if (y > 600 || y < 0) {
   return false;
}
return true;
}



Code: [Select]

if (LeftKeyDown  && locationAllowed(Blob))
            Blob.Move(-KeyMove, 0);
         if (RightKeyDown && locationAllowed(Blob))
            Blob.Move(KeyMove, 0);
         if (UpKeyDown  && locationAllowed(Blob))
            Blob.Move(0, -KeyMove);
         if (DownKeyDown  && locationAllowed(Blob))
            Blob.Move(0, KeyMove);
         if (GKeyDown  && locationAllowed(Blob))
            Blob.Rotate(KeyMove);
         if (HKeyDown  && locationAllowed(Blob))
            Blob.Rotate(-KeyMove);

unranked86

  • Newbie
  • *
  • Posts: 37
    • View Profile
Simulating Window-Border Collision!
« Reply #3 on: August 07, 2011, 01:34:18 am »
Think about this.
If x is 0 for example, the function returns false, and you can never change x again. Or x is 800, the function returns again false, for all eternity :)

I would go with something like this:

Code: [Select]

// not real code
void moveBlob (sf::Sprite& sprite, int direction_x)
{
   if (sprite.position_x >= 800 || sprite.position_x <= 0)
       sprite.position_x = sprite.position_x;
   else
       sprite.position += 1 * direction_x;
}

// usage, is something like this
sf::Sprite blob;
if (left_key_ispressed)
   moveBlob(blob, -1);
if (right_key_ispressed)
   moveBlob(blob, 1);

howderek

  • Newbie
  • *
  • Posts: 2
    • View Profile
Sorry, it was my fault.
« Reply #4 on: August 11, 2011, 02:47:45 pm »
You didn't change too much, my function was bad. I have made a revised function that I have tesed in my actual game, so I know for a fact it works. It actually handles moving in the function. Here is the fuction:
Code: [Select]

//smartMove(sf::Sprite&,int,int,int,int);
//usage: smartMove(sprite you are controlling, move x, move y, window width, window height);
//example: smartMove(Player,1,0,400,250)
//tip: subtract the sprite height and sprite width from the window height and window width

bool smartMove(sf::Drawable &obj,int moveX,int moveY,int windowWidth,int windowHeight) {
sf::Vector2f pos = obj.GetPosition();
sf::Vector2f scl = obj.GetScale();
//position from sprites base point
int posX = pos.x;
int posY = pos.y;

if (moveX > 0 || moveY > 0) {
if (posX + moveX >= windowWidth|| posY + moveY >= windowHeight) {
//Good luck moving there, YOU REBEL!!
return false;
}
}
if (moveX < 0 || moveY < 0) {
if (posX - moveX <= 0 || posY - moveY <= 0) {
//You want to move your sprite there? NO!!!
return false;
}
}
if (moveX == 0 && moveY == 0)
return false;
//if you want to handle moving in the function
obj.Move(moveX,moveY);

//go ahead, Mr.Sprite
return true;
}


You shouldn't have to change any code because it uses sf::Drawable which applies to all moveable objects. I would change your code to:
Code: [Select]

         if (LeftKeyDown)
            smartMove(blob,-KeyMove,800,600);
         if (RightKeyDown)
            smartMove(KeyMove, 0,800,600);  
         if (UpKeyDown)
            smartMove(0, -KeyMove,800,600);
         if (DownKeyDown)
            smartMove((0, KeyMove,800,600);  
         if (GKeyDown)
            Blob.Rotate(KeyMove);
         if (HKeyDown)
            Blob.Rotate(-KeyMove);
      }

All you have to do is change 800 to 800 minus your sprites/shapes width and 600 to 600 minus your sprites/shapes height. Enjoy!