TankRockett Ответов: 3

Нужна помощь с ошибкой 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 модуль не компилируется после изменения, или у вас есть вызов конструктора где-то еще с неправильным количеством параметров.

3 Ответов

Рейтинг:
27

Shao Voon Wong

Я не вижу ничего плохого в вашем коде. Вы можете попробовать очистить решение и перестроить его или проект. Выберите решение или проект на вкладке обозреватель проектов в VS и щелкните правой кнопкой мыши, чтобы открыть контекстное меню, а затем выберите пункт "Очистить". Затем используйте ту же процедуру, чтобы выбрать "построить".


Richard MacCutchan

Смотреть ниже.

TankRockett

Спасибо,это было неожиданно глупо с моей стороны.

Рейтинг:
1

phil.o

Если вы измените существующий конструктор, вы можете сломать вещи везде, где используется прежний конструктор.

Вместо этого вы можете попытаться создать перегрузку конструктора, добавив нужные параметры. Таким образом, компоновщик не будет потревожен, так как он сможет ссылаться как на устаревший конструктор, так и на введенную вами перегрузку.


Рейтинг:
0

Richard MacCutchan

В Settings.cpp у вас есть:

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)); // 14 parameters
}


Но ваш конструктор кнопок от Gui.cpp есть
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)  // 17 parameters (although the 17th is zero if absent


В сообщении об ошибке отображается 17 параметров, поэтому ваш проект, по-видимому, не синхронизирован.