chitler Temat założony przez niniejszego użytkownika |
[SFML 2.1][STL] Zapełnienie kontenera vector obiektami klasy. » 2014-05-07 18:09:35 Witam. Mam problem tego typu że chcę w pętli for wykonywanej przez ustaloną liczbę razy, dodać nowy element do kontenera typu vector. Dodanym elementem ma być obiekt klasy "targets" z polami o typach: sf::Sprite, sf::Texture, sf::Image i innymi podstawowymi. W konstruktorze klasy "targets", nadaje każdemu elementowi własne właściwości, teksturę (akurat to każdy nowy element ma taki sam) oraz, skalę, rozmiar, położenie X i Y, które są wybierane losowo. Chcę osiągnąć aby załóżmy pętla przeszła 3 razy, i wypełniła kontener trzema obiektami klasy "targets", a potem chcę te 3 Sprajty nanieść na ekran. 1.Tak nie działa Zapełnanie vectora: int countTarget = 3; vector < targets > test;
for( int i = 0; i < countTarget; i++ ) { test.push_back( targets() ); }
Lub tak: int countTarget = 3; vector < targets > test;
for( int i = 0; i < countTarget; i++ ) { targets tmpTargets; test.push_back( tmpTargets ); }
I to się kompiluje, lecz wyświetlany obraz jest niepoprawny. Są to 3 prostokąty, o różnych skalach i położeniu, czyli tak jakby nie wczytała się tekstura do sprajta. A gdy zrobię to tak, to działa: int countTarget = 3; targets tmpTarget[ countTarget ]; vector < targets > test;
for( int i = 0; i < countTarget; i++ ) { test.push_back( tmpTarget[ i ] ); }
Nie można jakoś usprawnić tych pierwszych niedziałających sposobów, żeby działały? Jestem po prostu ciekaw, i chcę powiększyć wiedzę. Pozatym bardziej elegancko będzie bez tymczasowej tablicy statycznej. wyświetlam to zawsze w ten sam sposób. for( int i = 0; i < test.size(); i++ ) { Window.draw( test[ i ].cel ); }
Mogę dodać jeszcze zdjęcia, tego jak to wygląda, a jak nie wygląda, oraz kody klasy. Będe bardzo wdzięczny za pomoc. Pozdrawiam |
|
colorgreen19 |
» 2014-05-07 21:13:10 napisałes jakoś tak nie składnie. Napisz co ci nie działa, co działa, co chcesz osiągnąć a co brzydko wygląda; |
|
pekfos |
» 2014-05-07 21:21:24 Najprawdopodobniej nie obsługujesz poprawnie kopiowania obiektu targets. z polami o typach: sf::Sprite, sf::Texture, sf::Image i innymi podstawowymi. |
Wow.. To na jakiś konkurs, na najgorszy projekt? |
|
chitler Temat założony przez niniejszego użytkownika |
» 2014-05-08 11:20:36 no dobra, post nie jest najlepszy, ale ja też jestem tylko początkującym programistą. pefkos, dlaczego chcesz mnie zniechęcić i zgnoić zamiast zmotyowować? proszę o to cały projekt: pytanie po prostu brzmi: jak najlepiej zainicjalizować objekty target i wpakować je do kontenera vector #include <stdio.h> #include "SFML/Window.hpp" #include "SFML/Graphics.hpp" #include <string> #include <vector> #include <iostream> #include <ctime> #include <cstdlib> #include "targets.h" using namespace std;
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; }
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; if( mouseX - maskaX - sprX < 0 && mouseY - maskaY - sprY < 0 ) { sf::Color check = maska.getPixel(( mouseX - sprX ) *( 1 / skalaX ),( mouseY - sprY ) *( 1 / skalaX ) ); if( check.a == 255 ) return true; else return false; } return false; }
int main( int argc, char * argv[] ) { srand( time( NULL ) ); sf::Texture texture2; if( !texture2.loadFromFile( "celownik.png" ) ) { cout << "nie mozna otworzyc celownika" << endl; } sf::Sprite celownik; celownik.setTexture( texture2 ); celownik.setPosition( 200, 200 ); celownik.setOrigin( 33, 34 ); int countTarget = 3; targets tmpTarget[ countTarget ]; vector < targets > test; for( int i = 0; i < countTarget; i++ ) { test.push_back( tmpTarget[ i ] ); } cout << test.size(); sf::RenderWindow Window( sf::VideoMode( 640, 480 ), "Shoot da Bastard" ); while( Window.isOpen() ) { celownik.setPosition( sf::Mouse::getPosition( Window ).x, sf::Mouse::getPosition( Window ).y ); sf::Event Event; while( Window.pollEvent( Event ) ) { switch( Event.type ) { case sf::Event::Closed: Window.close(); break; case sf::Event::MouseButtonPressed: for( int i = 0; i < test.size(); i++ ) { if( isSpriteClicked( test[ i ].cel, Window ) ) { if( isMaskNotAlpha( test[ i ].maska, Window, test[ i ].cel ) ) { cout << "TRAFILO W NIEPRZEZROCZYSTY" << endl; } } else cout << "nietrafiony" << endl; } break; default: break; } } Window.clear( sf::Color::Black ); for( int i = 0; i < test.size(); i++ ) { Window.draw( test[ i ].cel ); } Window.draw( celownik ); Window.display(); } return 0; }
plik z metodami #include "targets.h" using namespace std; targets::targets() { scale = RandFloatDced( 2, 10 ); coordX = RandInt( 0, 640 -( 350 * scale ) ); coordY = RandInt( 0, 480 -( 350 * scale ) ); if( !texture.loadFromFile( "hitlerAlfa.png" ) ) { cout << "nie mozna otworzyc celu" << endl; } cel.setTexture( texture ); cel.setPosition( coordX, coordY ); cel.scale( scale, scale ); if( !maska.loadFromFile( "hitlerAlfa.png" ) ) { cout << "nie mozna otworzyc maski" << endl; } cout << "wylosowane coordy x:" << coordX << " y:" << coordY << endl; cout << "wylosowana skala: " << scale << endl; }
int targets::RandInt( int a, int b ) { int result =( rand() % b - a ) + a; return result; }
float targets::RandFloatDced( int a, int b ) { float result =( rand() % b - a ) + a; result = result / 10; cout << result << endl; return result; } targets::~targets() { }
klasa targets #ifndef TARGETS_H #define TARGETS_H #include <cstdlib> #include <iostream> #include "SFML/Window.hpp" #include "SFML/Graphics.hpp"
class targets { public: int coordX; int coordY; float scale; sf::Texture texture; sf::Sprite cel; sf::Image maska; targets(); ~targets(); int RandInt( int a, int b ); float RandFloatDced( int a, int b ); };
#endif
|
|
pekfos |
» 2014-05-08 11:44:19 pefkos, dlaczego chcesz mnie zniechęcić i zgnoić zamiast zmotyowować? |
'pekfos', a takiego zamiaru nie mam. To po prostu prawdopodobnie najgorsze możliwe rozwiązanie do przypisywania tekstur obiektom - początkujący czy nie, wiedzieć nie zaszkodzi.. I to jest też przyczyna problemu. targets nie ma konstruktora kopiującego i operatora przypisania, który zapewniłby poprawne kopiowanie sprajta. sf::Sprite trzyma tylko wskaźnika na teksturę, ustawiany w setTexture(). Obecnie, po skopiowaniu obiektu i zniszczeniu oryginału, wskaźnik nie jest poprawny. Wracając do początku - tekstury powinny być trzymane oddzielnie. Utwórz do tego klasę, lub twórz tekstury jako luźne zmienne i przypisuj je obiektom za pomocą metody podobnej to setTexture() ze sprajta. Wraz z kopiowaniem obiektu, tekstury nie zmienią swojego położenia, więc nie będziesz musiał programować kopiowania. No i tekstury będziesz ładować wtedy raz, a nie osobno do każdego obiektu, co jest wolne i pamięciożerne. |
|
« 1 » |