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

[SFML 2.1] Sprawdzenie czy sprite został kliknięty w piksel kolorowy, czy przezroczysty.

Ostatnio zmodyfikowano 2014-05-05 16:41
Autor Wiadomość
chitler
Temat założony przez niniejszego użytkownika
[SFML 2.1] Sprawdzenie czy sprite został kliknięty w piksel kolorowy, czy przezroczysty.
» 2014-05-04 22:37:49
Ucząc się SFMLa chcę zrobić prostą gierkę, gdzie będziemy strzelać w jakiś cel (np w głowę, np w Adolfa, a kto mi zabroni :D )
wyciąłem samą głowę klienta i otoczyłem ją kanałem Alpha, wyświetla się ładnie. Wszystko działa tak jak powinno czyli po kliknięciu w sprite'a z głową, na konsoli pojawia się "trafiony". Teraz chciałbym zmodyfikować funkcję bool isSpriteClicked(.,.) tak aby zwracała TRUE gdy została kliknięta sama głowa, a nie tło alpha, dookoła niej.

Szukałem, szperałem, nie mogę znaleźć jak to zrobić. Jeśli się tak nie da, to trudno, będę parł naprzód.
Pozdrawiam

kod funkcji do sprawdzania kliknięcia w sprajta
C/C++
bool isSpriteClicked( sf::Sprite & av_Sprite, sf::RenderWindow & av_Window )
{
   
    int mouseX = sf::Mouse::getPosition().x;
    int mouseY = sf::Mouse::getPosition().y;
   
    sf::Vector2i windowPosition = av_Window.getPosition();
   
    if( mouseX > av_Sprite.getPosition().x + windowPosition.x && mouseX <( av_Sprite.getPosition().x + av_Sprite.getGlobalBounds().width + windowPosition.x )
    && mouseY > av_Sprite.getPosition().y + windowPosition.y + 30 && mouseY <( av_Sprite.getPosition().y + av_Sprite.getGlobalBounds().height + windowPosition.y + 30 ) )
    {
        if( sf::Mouse::isButtonPressed( sf::Mouse::Left ) )
        {
            return true;
        }
        return false;
    }
   
    return false;
   
}
P-109315
MrPoxipol
» 2014-05-04 23:47:16
getPixel() i składowa a (kanał alfa)
P-109317
chitler
Temat założony przez niniejszego użytkownika
» 2014-05-05 16:37:34
dzięki dzięki :) bardzo mi Pan pomógł. długo rozkminiałem i teraz mogę dodać wyniki mojej pracy, może komuś się przyda
funkcja typu bool sprawdzająca, czy dany sprite został kliknięty (w sensie prostokąt , pobierająca argumenty: Sprite i Render Window


C/C++
bool isSpriteClicked( sf::Sprite & av_Sprite, sf::RenderWindow & av_Window )
{
   
    int mouseX = sf::Mouse::getPosition().x;
    int mouseY = sf::Mouse::getPosition().y;
   
    sf::Vector2i windowPosition = av_Window.getPosition();
   
    if( mouseX > av_Sprite.getPosition().x + windowPosition.x && mouseX <( av_Sprite.getPosition().x + av_Sprite.getGlobalBounds().width + windowPosition.x )
    && mouseY > av_Sprite.getPosition().y + windowPosition.y + 30 && mouseY <( av_Sprite.getPosition().y + av_Sprite.getGlobalBounds().height + windowPosition.y + 30 ) )
    {
        if( sf::Mouse::isButtonPressed( sf::Mouse::Left ) )
        {
            return true;
        }
        return false;
    }
   
    return false;
   
}

a tutaj funkcja, która sprawdza, czy sprite o danej teksturze, o danym obrazku Image, kliknięty piksel jest przezroczysty

C/C++
bool isMaskNotAlpha( sf::Image & maska, sf::RenderWindow & Window, sf::Sprite & sprajt )
{
    int mouseX = sf::Mouse::getPosition( Window ).x;
    int mouseY = sf::Mouse::getPosition( Window ).y;
    float skalaX = sprajt.getScale().x;
    float skalaY = sprajt.getScale().y;
    int sprX = sprajt.getPosition().x;
    int sprY = sprajt.getPosition().y;
    int maskaX = maska.getSize().x * skalaX;
    int maskaY = maska.getSize().y * skalaY;
   
    /*cout<<mouseX<<"x"<<mouseY<<" rozmiar X maski to:"<<maskaX<<" skala x maski:"<<skalaX<<" pozycja x origin sprajta:"<<sprX<<endl;
        cout<<mouseX<<"y"<<mouseY<<" rozmiar Y maski to:"<<maskaY<<" skala y maski:"<<skalaY<<" pozycja y origin sprajta:"<<sprY<<endl;
        cout<<"rownanie X: "<<mouseX<<" - "<<maskaX<<" - "<<sprX<<" = "<< mouseX - maskaX - sprX<<endl;
        cout<<"rownanie Y: "<<mouseY<<" - "<<maskaY<<" - "<<sprY<<" = "<< mouseY - maskaY - sprY<<endl;*/
    if( mouseX - maskaX - sprX < 0 && mouseY - maskaY - sprY < 0 )
    {
        sf::Color check = maska.getPixel(( mouseX - sprX ) *( 1 / skalaX ),( mouseY - sprY ) *( 1 / skalaX ) );
        //cout<<"sprawdzam piksela na obrazku o coordach"<< (mouseX - sprX)*(1/skalaX)  << " x "<< (mouseY - sprY)*(1/skalaX) <<endl;
        if( check.a == 255 )
             return true;
        else
             return false;
       
    }
    return false;
   
}

a to wywołanie od Event tych funkcji :)
C/C++
case sf::Event::MouseButtonPressed:
cout << sf::Mouse::getPosition( Window ).x << " x " << sf::Mouse::getPosition( Window ).y << endl;
if( isSpriteClicked( cel, Window ) )
{
    cout << "trafiony" << endl;
    if( isMaskNotAlpha( maska, Window, cel ) )
    {
        cout << "TRAFILO W NIEPRZEZROCZYSTY" << endl;
    }
   
}
else
     cout << "nietrafiony" << endl;

break;

PS Przepraszam za mój kolokwialny język, i komentarze :D
P-109329
MrPoxipol
» 2014-05-05 16:41:36
Do sprawdzania, czy punkt leży w danym prostokącie możesz użyć metody sf::FloatRect::contains(sf::Vector2f).
sf::Sprite::getGlobalBounds()
P-109330
« 1 »
  Strona 1 z 1