Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML 2.1] Kolizja działa, jednak nie można poruszać obiektu

Ostatnio zmodyfikowano 2014-04-10 12:18
Autor Wiadomość
colorgreen19
Temat założony przez niniejszego użytkownika
[SFML 2.1] Kolizja działa, jednak nie można poruszać obiektu
» 2014-04-03 21:19:33
Pewnie będzie jakiś głupi bład ale moj mózg juz wyczerpany i nie pozostaje mi nic innego jak zwrócić sie do was.
Sytuacja prosta: laduje mape kafelkowa wyswietlam ja za pomaca vertecsu, pozniej operacjami wertuje każdy kafelek != od tła, jeżeli obszar gracza zawiera obszar kafelka, wykrywam z której strony jest kolizja.
Archer.cpp   (: public Player)
C/C++
void Archer::SetVelocity( int velocityX, int velocityY )
{
    velocity.x = velocityX;
    velocity.y = velocityY;
}

void Archer::SetPosition( int posX, int posY )
{
    m_positionX = posX;
    m_positionY = posY;
   
    shape.setPosition( m_positionX, m_positionY );
}

void Archer::Move( sf::Time elapsed )
{
    shape.move( velocity.x * elapsed.asSeconds(), velocity.y * elapsed.asSeconds() );
   
    m_positionX = shape.getPosition().x;
    m_positionY = shape.getPosition().y;
}
////////////DRAW////////////////////////////
void Archer::Draw( sf::RenderWindow * okno )
{
    okno->draw( shape );
   
    for( int i = 0; i < Arrows.size(); i++ )
    {
        okno->draw( Arrows[ i ].shape );
    }
}

void Archer::Update( sf::Time elapsed )
{
    if( m_gravity )
    {
        velocity.y += 4000 * elapsed.asSeconds();
    }
   
    Move( elapsed );
}
Wybrane funkcje z Game.cpp
C/C++
//w petli glownej
{
    Game_Input();
   
    Game_Logic();
   
    Game_Collision();
   
    Game_Update( elapsed );
   
    Game_Draw( okno );
}
void Game::Game_Input()
{
    if( Keyboard::isKeyPressed( Keyboard::Left ) )
    {
        archer->SetVelocity( - 250, archer->GetVelocity().y );
    }
    else if( Keyboard::isKeyPressed( Keyboard::Right ) )
    {
        archer->SetVelocity( 250, archer->GetVelocity().y );
    }
    else if( Keyboard::isKeyPressed( Keyboard::Down ) )
    {
        archer->SetVelocity( archer->GetVelocity().x, 250 );
    }
    else if( Keyboard::isKeyPressed( Keyboard::Up ) )
    {
        archer->SetVelocity( archer->GetVelocity().x, - 250 );
    }
    else archer->SetVelocity( 0, archer->GetVelocity().y );
   
}
///////////LOGIC/////////////////////////////////////////////////////
///////////COLISSION/////////////////////////////////////////////////////
void Game::Game_Collision()
{
    archer->SetGravity( true );
    for( int i = 0; i < mapa.collisionMap.size(); i++ )
    {
        for( int j = 0; j < mapa.collisionMap[ i ].size(); j++ )
        {
            if( mapa.collisionMap[ i ][ j ] != 0 )
            {
                int bottom = i * 32 + 32, top = i * 32, left = j * 32, right = j * 32 + 32;
               
                Rect < int > rect( left, top, 32, 32 );
               
                if( archer->GetBounds().intersects( static_cast < FloatRect >( rect ) ) )
                {
                    cout << ". ";
                    if( archer->GetBounds().left + archer->GetBounds().width >= left && archer->GetBounds().left <= left ) /// On left
                    {
                        cout << "left";
                    }
                    if( archer->GetBounds().top + archer->GetBounds().height >= top && archer->GetBounds().top <= top ) /// On top
                    {
                        cout << "top";
                        archer->SetVelocity( archer->GetVelocity().x, archer->GetVelocity().y );
                        archer->SetGravity( false );
                        archer->SetPosition( archer->GetPosition().x, top - archer->GetSize().y ); //Chyba nawala to archer->GetPosition().x
                    }
                    if( archer->GetBounds().left <= right && archer->GetBounds().left + archer->GetBounds().width >= right ) /// On right
                    {
                        cout << "right";
                    }
                    if( archer->GetBounds().top <= bottom && archer->GetBounds().top + archer->GetBounds().height >= bottom ) /// On bottom
                    {
                        cout << "bottom";
                        archer->SetVelocity( archer->GetVelocity().x, archer->GetVelocity().y );
                        archer->SetPosition( archer->GetPosition().x, bottom );
                    }
                }
            }
        }
    }
}
//archer->Update(elapsed)   gdzies tam niżej

