Crax Temat założony przez niniejszego użytkownika |
Kolizje sfml 2.X " Nie rozumiem jak to działa " » 2015-03-30 17:30:08 Jestem na etapie tworzenie własnej gry ( typowej tibi ). Mam problem z zrozumieniem jak działają kolizje, posiadam strzępki informacji zaczerpnięte z różnych stron ale brakuje mi dokładnego wytłumaczenia jak to działa. Prosił bym o link, lub wytłumaczenie ( jak najprościej ). Głownie chodzi mi o kolizje gracza z obiektem nie ruchomym i ruchomym. Mapa kafelkowa, kafelka 32 x 32, wielkość okna 20 x 20. |
|
Brunon3 |
» 2015-03-30 17:34:23 Hm... Mam kod kolizji ze swojego silnika (nie mapa kafelkowa, ale to podobne). Możesz sobie przeanalizować. :) void App::Player_Collision( int x, int y, int w, int h ) { if( world.isScreenScroll ) { if(( player.y <=(( y ) + h ) ) &&( player.y + player.h >=( y ) ) ) { if(( player.x <=( x + w ) ) &&( player.x >= x + w / 2 ) ) { player.camera.x += 1 - world.speed; } } if(( player.y <=(( y ) + h ) ) &&( player.y + player.h >=( y ) ) ) { if(( player.x + player.w ) >= x &&( player.x + player.w <= x + w / 2 ) ) { player.camera.x -= 1 - world.speed; } } if(( player.x <=( x + w ) &&( player.x + player.w >= x ) ) ) { if((( player.y + player.h ) >= y ) &&( player.y + player.h <= y + h / 2 ) ) { player.y -= 1 - world.speed; } } if(( player.x <=( x + w ) ) &&( player.x + player.w >= x ) ) { if( player.y <=( y + h ) && player.y >= y + h / 2 ) { player.y += 1 - world.speed; } } } else { if(( player.y <=(( y ) + h ) ) &&( player.y + player.h >=( y ) ) ) { if(( player.x <=( x + w ) ) &&( player.x >= x + w / 2 ) ) { player.x += 1 - world.speed; } } if(( player.y <=(( y ) + h ) ) &&( player.y + player.h >=( y ) ) ) { if(( player.x + player.w ) >= x &&( player.x + player.w <= x + w / 2 ) ) { player.x -= 1 - world.speed; } } if(( player.x <=( x + w ) &&( player.x + player.w >= x ) ) ) { if((( player.y + player.h ) >= y ) &&( player.y + player.h <= y + h / 2 ) ) { player.y -= 1 - world.speed; } } if(( player.x <=( x + w ) ) &&( player.x + player.w >= x ) ) { if( player.y <=( y + h ) && player.y >= y + h / 2 ) { player.y += 1 - world.speed; } } } } Legenda: App - moja autorska biblioteka; rozszerzenie Allegro 4; Allegro Plus Plus (Allegro++), world.isScreenScroll - czy jest aktywne przewijanie ekranu, world.speed - anty-prędkość gry, odejmuję od niej wszystko co się porusza, player.camera.x - pozycja kamery gracza; dla przewijania ekranu; odejmuję od niej wszystkie inne pozycje gdy jest aktywne przewijanie ekranu. No więc sprawdzam pozycję, czy gracz z której strony nie zachodzi na obiekt; jeżeli tak: cofam go odpowiednio. ;) -- Oj, to SFML. :D Ale tam chyba jest podobnie (chyba, jeżeli nie to przepraszam). -BD. |
|
Quirinnos |
» 2015-03-30 18:43:33 Najprościej jak można. Jeśli któraś ze stron gracza, przecina się z którąś ze stron obiektu, to jest kolizja xD. Kiedyś pisałem na blogu o prostym systemie kolizji w SFML, może Ci się przyda. SFML - Kolizje |
|
Crax Temat założony przez niniejszego użytkownika |
» 2015-03-30 19:54:14 #include <SFML/Graphics.hpp>
using namespace std; using namespace sf;
int main() { RenderWindow oknoAplikacji( VideoMode( 256, 256, 32 ), "xxx" ); Texture water, water_grass, gras, spider, players; Sprite spr0, spr1, spr2R, spr2D, spr2L, spr2U, spr3, player; water.loadFromFile( "C:\\Users\\Maciek\\Documents\\Visual Studio 2010\\Projects\\sfml\\Debug\\graph\\water.png" ); spr0.setTexture( water ); gras.loadFromFile( "C:\\Users\\Maciek\\Documents\\Visual Studio 2010\\Projects\\sfml\\Debug\\graph\\gras.png" ); spr1.setTexture( gras ); water_grass.loadFromFile( "C:\\Users\\Maciek\\Documents\\Visual Studio 2010\\Projects\\sfml\\Debug\\graph\\water_grassU.png" ); spr2U.setTexture( water_grass ); spr2R.setTexture( water_grass ); spr2R.setOrigin( 32, 0 ); spr2R.setRotation( 270 ); spr2D.setTexture( water_grass ); spr2D.setOrigin( 32, 32 ); spr2D.setRotation( 180 ); spr2L.setTexture( water_grass ); spr2L.setOrigin( 0, 32 ); spr2L.setRotation( 90 ); spider.loadFromFile( "C:\\Users\\Maciek\\Documents\\Visual Studio 2010\\Projects\\sfml\\Debug\\graph\\xxx.png" ); spr3.setTexture( spider ); spr3.setOrigin( 16, 16 ); players.loadFromFile( "C:\\Users\\Maciek\\Documents\\Visual Studio 2010\\Projects\\sfml\\Debug\\graph\\players.png" ); player.setTexture( players ); player.setOrigin( 16, 16 ); player.setPosition( 80, 80 ); int mapa[ 8 ][ 8 ] = { { 0, 1, 1, 1, 1, 1, 1, 0 }, { 2, 5, 5, 5, 5, 5, 5, 4 }, { 2, 5, 5, 5, 5, 5, 5, 4 }, { 2, 5, 5, 5, 5, 5, 5, 4 }, { 2, 5, 5, 5, 5, 5, 5, 4 }, { 2, 5, 5, 5, 5, 5, 5, 4 }, { 2, 5, 5, 5, 5, 5, 5, 4 }, { 0, 3, 3, 3, 3, 3, 3, 0 } }; while( oknoAplikacji.isOpen() ) { Event zdarzenie; while( oknoAplikacji.pollEvent( zdarzenie ) ) { if( zdarzenie.type == Event::Closed ) { oknoAplikacji.close(); } if( zdarzenie.type == Event::KeyPressed && zdarzenie.key.code == Keyboard::Escape ) { oknoAplikacji.close(); } if( zdarzenie.type == Event::KeyPressed && zdarzenie.key.code == Keyboard::Up ) { player.move( 0, - 32 ); player.setRotation( 360 ); } if( zdarzenie.type == Event::KeyPressed && zdarzenie.key.code == Keyboard::Down ) { player.move( 0, 32 ); player.setRotation( 180 ); } if( zdarzenie.type == Event::KeyPressed && zdarzenie.key.code == Keyboard::Left ) { player.move( - 32, 0 ); player.setRotation( 270 ); } if( zdarzenie.type == Event::KeyPressed && zdarzenie.key.code == Keyboard::Right ) { player.move( 32, 0 ); player.setRotation( 90 ); } } oknoAplikacji.clear( Color::Black ); for( int i = 0; i < 8; i++ ) { for( int j = 0; j < 8; j++ ) { if( mapa[ j ][ i ] == 0 ) { spr0.setPosition( i * 32, j * 32 ); oknoAplikacji.draw( spr0 ); } if( mapa[ j ][ i ] == 1 ) { spr2U.setPosition( i * 32, j * 32 ); oknoAplikacji.draw( spr2U ); } if( mapa[ j ][ i ] == 2 ) { spr2R.setPosition( i * 32, j * 32 ); oknoAplikacji.draw( spr2R ); } if( mapa[ j ][ i ] == 3 ) { spr2D.setPosition( i * 32, j * 32 ); oknoAplikacji.draw( spr2D ); } if( mapa[ j ][ i ] == 4 ) { spr2L.setPosition( i * 32, j * 32 ); oknoAplikacji.draw( spr2L ); } if( mapa[ j ][ i ] == 5 ) { spr1.setPosition( i * 32, j * 32 ); oknoAplikacji.draw( spr1 ); } } } oknoAplikacji.draw( spr3 ); spr3.setPosition( 48, 48 ); oknoAplikacji.draw( player ); oknoAplikacji.display(); } return 0; }
Możecie zaproponować jakieś rozwiązanie? |
|
RazzorFlame |
» 2015-03-31 11:47:12 Jeżeli zamierzasz ograniczyć poruszanie się do takiego jak jest w Tibii, to nawet nie ma sensu pisać kolizji. Wystarczy, że sprawdzisz czy kafelek, na który chcesz wejść nie jest przypadkiem przeszkodą. |
|
Quirinnos |
» 2015-03-31 12:00:32 Dokładnie, to co kolega wyżej napisał. Nie przesuwasz gracza od razu, tylko zapisujesz gdzieś, gdzie on chciałby się poruszyć. Potem sprawdzasz, czy miejsce na które chcę się przemieści jest dozwolone. Jeśli jest, poruszasz. Jeśli nie - nie ;) |
|
Brunon3 |
» 2015-03-31 14:08:08 Tak, ale takie rozwiązanie jak podano wyżej jest bardzo nie uniwersalne i IMHO lepiej jest się nauczyć takich kolizji jak ja podałem. ;)
-BD. |
|
RazzorFlame |
» 2015-03-31 15:19:32 Głupotą jest pisać w ten sposób wykrywanie kolizji. Prawdziwy silnik fizyczny powinien posiadać takie 3 zaimplementowane kroki: 1. Collision Detection 2. Collision Collision analyzer 3. Collision responser
Poza tym po co pisać silnik fizyczny do czegoś co nie będzie go używało. Możesz i tak przecież użyć jakiegoś gotowego silnika fizycznego. Na obliczanie tracisz czas i wydajność.
|
|
« 1 » 2 3 4 |