View previous topic :: View next topic |
Author |
Message |
Tankists
Joined: 18 Dec 2006 Posts: 81 Location: Baldone
|
Posted: Fri Oct 31, 2008 3:35 pm Post subject: Pogu uzglabasana menu klase |
|
Temas nosaukums varbut nedod izsmelosu info par problemu, bet neko labaku nespeju izdomat.
Lieta tada, ka ir CButton klase ar kuru palidzibu zimeju pogas uz ekrana, un ir CMenu klase kura es gribu lai glabajas visas pogas kas bus saja menu. No sakuma ienaca prata ideja CMenu klase izveidot std::vector<CButton> buttonSet mainigo ar kuru varet itka vienkarsi pievienot un manipulet ar katru no pogam, lidzigi ka ar masivu, tikai man tas skita ertak. CMenu konstruktora tiek izveidots tempButton kuram salieku poziciju un tekstu un tad buttonSet.push_back(tempButton), tad atkal pakorigeju tempButton ka vajag un atakl push_back(tempButton). Tad CMenu::handleEvents dariju sadi:
Code: | for (int i=0; i < buttonSet.size(); i++)
{
buttonSet.at(i).handleEvents(); //handleEvents ir pogas membera funkcija
} |
un tapat ar CMenu::update() un CMenu::draw() funkciju, bet rezultata nekas nesanak, pogas vienkarsi netiek uzzimetas, laigan piemeram ievietojot CButton::draw() funkcija kaitvai izvadi "a" burtam konsole redzams ka si funkcija tiek izsaukta, bet nesaprotu kapec nekas netiek uzzimets uz ekrana.
Izmeginaju to parastaka veida ar masivu kura glabajas sis pogas, viss iet ka tam vajadzetu notikt. Tatad kautko nepareizi daru ar vector`iem.
Piedodiet par negramatisku tekstu, ceru ka no si visa murga ko izlasijat kads vares palidzet... _________________ Getting used to problems... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Fri Oct 31, 2008 3:48 pm Post subject: |
|
Tev tā CButton gadījumā nesatur kādu mainīto nevis pēc vērtības, bet kā pointeri? Jo tādā gadījumā visiem buttoniem tas būs viens un tas pats, ja tos kopē no viena tempButtona. Varbūt tur ir problēma?
Starp citu - vektoram ir arī [] operators, nevajag to .at() lietot.
Var mierīgi rakstīt tāpat kā parastam masīam: buttonSet[i].handleEvents();
Vai vēl labāk - lietot iteratorus:
Code: | for (std::vector<CButton>::const_iterator button=buttonSet.begin(); button != buttonSet.end(); ++button)
{
button->handleEvents();
} |
Lai to būtu ērtāk pierakstīt, uztaisi makrosu:
Code: | #define EACH_CONST(Class, Container, Iterator) \
(Class::const_iterator Iterator=Container.begin(); Iterator != Container.end(); ++Iterator) |
Tad varēsi rakstīt šādi:
Code: | for EACH_CONST(std::vector<CButton>, buttonSet, button)
{
button->handleEvents();
} |
|
|
Back to top |
|
|
Tankists
Joined: 18 Dec 2006 Posts: 81 Location: Baldone
|
Posted: Fri Oct 31, 2008 3:57 pm Post subject: |
|
CButton klase izskatas sadi:
Code: | class CButton
{
public:
CButton();
void handleEvents(CGameEngine* game);
void updateButton();
void drawButton(CGameEngine* game);
void setPos(int x, int y); //sets buttons position
void setTab(int tab); //sets x position of text relative to button
void setText(char* string); //sets text string of button
void setTextColor(sf::Color color); //set text color of button
CPoint getButtonPos(); //gets buttons position
CPoint getTextRelPos(); //gets text position relative to button
bool mouseOver;
bool buttonPressed;
private:
sf::Font textFont;
sf::String textString;
CRect buttonBox;
}; |
pointerus itka nesatur... _________________ Getting used to problems... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Fri Oct 31, 2008 4:20 pm Post subject: |
|
sf::Font un sf::String var saturēt sazin ko iekšā...
Un šis te: Code: | void setText(char* string); //sets text string of button
| ir kautkas ļoti drausmīgs.
Ja tu programmē C++, tad par char* aizmirsti. Visur, kur tev vajag stringu, tur lieto tikai un vienīgi std::string. Funkciju argumentos const std::string&. |
|
Back to top |
|
|
snake5 Indago dalībnieks
Joined: 27 Jun 2007 Posts: 2590
|
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Fri Oct 31, 2008 6:05 pm Post subject: |
|
šņakuci, tev vēl nav apnicis offtopiku beztēmā dzīt?
Tajā doxygen ģenerētajā dokumentācijā nav privātie memberu uzskaitīti vispār. Būtu sourci apskatījis, redzētu, ka ir gan tur "sazin kas". |
|
Back to top |
|
|
Tankists
Joined: 18 Dec 2006 Posts: 81 Location: Baldone
|
Posted: Fri Oct 31, 2008 6:50 pm Post subject: |
|
Samainiju buttonSet.at(i), pret buttonSet[i] un pie CButton setText funkcijas pārliku uz const std::string& text, bet rezultāts joprojām tas pats. Ko vajadzētu mainīt, vai varbū vispār atmest domu par vector izmantošanu un lietot masīvu? _________________ Getting used to problems... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Fri Oct 31, 2008 6:56 pm Post subject: |
|
Vektora lietošanai nav ne vainas. Problēma ir kaut kur citur. Parādi kodu kā tu liec iekšā vektorā tos buttonus. |
|
Back to top |
|
|
Tankists
Joined: 18 Dec 2006 Posts: 81 Location: Baldone
|
Posted: Fri Oct 31, 2008 6:57 pm Post subject: |
|
Code: | CMenu::CMenu()
{
CButton tempButton;
tempButton.setText("New Game");
tempButton.setPos(100, 100);
buttonSet.push_back(tempButton);
tempButton.setText("Load Game");
tempButton.setPos(100, 150);
buttonSet.push_back(tempButton);
tempButton.setText("Options");
tempButton.setPos(100, 200);
buttonSet.push_back(tempButton);
tempButton.setText("Credits");
tempButton.setPos(100, 250);
buttonSet.push_back(tempButton);
tempButton.setText("Quit");
tempButton.setPos(100, 300);
buttonSet.push_back(tempButton);
} |
_________________ Getting used to problems... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Fri Oct 31, 2008 7:16 pm Post subject: |
|
Iesaku iemācīties lietot konstruktorus:
Code: | class CButton
{
public:
CButton(const std::string& text, int x, int y)
{
setText(text);
setPos(x, y);
}
...
};
CMenu::CMenu()
{
buttonSet.push_back(CButton("New Game", 100, 100));
buttonSet.push_back(CButton("Load Game", 100, 150));
...
} |
|
|
Back to top |
|
|
Tankists
Joined: 18 Dec 2006 Posts: 81 Location: Baldone
|
Posted: Fri Oct 31, 2008 8:49 pm Post subject: |
|
Šādi jau ir daudz ērtāk un labāk laikam, bet šādā veidā radās cita problēma.
Iepriekšējais CButton konstruktors ielādēja fontu no faila un uzstādīja to tekstam:
Code: | CButton(const std::string& text, int x, int y)
{
sf::Font buttonFont;
buttonFont.LoadFromFile("fonts/button_font.ttf");
textString.SetFont(buttonFont);
} |
Tagad, kad ir:
Code: |
class CButton
{
public:
CButton(const std::string& text, int x, int y)
{
sf::Font buttonFont;
buttonFont.LoadFromFile("fonts/button_font.ttf");
textString.SetFont(buttonFont);
setText(text);
setPos(x, y);
}
...
}; |
Programma nokrešo pie fontu ielādes. Saprotu ka jāizmanto debugeris, bet nesaprotu ko nozīmē Segmentation fault un ko nozīmē viss šis(iekš Call stack:
Quote: | #0 100DC1F9 std::_Rb_tree<wchar_t, std::pair<wchar_t const, sf::Font::Character>, std::_Select1st<std::pair<wchar_t const, sf::Font::Character> >, std::less<wchar_t>, std::allocator<std::pair<wchar_t const, sf::Font::Character> > >::find() (D:\Mikus\C++\run\bin\Debug\sfml-graphics.dll:??)
#1 10032297 sf::String::RecomputeRect() (D:\Mikus\C++\run\bin\Debug\sfml-graphics.dll:??)
#2 100325E8 sf::String::GetRect() (D:\Mikus\C++\run\bin\Debug\sfml-graphics.dll:??)
#3 0040308A CButton::updateButton(this=0x3fa08) (D:/Mikus/C++/run/CButton.cpp:45)
#4 004029E7 CMenu::update(this=0x44e0f8) (D:/Mikus/C++/run/CMenu.cpp:29)
#5 00401E0E CIntroState::update(this=0x44e020, game=0x23fcd0) (D:/Mikus/C++/run/CIntroState.cpp:40)
#6 00401BC9 CGameEngine::update(this=0x23fcd0) (D:/Mikus/C++/run/CGameEngine.cpp:86)
#7 00402C4F main(argc=1, argv=0x326b0) (D:/Mikus/C++/run/main.cpp:16) |
_________________ Getting used to problems... |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Fri Oct 31, 2008 9:08 pm Post subject: |
|
Segmentation fault nozīmē to, ka programma nokrašojusi :)
A pēc tā call stack izskatās, ka sf::String pieprasa sf::Font'u, taču tas visdrīzāk ir izlādējies ārā. Tev CButton klases konstruktorā fonts tiek ielādēts un pie konstruktora beigām automātiski izlādēts (C++ destruktors izsaucās koda vadībai izejot no redzamības apgabala). Un arī - kur tev prāts katram buttonam lādēt vienu un to pašu fontu miljons reizes.
Prātīgāk ir ielādēt fontu tikai vienreiz:
Code: | CButton(sf::Font& font, const std::string& text, int x, int y)
{
textString.SetFont(font);
setText(text);
setPos(x, y);
}
class CMenu
{
....
sf::Font buttonFont;
};
CMenu::CMenu()
{
buttonFont.LoadFromFile("fonts/button_font.ttf");
buttonSet.push_back(CButton(buttonFont, "New Game", 100, 100));
buttonSet.push_back(CButton(buttonFont, "Load Game", 100, 150));
...
} |
|
|
Back to top |
|
|
Tankists
Joined: 18 Dec 2006 Posts: 81 Location: Baldone
|
Posted: Fri Oct 31, 2008 9:30 pm Post subject: |
|
Beidzot viss ir labi.
Paldies visiem kas palīdzēja. No kļūdām cenšos mācīties un laikam jau bez tām nekur tālu es netiktu. _________________ Getting used to problems... |
|
Back to top |
|
|
|