Co sie dzieje? (kolizja na prawo i lewo jeszcze niedokonczona)
Kiedy gracz upada na kafelek, odyba sie to normalnie. Moze tez podskoczyc z kafelka. Jednak kiedy chce ruszyc sie na boki moge tylko w lewo, w dodatku z jaką zawrotną prędkością, a prawo w ogole nie mozna.
P-107668
colorgreen19
Temat założony przez niniejszego użytkownika
» 2014-04-07 17:33:38
Nie zakładam nowego posta bo temat jest mniej wiecej ten sam. //Problem u gory nadal niezbyt rozwiązany, jednak go obszedłem
Napisałem sobie jakiś tam system kolizji, rozpoznający z której strony kolizja następuje i tu sie zaczynają "schody". Trudnosci nie ma, no bo gdzie, ale jednak przy testach program szwankuje. Otóż mam pytanie co sie powinno robic przy kolizji. Zerować prędkość czy cofać postać (zmieniac pozycje) do najblizszej mozliwej pozycji czy może oba naraz?
C/C++
bool Player::Collision( sf::Rect < int > rect )
{
    SetGravity( true );
    if( GetBounds().intersects( static_cast < FloatRect >( rect ) ) )
    {
        if( CollisionOnTop( rect ) )
        {
            SetGravity( false );
            SetVelocity( GetVelocity().x, 0 );
            SetAllowOnJump( true );
            //SetPosition( GetPosition().x, rect.top - GetSize().y );
        }
        else if( CollisionOnBottom( rect ) )
        {
            SetVelocity( GetVelocity().x, 0 );
            SetPosition( GetPosition().x, rect.top + rect.height );
        }
        else if( CollisionOnLeft( rect ) )
        {
            SetAllowToGoRight( false );
            //SetPosition( rect.left - GetSize().x, GetPosition().y );
        }
        else if( CollisionOnRight( rect ) )
        {
            SetAllowToGoLeft( false );
            //SetPosition( rect.left + rect.width, GetPosition().y );
        }
    }
}
Widzimy tu dużo komentarzy z funkcjami bo mam ten dylemat wlasnie. Na moim komputerze (z i7) kod działa bez zarzutów ale juz na starszym lapku (z Pentiumem IV) tak jakby kod nie nadążał (ale to dziwne) i postać "przebija" sie (problem tylko przy styku z podłożem, jak wiadomo najczęściej zachodzi (CollisionOnTop) ) przez kafelek mapy i utyka w środku mapki. Więc wracając do pytania jak obsługiwać kolizje ( Zerować prędkość czy cofać postać (zmieniac pozycje) do najblizszej mozliwej pozycji czy może oba naraz?) prosze o jakąś składną odpowiedz ;)
P-107854
hincu
» 2014-04-07 20:34:41
ogranicz liczbe fps do 60 lub zrob petle stalokrokowa, ten twoj elapsed time ile wynosi? co do 2 pytania 1 problem 1 watek, ale odpowiem, wszystko jest zalezne od tego jaka chcesz miec mechanike gry i czy uwzgledniasz fizyke, jesli postac ma sie poruszac razem z kolidowanym obiektem to wiadomo ze predkosc moze sie zmniejac stopniowo do -, jesli obiekt jest statyczny to po prostu cofaj do mozliwie jak najblizszej odleglosci z obiektem kolidujacym

