• Platformer Collision Troubles (SFML)
    4 replies, posted
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.