LNK 2001 unresolved with C++ SFML

LNK 2001 unresolved with C++ SFML

本文关键字:C++ SFML with unresolved 2001 LNK      更新时间:2023-10-16

我正在尝试使用SFML库在C 中移动的角色。每次制作项目时,我都会出现相同的LNK 2001错误。

请向我解释我做错了什么以及如何解决。我仍然是初学者,因此,如果您对解决错误或编写代码有任何建议。

main.cpp:

#include "Game.cpp"
#include "Game.h"
int main ()
{
    Game Game;
    Game.GameRun();
}

game.h:

#pragma once
#include <SFMLWindow.hpp>
#include "Character.h"
class Game
{
public:
    void GameRun ();
    void UpdateGame(Character player);
    void Controls(int sourceX, int sourceY, Character player);
};

targin.h:

#pragma once
#include <SFMLGraphics.hpp>
#include <SFMLSystem.hpp>
#include <SFMLWindow.hpp>
#include "Game.h"
class Character
{
public:
    enum Direction {Down, Left, Right, Up};
    int characterX;
    int characterY;
    sf::Texture txt_character;
    sf::Sprite spr_character;
};

game.cpp:

#include "Game.h"
#include "Character.h"
#include <iostream>
inline void Game::GameRun()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML test");
    Character player;
    player.characterX = 1;
    player.characterY = Character::Down;
    player.txt_character.loadFromFile("character sprite sheet.png");
    player.spr_character.setTexture(player.txt_character);
    while(window.isOpen())
    {
        Game::UpdateGame(player);
    }
}
inline void Game::UpdateGame(Character player)
{
    sf::Event event;
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML test");
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
        window.close();
    }
    Game::Controls(player.characterX, player.characterY, player);
    player.spr_character.setTextureRect(sf::IntRect(player.characterX * 32, player.characterY * 32, 32, 32));
    window.draw(player.spr_character);
    window.display();
    window.clear();
}
inline void Game::Controls(int sourceX, int sourceY, Character player)
{
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        sourceY = Character::Up;
        sourceX++;
        if (sourceX * 32 >= player.txt_character.getSize().x)
            sourceX = 0;
        player.spr_character.move(0, -2);
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    {
        sourceY = Character::Down;
        sourceX++;
        if (sourceX * 32 >= player.txt_character.getSize().x)
            sourceX = 0;
        player.spr_character.move(0, 2);
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        sourceY = Character::Left;
        sourceX++;
        if (sourceX * 32 >= player.txt_character.getSize().x)
            sourceX = 0;
        player.spr_character.move(-2, 0);
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        sourceY = Character::Right;
        sourceX++;
        if (sourceX * 32 >= player.txt_character.getSize().x)
            sourceX = 0;
        player.spr_character.move(2, 0);
    }
}

错误:

1> main.obj:错误lnk2001:未解决的外部符号" public:static int角色::角色"(?pronagy@tarne@targine@@@@2ha)

>

1> main.obj:错误lnk2001:未解决的外部符号" public:static int cartarair :: targinx"(?targinx@targinx@farne @@ 2ha)

>

1> c: users sony documents visual Studio 2010 projects promppy top down game debug game.exe.exe:致命错误lnk1120:2未解决的外部

谢谢:D

编辑:仅供参考,我没有上课的代码,而且它正常工作,它只是Main.cpp

中的一个很大的代码。

编辑:链接到程序for程序:https://www.dropbox.com/s/3yyjti8zwu019s7/top down game game with Classes.rar

编辑2014/03/08:我尝试了您的资源。在Main.cpp文件中删除#include "Game.cpp"inline文件中的CC_3关键字。

背后的逻辑不起作用,因此我将其修复至最低,因此它将在您解决编译(链接)错误后立即工作。您应该尝试我的代码以查看是否有帮助。

首先解释