edit, skoro w metodza z kolizja zwraca bool to zwracaj true lub false zaleznie czy kolizja wystepuje lub nie, reszta jak wyzej zaleznie od wartosci zwracanej metody
P-107871
colorgreen19
Temat założony przez niniejszego użytkownika
» 2014-04-07 20:58:38
hmm ustawiając limit klatek na 60 fps cały ten napisany system sie porypał i zaczął byc jak na lapku. elapsed time wynosi u mnie 0.0004. Fizyka ma tylko powodowac opadanie graczy, stworów, żadne tam zaawansowane karuzele, siły odśrodkowe czy cos
P-107872
hincu
» 2014-04-08 13:15:24
wywal ten twoj timer, ustaw 60fps, wylacz synchronizacje pionowa i zrob stala wartosc poruszania, jak dla mnie to niepotrzebnie z timerem kombinujesz, jak serio chcesz juz uzywac timera to poczytaj czym jest petla stalokrokowa, to ze ustawiles 60fps nie znaczy ze czas, ktory pobierasz z obiektu bedzie nadal taki sam, wszystko zaleznie od procesora
http://xion.org.pl/productions/texts/coding/game-programming/real-time-loop/


edit

to tez powinno rozwiazac problem
http://cpp0x.pl/forum/temat/?id=14825&p=2
P-107897
colorgreen19
Temat założony przez niniejszego użytkownika
» 2014-04-08 18:05:59
zmieniłem te petle glowana gry na  //same instrukcje//
C/C++
accumulator += elapsed.asSeconds();
acc += elapsed;

Game_Input();

if( accumulator >= 0.02f ) //na 66.6 fps
{
    Game_Logic();
   
    Game_Collision();
   
    Game_Update( elapsed );
   
    accumulator -= 0.02f;
    acc -= seconds( 0.02f );
}

Game_Draw( okno );

elapsed = clock.restart();
tylko rodzi mi sie pytane co wstawic do Game_Update(), czy wstawic ten elapsed (~0.004) czy juz nieco przyszykowane acc ( acc == accumulator tylko ze to sf::Time)
bo jak wstawiam elapsed to gra tak jakby przeskakuje, przycina, a jak wstawiam ten acc to... narazie identyfikuje zjawisko ale wyglada jakby dzialo to jak wczesniej, czyli na laptopie tak a na stacjonarnym siak.
P-107912
hincu
» 2014-04-08 18:15:15
siak czyli jak? japitole, nie mozesz tego zobrazowac jakos slowami? nie jestem mentalista i jasnowidzami nie jestesmy
P-107914
colorgreen19
Temat założony przez niniejszego użytkownika
» 2014-04-08 18:23:17
Ok. Dając czas jako Game_Update(elapsed) postac (przy niezmienionych tamtych ustawieniach predkosci) porusza sie bardzo wolno (to jednak jednak jest logiczne) i dodatkowo widac ze jest wolniej aktualizowana bo nie jest to ruch wolny płynny tylko wolny "skakany" (przycina sie tak z lekka) jendak to tez jest w miare wytłumaczalne tylko nie wiem czy tak powinno byc. Zaleta ze na laptopie działa to tak samo

Dając jako Game_Update(acc) (inaczej ten akcelerator trzymający czas do wykonania warunku stałokrokowego) postac porusza sie tak jak wtedy jednak dzieje się tak jak wtedy na laptopie czyli czasami wpada pod kafelki w mapce (to jest bez ustawiania jej pozycji, tylko sterowania sama prędkością, bo z ustawianiem pozycji to jeszcze większe bugi), zaś na wolniejszym laptopie tez jest jeszcze inaczej
P-107916
« 1 » 2
  Strona 1 z 2 Następna strona