Итак, я делаю игру, и она работает отлично, поэтому я начал разрабатывать следующую часть игры, которая представляет собой систему chunking и поколение (вы могли бы сказать из моих предыдущих сообщений), но затем все неожиданно я получил некоторые случайные ошибки компоновщика, хотя я ничего не трогал в компоновщике, и игра работала отлично. Вот ошибки:Ошибка компоновщика 2019, не касаясь свойств компоновщика?
Error 3 error LNK2019: unresolved external symbol "public: class sf::Sprite __thiscall AbstractBlock::draw(void)" ([email protected]@@[email protected]@@XZ) referenced in function _main C:\(Insert personal stuff here)\Main.obj Top Down Shooter
Error 4 error LNK2019: unresolved external symbol "public: void __thiscall AbstractBlock::destroy(class b2World *)" ([email protected]@@[email protected]@@Z) referenced in function "public: int __thiscall Universe::saveGame(void)" ([email protected]@@QAEHXZ) C:\(Insert personal stuff here)\Universe.obj Top Down Shooter
Error 5 error LNK1120: 2 unresolved externals
Они не имеют номера строк и, кажется, проблема в Universe.obj и main.obj? Я честно не знаю, что это такое, так что вместо этого я собираюсь опубликовать оба .cpp файлов в полном:
Universe.cpp:
#include "Universe.h"
Universe::Universe(){
world = new b2World(b2Vec2(0, 0));
world->SetAllowSleeping(false);
chunkManager = new ChunkManager(world);
player = new Player(world);
}
Universe::~Universe()
{
}
int Universe::saveGame(){
player->destroy(world);
player = nullptr;
std::list<AbstractBlock>::iterator i;
for (i = getLoadedBlocks()->begin(); i != getLoadedBlocks()->end(); i++){
i->destroy(world);
}
world = nullptr;
return 1;
}
void Universe::spawnEntity(int x, int y, int entityID){
}
std::list<AbstractBlock>* Universe::getLoadedBlocks(){
return chunkManager->getLoadedBlocks();
}
void Universe::update(){
player->update();
world->Step(1/60.f, 8, 3);
}
Player* Universe::getPlayer(){
return player;
}
main.cpp:
#include <iostream>
#include "Box2D\Box2D.h"
#include "SFML/Graphics.hpp"
#include "Universe.h"
#include "simplexnoise.h"
int main(){
static int FPS = 1.f/60.f;
sf::RenderWindow window(sf::VideoMode(640, 480), "Top Down Shooter");
sf::Event event;
Universe universe;
bool running = true;
int distX;
int distY;
float angle;
while (running){
window.clear(sf::Color::White);
while (window.pollEvent(event)){
switch (event.type){
case sf::Event::Closed:
running = false;
break;
case sf::Event::KeyPressed:
switch (event.key.code){
case sf::Keyboard::Q:
running = false;
break;
case sf::Keyboard::W:
universe.getPlayer()->setMoveUp(true);
break;
case sf::Keyboard::A:
universe.getPlayer()->setMoveLeft(true);
break;
case sf::Keyboard::D:
universe.getPlayer()->setMoveRight(true);
break;
case sf::Keyboard::S:
universe.getPlayer()->setMoveDown(true);
break;
}
break;
case sf::Event::KeyReleased:
switch (event.key.code){
case sf::Keyboard::W:
universe.getPlayer()->setMoveUp(false);
break;
case sf::Keyboard::A:
universe.getPlayer()->setMoveLeft(false);
break;
case sf::Keyboard::D:
universe.getPlayer()->setMoveRight(false);
break;
case sf::Keyboard::S:
universe.getPlayer()->setMoveDown(false);
break;
}
break;
}
}
distX = (sf::Mouse::getPosition().x - universe.getPlayer()->getXpos() - window.getPosition().x - 10);
distY = (sf::Mouse::getPosition().y - universe.getPlayer()->getYpos() - window.getPosition().y - 30);
if (distX != 0){
angle = std::atan2f(distY, distX);
universe.getPlayer()->setAngle(angle + (b2_pi/2));
}
//Updating the universe
universe.update();
//Drawing Everything
window.draw(universe.getPlayer()->draw());
std::list<AbstractBlock>::iterator i;
for (i = universe.getLoadedBlocks()->begin(); i != universe.getLoadedBlocks()->end(); i++){
window.draw(i->draw());
}
window.display();
}
universe.saveGame();
return 0;
}
Итак, я пытался самостоятельно решить эту проблему, и я подумал, что это, возможно, та часть, в которой я использую итератор и списки, чтобы рисовать все текущие блоки во вселенной. Я думал об этом, потому что и у Вселенной, и у основного .cpp есть эти маленькие для них петли (которые я только недавно добавил). Поэтому я прокомментировал эти части в каждом файле, и все стало еще более странным. Visual Studio 2013 тогда дал мне ошибки, когда я запустил свою программу, а затем отвезет меня в файл xutility! Я не имею понятия почему! Я убедился, чтобы прокомментировать часть итератора и попытался снова, но то же самое произошло! С этими двумя строками итераторов прокомментировал, что я вообще не использую итераторы в своей программе! Зачем мне это отводить? Пожалуйста, помогите мне так запутаться>. <
Edit: AbstractBlock.cpp:
#include "AbstractBlock.h"
AbstractBlock::AbstractBlock()
{
}
AbstractBlock::AbstractBlock(int x, int y, float roation, b2World *world){
}
sf::Sprite AbstractBlock::draw(){
sf::Sprite sprite;
return sprite;
}
void AbstractBlock::destroy(b2World *world){
}
AbstractBlock::~AbstractBlock()
{
}
Я изначально программист Java, и я не был уверен, что если бы был способ сделать «абстрактный» класс, как вы можете в Java , поэтому вместо этого я просто сделал обычный класс с не многими определенными методами, которые затем унаследованы другими классами.
Второй Изменить: Я также решил показать свой класс Dirt, который расширяет свой класс AbstracBlock и до сих пор это единственный класс, который наследует от AbstractBlock:
#include "DirtBlock.h"
DirtBlock::DirtBlock()
{
}
DirtBlock::DirtBlock(int x, int y, float rotation, b2World *world){
bodyDef.position.Set(x, y);
bodyDef.type = b2_dynamicBody;
fixDef.density = .1f;
b2PolygonShape shape;
shape.SetAsBox(16, 16);
fixDef.shape = &shape;
body = world->CreateBody(&bodyDef);
body->CreateFixture(&fixDef);
texture.loadFromFile("dirt.png");
}
void DirtBlock::destroy(b2World *world){
world->DestroyBody(body);
body = nullptr;
}
DirtBlock::~DirtBlock()
{
}
sf::Sprite DirtBlock::draw(){
sf::Sprite sprite;
sprite.setTexture(texture);
sprite.setOrigin(16, 16);
sprite.setPosition(body->GetPosition().x, body->GetPosition().y);
return sprite;
}
Третье Edit: Также! Это где VisualStudio берет меня, когда я пытаюсь запустить мою программу:
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy != _Parent_proxy)
{ // change parentage
_Lockit _Lock(_LOCK_DEBUG);
_Orphan_me();
_Mynextiter = _Parent_proxy->_Myfirstiter;
_Parent_proxy->_Myfirstiter = this;
_Myproxy = _Parent_proxy;
}
Он находится в классе xutility, и я понятия не имею, что это is.The следующая строка не должна быть выполнена линия _Mynextiter.
Проблема не в этих файлах. Проблема заключается в файле (файлах), который определяет 'AbstractBlock :: draw (void)' и 'AbstractBlock :: destroy (класс b2World *)'. Этот файл (ы) отсутствует в проекте (или определения отсутствуют в файле), поэтому эти определения не найдены компоновщиком. – AnT
Является ли 'AbstractBlock' объектом библиотеки? Если не показать нам файлы, определяющие его, и не забудьте включить его заголовок в Main.cpp –
Вещи также просто немного страннее ... Вы знаете, как я сказал, что Visual Studio дала мне ошибку и отвела меня к файл xutility, когда я пропустил итерационную часть? Ну, я раскоментировал его, но теперь он все еще берет меня туда. О. Я так запутался. – MagnusCaligo