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

[SFML 2.1] Kolizja per pixel

Ostatnio zmodyfikowano 2014-12-14 14:23
Autor Wiadomość
Winner
Temat założony przez niniejszego użytkownika
[SFML 2.1] Kolizja per pixel
» 2014-12-09 20:11:43
Cześć, od wczoraj zastanawiam się jak zrobić kolizje per pixel w mojej grze. Znalazłem kilka możliwości ale w każdej z nich trzeba podać nazwe obrazu z którego chce się pobrać kolor pixela, niestety ja takiego obrazu nie posiadam, ponieważ mam mapę kafelkową i nie mam jej obrazu jako całość. A mi chodzi o prostą funkcje która zwróci mi kolor pixela na podanych współrzędnych z wyświetlanej już mapy.
P-122596
colorgreen19
» 2014-12-09 20:28:04
texture z mapy na sf::Image i możesz getPixel() użyc
P-122597
Winner
Temat założony przez niniejszego użytkownika
» 2014-12-09 20:45:54
Nie wiem czy dobrze zrozumiałem, ale która z tych funkcji http://sfml-dev.org/documentation/2.0/classsf_1_1Image.php  "przekształci" mi texture na image? Tutaj kod odpowiadający za ładowanie textur:
C/C++
NazwyTextur[ 0 ] = "cegla.png";
NazwyTextur[ 1 ] = "podloze.png";
NazwyTextur[ 2 ] = "komin.png";
NazwyTextur[ 3 ] = "komin2.png";

for( int i = 0; i <= 3; i++ )
{
    tlo[ i ].loadFromFile( NazwyTextur[ i ] );
}
for( int i = 0; i <= 3; i++ )
{
    teren[ i ].setTexture( tlo[ i ] );
}
P-122601
colorgreen19
» 2014-12-09 21:11:02
sf::Texture::copyToImage()
P-122604
Winner
Temat założony przez niniejszego użytkownika
» 2014-12-09 21:35:06
I chyba nie zrozumieliśmy się co do mojego problemu :/
Mam teraz taki kod:
C/C++
NazwyTextur[ 0 ] = "cegla.png";
NazwyTextur[ 1 ] = "podloze.png";
NazwyTextur[ 2 ] = "komin.png";
NazwyTextur[ 3 ] = "komin2.png";

for( int i = 0; i <= 3; i++ )
{
    tlo[ i ].loadFromFile( NazwyTextur[ i ] );
    pixel[ i ] = tlo[ i ].copyToImage();
}
for( int i = 0; i <= 3; i++ )
{
    teren[ i ].setTexture( tlo[ i ] );
}
}
Wcześniej sf::Image pixel[4];
Kompiluje się.
I co dalej? Mógłbym użyć getpixel ale na jakich współrzędnych? Bo np. teren wyświetlam i ustawiam za pomocą tego kodu:

C/C++
void LadowanieMapy( int iLiczba )
{
    map_y = 0;
    for( int i = 0; i < 13; i++ )
    {
        map_x = 0;
        for( int j = 0; j < 100; j++ )
        {
            if( mapa[ i ][ j ] == 2 )
            {
                teren[ 0 ].setPosition( map_x + iLiczba, map_y );
                GraMario.draw( teren[ 0 ] );
               
            }
            if( mapa[ i ][ j ] == 1 )
            {
                teren[ 1 ].setPosition( map_x + iLiczba, map_y );
                GraMario.draw( teren[ 1 ] );
            }
            if( mapa[ i ][ j ] == 3 )
            {
                teren[ 2 ].setPosition( map_x + iLiczba, map_y );
                GraMario.draw( teren[ 2 ] );
            }
            if( mapa[ i ][ j ] == 4 )
            {
                teren[ 3 ].setPosition( map_x + iLiczba, map_y );
                GraMario.draw( teren[ 3 ] );
            }
            map_x += 50;
        }
        map_y += 50;
    }
   
}
I mam sobie jakąś tablice z mapą:

np. mape[5][5] =
{
  0,0,0,0,0,
  0,0,1,2,3,
  0,0,1,2,3,
  0,1,2,3,0
  0,0,0,0,0
};

I na miejscach "0" nie wyświetlam nic tylko czyszcze ekran na czarno i właśnie jak pobrać pixele gdzie jest tylko czarny kolor?


P-122606
colorgreen19
» 2014-12-10 16:38:59
1) narazie mape masz małą ale rysowanie każdego kafelka osobno wkrótce da ci sie we znaki pod względem wydajności. polecam ci użycie sf::VertexArray, na stronie SFMLa masz nawet kod jak łątwo zaimplementować na tym mape
2) nie musisz robic kolizji per pixel. wystarczy że bedziesz sprawdzał ją dla kafelków. no chyba że masz textury skośne itp to wtedy tak (najlepiej pokaż co tam masz)
3) możesz spróbować zbudować swój kod w oparciu o to https://github.com/LaurentGomila/SFML/wiki/Source:-Simple-Collision-Detection-for-SFML-2

a odwołując sie do twojego pytania. jeśli twoja mapa zaczyna sie od 10,10, kazdy kafelek ma np szerokosci 20 to kafelki bd po kolei na pozycjach (10,10),(30,30),(50,50). Więc używając getPixel() najpierw powinieneś "znalezc" obraz na którym chcesz tej funkcji użyć.
pseudo kod:
C/C++
#define TILE_SIZE 60
#define TILE_COUNT 3

sf::Image img[ 3 ]; //twoje obrazy z kafelków
int mapPosX = 10;
int alpha = 127;

for( int i = 0; i < TILE_SIZE; i++ ) //tylko iteracja pixeli "pozioma"
{
    if( img[ i / 20 ].getPixel( i + mapPosX, 10 ).a > alpha ) //kiedy pixel ma byc brany jako przeźroczysty
    ...
}
//pisane bez sprawdzenia, możliwe błędy
P-122632
Winner
Temat założony przez niniejszego użytkownika
» 2014-12-12 17:12:45
Ten kod:
if( img[ i / 20 ].getPixel( i + mapPosX, 10 ).a
 zawsze zwraca wartość 255, obojętnie czy wyczyszcze ekran na niebiesko, czarno czy załaduje same białe obrazy zamiast mapy zawsze wynosi 255 :/

A do to tamtych podpunktów to narazie mam mapę 100/50 i nie widzę spadków wydajności, ale dzięki za propozycje :)
Robię kolizje per pixel bo kiedyś chciałem zrobić kolizje kafelkową ale były problemy z nią gdy mapa przesuwała się w lewą stronę(nie mogłem sprawdzić wszystkich możliwości) i dlatego wybrałem kolizje per pixel.
P-122748
colorgreen19
» 2014-12-12 17:49:56
bo to zwraca kanał alpha pixela czyli jego przeźroczystość. a nie kolor czy jest biały, różowy czy zielony
P-122751
« 1 » 2
  Strona 1 z 2 Następna strona