I'm pleased with the capabilities of SFML with my test Hangman program, now I wish to make something more complicated. I decided on a basic platformer, since I thought the code for gravity/collision would be good practice for me, although I am having some troubles.
If I have a wall of "tiles" (not tile-engine tiles, but heh...) and my box pushes against them, it will slightly overlap them, so when I jump, the box (player) is teleported to the top of these boxes and then "jumps". Here is the relevant code.
[cpp] //Collision for player moving left/left side of player
int HitTestL( player& playerid )
{
for(int i=0; i<tCount; i++)
{
//playerid is a defined class "player", containing the SFML sprite "pSprite"
if(playerid.pSprite.GetPosition().y >= tileArr[i].tSprite.GetPosition().y && playerid.pSprite.GetPosition().y <= tileArr[i].tSprite.GetPosition().y + tileArr[i].tSprite.GetSize().y)
{
if(playerid.pSprite.GetPosition().x <= tileArr[i].tSprite.GetPosition().x + tileArr[i].tSprite.GetSize().x && playerid.pSprite.GetPosition().x >= tileArr[i].tSprite.GetPosition().x)
{
playerid.pSprite.SetPosition(tileArr[i].tSprite.GetPosition().x + playerid.pSprite.GetSize().x, playerid.pSprite.GetPosition().y);
return 0;
}
}
}
return 1;
}
//Collision for player moving right/right side of player
int HitTestR( player& playerid )
{
for(int i=0; i<tCount; i++)
{
//tileArr is an array of the created class "tile", containing a sprite named "tSprite"
if(playerid.pSprite.GetPosition().y >= tileArr[i].tSprite.GetPosition().y && playerid.pSprite.GetPosition().y <= tileArr[i].tSprite.GetPosition().y + tileArr[i].tSprite.GetSize().y)
{
if(playerid.pSprite.GetPosition().x + playerid.pSprite.GetSize().x >= tileArr[i].tSprite.GetPosition().x && playerid.pSprite.GetPosition().x <= tileArr[i].tSprite.GetPosition().x)
{
playerid.pSprite.SetPosition(tileArr[i].tSprite.GetPosition().x - playerid.pSprite.GetSize().x - 0.01f, playerid.pSprite.GetPosition().y);
return 0;
}
}
}
return 1;
}
//This code is placed in the main function, correctly
if (wMain.GetInput().IsKeyDown(sf::Key::Space) && (thePlayer.grounded))
{
HitTestL(thePlayer);
HitTestR(thePlayer);
thePlayer.yvelocity -= 20.f;
thePlayer.grounded = false;
}
if (wMain.GetInput().IsKeyDown(sf::Key::Left) && Move.GetElapsedTime() > 0.01f)
{
if(HitTestL(thePlayer))
thePlayer.pSprite.Move(-5.f, 0.f);
Move.Reset();
}
if (wMain.GetInput().IsKeyDown(sf::Key::Right) && Move.GetElapsedTime() > 0.01f)
{
if(HitTestR(thePlayer))
{
thePlayer.pSprite.Move(5.f, 0.f);
}
Move.Reset();
}
[/cpp]
Changing the players position in the HitTestR or HitTestL functions to be moved "away" from the block causes a "jumpy" motion and a player can hold down Right or Left and press jump to exploit the same bug as mentioned earlier.
Any suggestions?
You need to check for collision [i]before[/i] moving.
look at this yet?
[url]http://www.sfml-dev.org/wiki/en/sources/simple_collision_detection[/url]
sf::IntRect has an intersect function that can be used for collision. It basically does what you have in those huge if statements.
Unless you need per pixel collision.
[QUOTE=Bang Train;16935429]look at this yet?
[url]http://www.sfml-dev.org/wiki/en/sources/simple_collision_detection[/url][/QUOTE]
Thank you, I will look into this, hopefully replacing my inefficient functions.
Sorry, you need to Log In to post a reply to this thread.