SFML community forums

Help => General => Topic started by: Ventus on January 13, 2016, 04:06:17 pm

Title: Determining if player is on air/ground
Post by: Ventus on January 13, 2016, 04:06:17 pm
I've implemented some gravity and collision in my 2d side-scroller/platformer game, but i needed to know if the player is currently grounded or mid-air. I really can't think of anything, especially because I can't define a fixed minimum height (because of the tilemap i've implemented can have some weird combinations and i would like to avoid imposing limits to the level design).

Anyone has an interesting insight on this?

Maybe I'm just looking at it from the wrong perspective...
Title: Re: Determining if player is on air/ground
Post by: SpeCter on January 13, 2016, 04:26:15 pm
You could cast a ray(or one for each bottom corner) downwards with little steps. If the ray reached a certain length before a solid block has been hit you are mid-air.
Or just check if the bottom corners collide with anything.
Or just check if your sprite collides with anything(making sure your sprite penetrates the other sprite from the right direction)

There are many ways, but without knowing any specifics about tilesizes and playersizes it is hard to guess which one would be a good fit for your game.

Title: Re: Determining if player is on air/ground
Post by: Ventus on January 13, 2016, 05:46:09 pm
Do you think this works?

        bool thereWasABottomCollision = false;
        for (auto &i : m_wmap->m_fixturerects)
        {
                if (rect.getGlobalBounds().intersects(i))
                {
                        float x = 0.f, y = 0.f;
                        if (rect.getGlobalBounds().left < i.left && i.left < rect.getGlobalBounds().left + rect.getGlobalBounds().width &&
                                rect.getGlobalBounds().left + rect.getGlobalBounds().width < i.left + i.width)
                        {
                                x += rect.getGlobalBounds().left + rect.getGlobalBounds().width - i.left;
                        }
                        else if (i.left < rect.getGlobalBounds().left && rect.getGlobalBounds().left < i.left + i.width &&
                                i.left + i.width < rect.getGlobalBounds().left + rect.getGlobalBounds().width)
                        {
                                x -= i.left + i.width - rect.getGlobalBounds().left;
                        }
                        else if (rect.getGlobalBounds().top < i.top && i.top < rect.getGlobalBounds().top + rect.getGlobalBounds().height &&
                                rect.getGlobalBounds().top + rect.getGlobalBounds().height < i.top + i.height)
                        {
                                y -= rect.getGlobalBounds().top + rect.getGlobalBounds().height - i.top - 2.f;
                                thereWasABottomCollision = true;
                        }

                        else if (i.top < rect.getGlobalBounds().top && rect.getGlobalBounds().top < i.top + i.height &&
                                i.top + i.height < rect.getGlobalBounds().top + rect.getGlobalBounds().height)
                        {
                                y += i.top + i.height - rect.getGlobalBounds().top;
                        }
                        move(x, y);
                }
        }

        if (thereWasABottomCollision)
                m_onair = false;
        else
                m_onair = true;

m_fixturerects is an std::vector<sf::FloatRect>, containing the tiles.
Title: Re: Determining if player is on air/ground
Post by: Mr_Blame on January 13, 2016, 07:53:06 pm
You can check if player doesn't move down then he is grounded  ;D
Title: Re: Determining if player is on air/ground
Post by: Ventus on January 13, 2016, 08:30:42 pm
You can check if player doesn't move down then he is grounded  ;D

The problem is: I need to have this information in order to determine if gravity should be applied. Otherwise, the player will start going though the ground and coming back.