Нужна помощь с ошибкой lnk2019 в проекте SFML/C++
В настоящее время я создаю 2D видеоигру с использованием библиотеки SFML в сообществе Visual Studio 2019 с помощью серии учебников Youtube от Suraj Sharma:
https://www.youtube.com/watch?v=IdKZpv6xqdw&list=PL6xSOsbVA1ebkU66okpi-KViAO8_9DJKg&index=1
Недавно я составляю выпадающий список кнопок, которые будут реализованы в настройках игрового меню(видео с 44 по 48)
Например,когда я нажимаю на кнопку меню "Настройки", меню переключается в состояние "настройки", которое содержит выпадающий список параметров разрешения для меня на выбор.
Вот этот код:
Графический интерфейс.ч
<pre>#pragma once #ifndef GUI_H #define GUI_H #include "pch.h" enum BStates { IDLE = 0,HOVER,ACTIVE }; namespace gui { class Button { private: short unsigned bStates; short unsigned Id; sf::RectangleShape Shape; sf::Font* Font; sf::Text Text; sf::Color TextIdl; sf::Color TextHover; sf::Color TextActive; sf::Color Idle; sf::Color Hover; sf::Color Active; sf::Color OutlIdle; sf::Color OutlHover; sf::Color OutlActive; public: Button(float x, float y, float w, float h, sf::Font* Font, std::string Text, unsigned CharSize, sf::Color TextIdl, sf::Color TextHover, sf::Color TextActive, sf::Color Idle, sf::Color Hover, sf::Color Active ,sf::Color OutlIdle, //= sf::Color::Transparent ,sf::Color OutlHover = sf::Color::Transparent, sf::Color OutlActive = sf::Color::Transparent, short unsigned Id = 0); ~Button(); //Access const bool Pressed()const; const std::string GetText()const; const short unsigned& GetId()const; //Modifier void SetText(const std::string Text); void SetId(const short unsigned Id); //Function void Update(const sf::Vector2f& MousePos); void Render(sf::RenderTarget& target); }; class DrpList { private: float Keytime; float KeytimeMax; sf::Font& Fnt; gui::Button* ActivElmnt; std::vector<gui::Button*> List; bool ShowList; public: DrpList(float x, float y, float w, float h, sf::Font& Fnt, std::string List[], unsigned NumElemnt, unsigned DefIndex = 0); ~DrpList(); //Funcs const bool GetKeytime(); void UpdateKeytime(const float& dt); void Update(const sf::Vector2f& MousePos, const float& dt); void Render(sf::RenderTarget& target); }; } #endif // !BUTTON_H
Gui.cpp
#include "Gui.h" using namespace gui; Button::Button(float x, float y, float w, float h, sf::Font* Font, std::string Text, unsigned CharSize, sf::Color TextIdl, sf::Color TextHover, sf::Color TextActive, sf::Color Idle, sf::Color Hover, sf::Color Active ,sf::Color OutlIdle, sf::Color OutlHover, sf::Color OutlActive, short unsigned Id) { this->bStates = IDLE; this->Id = Id; this->Shape.setPosition(sf::Vector2f(x, y)); this->Shape.setSize(sf::Vector2f(w, h)); this->Shape.setFillColor(Idle); this->Shape.setOutlineThickness(1.f); this->Shape.setOutlineColor(OutlIdle); this->Font = Font; this->Text.setFont(*this->Font); this->Text.setString(Text); this->Text.setFillColor(TextIdl); this->Text.setCharacterSize(CharSize); this->Text.setPosition(this->Shape.getPosition().x + (this->Shape.getGlobalBounds().width / 2.f) - this->Text.getGlobalBounds().width / 2.f, this->Shape.getPosition().y + (this->Shape.getGlobalBounds().height / 2.f) - this->Text.getGlobalBounds().height / 2.f); this->TextIdl = TextIdl; this->TextHover = TextHover; this->TextActive = TextActive; this->Idle = Idle; this->Hover = Hover; this->Active = Active; this->OutlIdle = OutlIdle; /*this->OutlHover = OutlHover; this->OutlActive = OutlActive;*/ } Button::~Button() { } //Access const bool Button::Pressed() const { if (this->bStates == ACTIVE) return true; return false; } const std::string gui::Button::GetText() const { return this->Text.getString(); } const short unsigned& gui::Button::GetId() const { return this->Id; } //Modifier void gui::Button::SetText(const std::string Text) { this->Text.setString(Text); } void gui::Button::SetId(const short unsigned Id) { this->Id = Id; } //Functions void Button::Update(const sf::Vector2f& MousePos) { this->bStates = IDLE; if (this->Shape.getGlobalBounds().contains(MousePos)) { this->bStates = HOVER; if (sf::Mouse::isButtonPressed(sf::Mouse::Left)){ this->bStates = ACTIVE; } } switch (this->bStates) { case IDLE: this->Shape.setFillColor(this->Idle); this->Text.setFillColor(this->TextIdl); this->Shape.setOutlineColor(this->OutlIdle); break; case HOVER: this->Shape.setFillColor(this->Hover); this->Text.setFillColor(this->TextHover); this->Shape.setOutlineColor(this->OutlHover); break; case ACTIVE: this->Shape.setFillColor(this->Active); this->Text.setFillColor(this->TextActive); this->Shape.setOutlineColor(this->OutlActive); break; default: this->Shape.setFillColor(sf::Color::White); this->Text.setFillColor(sf::Color::Blue); this->Shape.setOutlineColor(sf::Color::Green); break; } } void Button::Render(sf::RenderTarget& target) { target.draw(this->Shape); target.draw(this->Text); } //-------------DrpList--------------- gui::DrpList::DrpList(float x, float y, float w, float h, sf::Font& Fnt, std::string List[], unsigned NumElemnt, unsigned DefIndex) :Fnt(Fnt), ShowList(false), KeytimeMax(10.f), Keytime(0.f) { //unsigned NumElemnt = sizeof(List) / sizeof(std::string); this->ActivElmnt = new gui::Button( x, y, w, h, &this->Fnt, List[DefIndex], 12, sf::Color(255, 255, 255, 150), sf::Color(255, 255, 255, 200), sf::Color(20, 20, 20, 50), sf::Color(70, 70, 70, 200), sf::Color(150, 150, 150, 200), sf::Color(20, 20, 20, 200), sf::Color(255, 255, 255, 200) sf::Color(255, 255, 255, 255), sf::Color(20, 20, 20, 200)); for (size_t i = 0; i < NumElemnt; i++) { this->List.push_back(new gui::Button( x, y + ((i + 1) * h), w, h, &this->Fnt, List[i], 12, sf::Color(255, 255, 255, 150), sf::Color(255, 255, 255, 255), sf::Color(20, 20, 20, 50), sf::Color(70, 70, 70, 200), sf::Color(150, 150, 150, 200), sf::Color(20, 20, 20, 200), sf::Color(255, 255, 255, 0) sf::Color(255, 255, 255, 0), sf::Color(20, 20, 20, 0),i)); } } gui::DrpList::~DrpList() { delete this->ActivElmnt; for (size_t i = 0; i < this->List.size(); i++) { delete this->List[i]; } } const bool gui::DrpList::GetKeytime() { if (this->Keytime >= this->KeytimeMax) { this->Keytime = 0.f; return true; } return false; } void gui::DrpList::UpdateKeytime(const float& dt) { if (this->Keytime < this->KeytimeMax) this->Keytime += 10.f * dt; } //DrpList void gui::DrpList::Update(const sf::Vector2f& MousePos , const float& dt) { this->UpdateKeytime(dt); this->ActivElmnt->Update(MousePos); //Show - hide list if (this->ActivElmnt->Pressed() && this->GetKeytime()) { if (this->ShowList) this->ShowList = false; else this->ShowList = true; } if (this->ShowList) { for (auto& i : this->List) { i->Update(MousePos); if (i->Pressed() && this->GetKeytime()) { this->ShowList = false; this->ActivElmnt->SetText(i->GetText()); this->ActivElmnt->SetId(i->GetId()); } } } } void gui::DrpList::Render(sf::RenderTarget& target) { this->ActivElmnt->Render(target); if (this->ShowList) { for (auto& i : this->List) { i->Render(target); } } }
Параметры.ч
#pragma once #ifndef SETTINGS_H #define SETTINGS_H #include "State.h" #include "Gui.h" class Settings : public State { private: //Vars sf::Font Fnt; sf::Texture BgTex; sf::RectangleShape BackGrnd; std::map<std::string, gui::Button*> buttons; std::map<std::string, gui::DrpList*> drplist; gui::DrpList* Dl; //Functions void InitVars(); void InitBackGrnd(); void InitFonts(); void InitKeybinds(); void InitGui(); public: Settings(sf::RenderWindow* window, std::map<std::string, int>* SupportedKeys, std::stack<State*>* states); virtual~Settings(); //Access //Funcs void UpdateInput(const float& dt); void Update(const float& dt); void UpdateGui(const float& dt); void RenderGui(sf::RenderTarget& target); void Render(sf::RenderTarget* target = nullptr); }; #endif // !SETTINGS_H
Settings.cpp
#include "Settings.h" //Init Funcs void Settings::InitVars() { } void Settings::InitBackGrnd() { this->BackGrnd.setSize( sf::Vector2f( static_cast<float>(this->window->getSize().x), static_cast<float>(this->window->getSize().y))); if (!this->BgTex.loadFromFile("Resources/Images/BackGrounds/Menu/M2.png")) { throw "Error:Main_Menu:Failed to load background texture"; } this->BackGrnd.setTexture(&this->BgTex); } void Settings::InitFonts() { if (!this->Fnt.loadFromFile("Fonts/SPACEMAN.ttf")) { throw("Error:Main Menu St::Couldn't load font"); } } void Settings::InitKeybinds() { std::ifstream ifs("Config/MMKeys.ini"); if (ifs.is_open()) { std::string key = ""; std::string key2 = ""; int keyval = 0; while (ifs >> key >> key2) { this->Keybinds[key] = this->SupportedKeys->at(key2); } } ifs.close(); this->Keybinds["CLOSE"] = this->SupportedKeys->at("ESC"); this->Keybinds["Left"] = this->SupportedKeys->at("A"); this->Keybinds["Right"] = this->SupportedKeys->at("D"); this->Keybinds["Up"] = this->SupportedKeys->at("W"); this->Keybinds["Down"] = this->SupportedKeys->at("S"); } void Settings::InitGui()//Lnk2019 { this->buttons["Exit"] = new gui::Button( 900.f, 880.f, 250.f, 50.f, &this->Fnt, "Back", 50, sf::Color(70, 70, 70, 200), sf::Color(150, 150, 150, 250), sf::Color(20, 20, 20, 50), sf::Color(70, 70, 70, 0), sf::Color(150, 150, 150, 0), sf::Color(20, 20, 20, 0), sf::Color(70, 70, 70, 0)); std::string Li[] = {"1920x1080","800x600","640x480"}; this->drplist["Resolution"] = new gui::DrpList(800, 450, 200, 50, Fnt, Li, 3); } Settings::Settings(sf::RenderWindow* window, std::map<std::string, int>* SupportedKeys, std::stack<State*>* states) :State(window,SupportedKeys,states) { this->InitVars(); this->InitBackGrnd(); this->InitFonts(); this->InitKeybinds(); this->InitGui(); } Settings::~Settings() { auto it = this->buttons.begin(); for (it = this->buttons.begin(); it != this->buttons.end(); ++it) { delete it->second; } auto it2 = this->drplist.begin(); for (it2 = this->drplist.begin(); it2 != this->drplist.end(); ++it2) { delete it2->second; } } //Access //Funcs void Settings::UpdateInput(const float& dt) { } void Settings::Update(const float& dt) { this->UpdateMousePos(); this->UpdateInput(dt); this->UpdateGui(dt); std::cout << this->MousePosView.x << " " << this->MousePosView.y << "\r"; } void Settings::UpdateGui(const float& dt) { //Update guis and handle their functions for (auto& it : this->buttons) { it.second->Update(this->MousePosView); } //Quit if (this->buttons["Exit"]->Pressed()) { this->Endstate(); } //Drop List for (auto& it : this->drplist) { it.second->Update(this->MousePosView, dt); } } void Settings::RenderGui(sf::RenderTarget& target) { for (auto& it : this->buttons) { it.second->Render(target); } for (auto& it : this->drplist) { it.second->Render(target); } } void Settings::Render(sf::RenderTarget* target) { if (!target) target = this->window; target->draw(this->BackGrnd); this->RenderGui(*target); }
Полное сообщение об ошибке:
'
Ошибка lnk2019 ошибка
неразрешенных внешних символ "общественности: __thiscall интерфейс::кнопка:кнопка(поплавок,поплавка,флоат,поплавковый,класса СФ::купели *,класс std::элементах&ЛТ;шар,структура, функции std::char_traits&ЛТ;char с=""&ГТ;,класс std::распределитель&ЛТ;чар&ГТ; &ГТ;,беззнаковый инт класса СФ::цвет,класс СФ::цвет,класс СФ::цвет,класс СФ::Цвет,класса СФ::цвет,класс СФ::цвет,класс СФ::цвет,класс СФ::цвет,класс СФ::цвет,короткое целое без знака)" (??0Button@ГИП@@ка@MMMMPAVFont@СФ@@в?$basic_strin г@ДУ?$char_traits@Д@СТД@@в?$распределитель@Д@2@@СТД@@Ив цвет@3@22222222G@З), на которые ссылается функция "частная: пустота __thiscall параметры::InitGui(ничтожным)" (?Параметры InitGui@@@AAEXXZ)
Проект:
Звездный Огонь
Файл:
F:\Star огонь СФМЛ\Звездный огонь\настройки.параметр obj
Линия:
1
'
Все отлично работает до видео 48,а Lnk2019 происходит сразу после того, как я ввожу дополнительные параметры в 'gui::Button();' конструктор in 'Gui.cpp-в частности, параметры" sf::color:: "OutlIdle - Hover и Active. Как только я их вставляю, возникает ошибка.
Кто-нибудь может мне помочь ?
Что я уже пробовал:
Вместо этого я попытался запустить проект в режиме выпуска, и он отлично работает.Ошибка появляется только в отладке.
Richard MacCutchan
Либо то, что Gui.cpp модуль не компилируется после изменения, или у вас есть вызов конструктора где-то еще с неправильным количеством параметров.