按值传递播放器对象(如 void someMethod(Character player)时,将对象的副本发送到方法。因此,当您更改播放器对象时,这些更改仅是对副本而不是实际播放器进行的。我更改了您的代码,以便将指针发送给指针(void someMethod(Character * player)。该方法接收到对实际播放器对象的指针,对该对象进行的更改反映了实际播放器对象。

除了使用指针以外,还有其他解决方案(有人可能会说这是过度杀伤或太危险的)。

可能是:

  • 参考void someMethod(Character& player)
  • 或返回值Character someMethod(Character player)
  • 或两个Character someMethod(const Character& player)
  • 的混合
  • 或成员变量(在标题文件中定义)

另一件事是,您在字符类中保留sf ::按值按值。sf ::纹理确实是"重"的对象,因此不应按价值通过,应将其保存为指针。您可以做的最好的事情(并且我在下面的代码中没有完成)是完全从字符类中删除sf ::纹理,只保留已经容纳SF ::纹理的SF :: Sprite(在一种优化的方式,因此您不会打扰)。

这是代码

main.cpp

#include "Game.h"
int main ()
{
    Game Game;
    Game.GameRun();
}

game.h

#ifndef GAME_H_
#define GAME_H_
//#include <SFML/Window.hpp> /* you don't need this */
#include <SFML/Graphics/RenderWindow.hpp>

// forward declaration, this prevents recursive/circular dependencies.
// only works with pointer or referenced type.
class Character;
class Game
{
public:
    void GameRun ();
    // I change the param to pointer to Character for logic reasons.
    // You were doing changes on a Character COPY of the player,
    // which was deleted when leaving the scope of the functions.
    void UpdateGame(Character * player);
    void Controls(Character * player);
private:
    // I added this here, so you can create the window in the 
    // GameRun and UpdateGame methods where needed.
    sf::RenderWindow window;
};
#endif

game.cpp

#include "Game.h"
#include "Character.h"
#include <SFML/Window/Event.hpp> /* you only need this */
#include <iostream>
void Game::GameRun()
{
    // I moved the window creation here because you were 
    // creating a new window each update which made the windows
    // flickers each frame, making it impossible to close properly.
    window.create(sf::VideoMode(800, 600), "SFML test");
    Character * player = new Character();
    player->characterX = 1;
    player->characterY = Character::Down;
    // if the file isn't available, this will prevent further problems.
    if (player->txt_character.loadFromFile("character.png"))
    {
        player->spr_character.setTexture(player->txt_character);
    }
    while (window.isOpen())
    {
        Game::UpdateGame(player);
    }
}
void Game::UpdateGame(Character * player)
{
    sf::Event event;

    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed){
            window.close();
        }
    }
    Controls(player);
//  player.spr_character.setTextureRect(
//          sf::IntRect(player.characterX * 32, player.characterY * 32, 32,
//                  32));
    window.clear();
    window.draw(player->spr_character);
    window.display();
}
// You were already sending the player so I removed the other
// params and used the player instead.
void Game::Controls(Character * player)
{
    int sourceX = player->characterX;
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        player->characterY = Character::Up;
        sourceX++;
        if (sourceX * 32 >= player->txt_character.getSize().x)
            sourceX = 0;
        player->spr_character.move(0, -2);
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    {
        player->characterY = Character::Down;
        sourceX++;
        if (sourceX * 32 >= player->txt_character.getSize().x)
            sourceX = 0;
        player->spr_character.move(0, 2);
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        player->characterY = Character::Left;
        sourceX++;
        if (sourceX * 32 >= player->txt_character.getSize().x)
            sourceX = 0;
        player->spr_character.move(-2, 0);
    }
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        player->characterY = Character::Right;
        sourceX++;
        if (sourceX * 32 >= player->txt_character.getSize().x)
            sourceX = 0;
        player->spr_character.move(2, 0);
    }
    player->characterX = sourceX;
}

targin.h

#ifndef CHARACTER_H_
#define CHARACTER_H_
//#include <SFMLGraphics.hpp>
//#include <SFMLSystem.hpp>
//#include <SFMLWindow.hpp>
//#include "Game.h"
#include <SFML/Graphics/Sprite.hpp> /* Don't include more than you need */
#include <SFML/Graphics/Texture.hpp>
class Character
{
public:
    enum Direction {Down, Left, Right, Up};
    int characterX;
    int characterY;
    sf::Texture txt_character; // Don't keep the texture value, it's really heavy.
    sf::Sprite spr_character;
};
#endif

一般C 信息

  • 通过参考与通过价值传递的传递与传递之间有什么区别?
  • 何时使用远期声明?
  • 可选是什么导致需要转发声明类型。
  • C 中的指针变量和参考变量之间有什么区别?
  • 可选在指针的深度解释
  • 可选为什么"使用名称空间std";被认为是不良习惯吗?