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) 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; }
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 { 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 ); }
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 ) { cout << "left"; } if( archer->GetBounds().top + archer->GetBounds().height >= top && archer->GetBounds().top <= top ) { cout << "top"; archer->SetVelocity( archer->GetVelocity().x, archer->GetVelocity().y ); archer->SetGravity( false ); archer->SetPosition( archer->GetPosition().x, top - archer->GetSize().y ); } if( archer->GetBounds().left <= right && archer->GetBounds().left + archer->GetBounds().width >= right ) { cout << "right"; } if( archer->GetBounds().top <= bottom && archer->GetBounds().top + archer->GetBounds().height >= bottom ) { cout << "bottom"; archer->SetVelocity( archer->GetVelocity().x, archer->GetVelocity().y ); archer->SetPosition( archer->GetPosition().x, bottom ); } } } } } }
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. |
|
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? 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 ); } else if( CollisionOnBottom( rect ) ) { SetVelocity( GetVelocity().x, 0 ); SetPosition( GetPosition().x, rect.top + rect.height ); } else if( CollisionOnLeft( rect ) ) { SetAllowToGoRight( false ); } else if( CollisionOnRight( rect ) ) { SetAllowToGoLeft( false ); } } }
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 ;) |
|
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 |
|
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 |
|
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 |
|
colorgreen19 Temat założony przez niniejszego użytkownika |
» 2014-04-08 18:05:59 zmieniłem te petle glowana gry na //same instrukcje// accumulator += elapsed.asSeconds(); acc += elapsed;
Game_Input();
if( accumulator >= 0.02f ) { 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. |
|
hincu |
» 2014-04-08 18:15:15 siak czyli jak? japitole, nie mozesz tego zobrazowac jakos slowami? nie jestem mentalista i jasnowidzami nie jestesmy |
|
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
|
|
« 1 » 2 |