SFML community forums
Help => Graphics => Topic started by: AngelHoof 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:
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 while (CheckBorderColl)
but that froze the program as soon as it executed... Umm, am I using the wrong functions for checking this, any ideas?
-
I would do that by checking each movement to the edge. I would create a function called locationAllowed like below:
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:
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!
-
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?
//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;
}
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);
-
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:
// 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);
-
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:
//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:
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!