SFML community forums
Help => General => Topic started by: NoobsDeSroobs on July 24, 2010, 01:07:41 pm
-
Risking being laughed at for bad coding, I still have a question that has been bugging me lately. "Unresolved external symbol". I have gotten this error a few times now, and I really want to know exactly what it means and why it is showing up. The code parts that are causing this are:
Player.cpp
#include "Player.h"
#include "Window.h"
Player::Player()
{
Image.LoadFromFile("Animal.tga");
Image.CreateMaskFromColor(sf::Color(255,0,255),0);
Sprite.SetImage(Image);
Sprite.SetCenter(10.f, 10.f);
}
int PlayerMovement()
{
sf::Event KeyPress;
bool up = Player::up;
bool down = Player::down;
bool left = Player::left;
bool right = Player::right;
bool shoot = Player::shoot;
int SpeedMultiplier = Player::SpeedMultiplier;
if (KeyPress.Type == sf::Event::KeyPressed)
{
switch (KeyPress.Key.Code)
{
case sf::Key::Up:
Player::up = true;
break;
case sf::Key::Down:
Player::down = true;
break;
case sf::Key::Left:
Player::left = true;
break;
case sf::Key::Right:
Player::right = true;
break;
case sf::Key::LShift:
Player::SpeedMultiplier = 3;
case sf::Key::Space:
Player::shoot = true;
default:
break;
}
}
if (KeyPress.Type == sf::Event::KeyReleased)
{
switch (KeyPress.Key.Code)
{
case sf::Key::Up:
up = false;
break;
case sf::Key::Down:
down = false;
break;
case sf::Key::Left:
left = false;
break;
case sf::Key::Right:
right = false;
break;
case sf::Key::LShift:
SpeedMultiplier = 1;
default:
break;
}
}
/* //MOVING THE PLAYER SPRITE.
if(up)
{
Player::Sprite.Move((cos(Player::Sprite.GetRotation()*3.14159265/180)*3)*Player::SpeedMultiplier, (sin(Player::Sprite.GetRotation()*3.14159265/180)*-3)*Player::SpeedMultiplier);
}
if(down)
{
Player::Sprite.Move((cos(Player::Sprite.GetRotation()*3.14159265/180)*-3)*Player::SpeedMultiplier, (sin(Player::Sprite.GetRotation()*3.14159265/180)*3)*Player::SpeedMultiplier);
}
if(left)
{
Player::Sprite.Rotate(6);
}
if(right)
{
PLayer::Sprite.Rotate(-6);
}
while (shoot)
{
//App.Draw(FireSprite);
//FireSprite.SetDirection(AnimalSprite);
//FireSprite.Move(cos(BulletAngle*3.14159265/180)*3, sin(BulletAngle*3.14159265/180)*-3);
//RenderTarget(FireSprite);
}*/
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include "Window.h"
#include "Enemy.h"
class Player
{
public:
Player();
sf::Image Image;
sf::Sprite Sprite;
int XCord();
int YCord();
static bool up;
static bool down;
static bool left;
static bool right;
static bool shoot;
static int SpeedMultiplier;
private:
int PosX;
int PosY;
};
int PlayerMovement();
#endif
Can you point out what is causing it and why it is a negative thing? I want to understand the errors so I can work with them even better in the future.
Notes:
The sfml packets are all under the Window.h header.
Full error list:
1>Player.obj : error LNK2001: unresolved external symbol "public: static bool Player::right" (?right@Player@@2_NA)
1>Player.obj : error LNK2001: unresolved external symbol "public: static bool Player::left" (?left@Player@@2_NA)
1>Player.obj : error LNK2001: unresolved external symbol "public: static bool Player::up" (?up@Player@@2_NA)
1>Player.obj : error LNK2001: unresolved external symbol "public: static int Player::SpeedMultiplier" (?SpeedMultiplier@Player@@2HA)
1>Player.obj : error LNK2001: unresolved external symbol "public: static bool Player::down" (?down@Player@@2_NA)
1>Player.obj : error LNK2001: unresolved external symbol "public: static bool Player::shoot" (?shoot@Player@@2_NA)
Thank you so much in advance.
-
Well, just read a tutorial about how to properly initialize static member variables... Google knows lots of them ;)
-
Well, just read a tutorial about how to properly initialize static member variables... Google knows lots of them ;)
Well, done that again, and as I understood it, the error is about me not adding a library or header file that is requested in my code. But I have gone through that and I know I have all of them added.
-
Not at all (don't forget "static" in your search keywords).
This is because you declare your static members, but you don't initialize them.
in player.cpp
-------------
bool Player::up = /* whatever */;
bool Player::down = /* whatever */;
bool Player::left = /* whatever */;
bool Player::right = /* whatever */;
bool Player::shoot = /* whatever */;
int Player::SpeedMultiplier = /* whatever */;
-
That is what I thought might have caused it, but then I get a redeclaration error.
\Player.cpp(16) : error C2655: 'Player::up' : definition or redeclaration illegal in current scope
1> c:\users\nds\documents\visual studio 2008\projects\firelizards\firelizards\Player.h(18) : see declaration of 'Player::up'
1>.\Player.cpp(16) : error C2086: 'bool Player::up' : redefinition
Then I thought, maybe it is because I wrote bool again, so I removed bool and only used Player::(whatever). That caused the compiler to complain and give the same error as originally, unresolved external symbol.
I know I can fix it by rewriting it as non.static, but I would rather fix this and learn from it.
-
Can you show a complete and minimal source code reproducing this error?
-
The header where I defined the class and its variables.
#ifndef PLAYER_H
#define PLAYER_H
#include "Window.h"
#include "Enemy.h"
class Player
{
public:
Player();
sf::Image Image;
sf::Sprite Sprite;
int XCord();
int YCord();
static bool up;
static bool down;
static bool left;
static bool right;
static bool shoot;
static int SpeedMultiplier;
private:
int PosX;
int PosY;
};
int PlayerMovement();
#endif
The cpp file with only the code part causing trouble:
#include "Player.h"
#include "Window.h"
Player::Player()
{
Image.LoadFromFile("Animal.tga");
Image.CreateMaskFromColor(sf::Color(255,0,255),0);
Sprite.SetImage(Image);
Sprite.SetCenter(10.f, 10.f);
}
int PlayerMovement()
{
///////////////////////////////////////////////////////
sf::Event KeyPress;
Player::up = false;
Player::down = false;
Player::left = false;
Player::right = false;
Player::shoot = false;
Player::SpeedMultiplier = 1;
////////////////////////////////////////////////////////
if (KeyPress.Type == sf::Event::KeyPressed)
{
switch (KeyPress.Key.Code)
{
case sf::Key::Up:
Player::up = true;
break;
case sf::Key::Down:
Player::down = true;
break;
case sf::Key::Left:
Player::left = true;
break;
case sf::Key::Right:
Player::right = true;
break;
case sf::Key::LShift:
Player::SpeedMultiplier = 3;
case sf::Key::Space:
Player::shoot = true;
default:
break;
}
}
if (KeyPress.Type == sf::Event::KeyReleased)
{
switch (KeyPress.Key.Code)
{
case sf::Key::Up:
Player::up = false;
break;
case sf::Key::Down:
Player::down = false;
break;
case sf::Key::Left:
Player::left = false;
break;
case sf::Key::Right:
Player::right = false;
break;
case sf::Key::LShift:
Player::SpeedMultiplier = 1;
default:
break;
}
}
}
The problem lies within the code between the //// lines. The linker is what is having trouble.
Can it be because of using the Player::(something) outside the constructor??
NOTES:
Think();
Draw();
SetPos();
Not made those yet, because I want the class to compile and exist before I make it think and do stuff.
-
In this code, the static members are not defined. Where did you put the piece of code that I showed you first?
-
In this code, the static members are not defined. Where did you put the piece of code that I showed you first?
In the problem area. Whithin the //// lines. I tried to replace it and just add it. Both times I got a redefinition error.
-
You forgot the type (bool, int) and you must put these lines in the global scope, outside a function.
Man... Google has 604000 pages that talk about "static members initialization in C++", they explain it very clearly, so you should read more of them to understand what you must do, rather than guessing what code to write.
I don't mean to be rude, just trying to help. Because if you write code that you don't understand, you'll be back next week with the same kind of problem.
-
You forgot the type (bool, int) and you must put these lines in the global scope, outside a function.
Man... Google has 604000 pages that talk about "static members initialization in C++", they explain it very clearly, so you should read more of them to understand what you must do, rather than guessing what code to write.
I don't mean to be rude, just trying to help. Because if you write code that you don't understand, you'll be back next week with the same kind of problem.
I feel like an idiot now. Never hit me to make them global... Thank you. And I will retry reading up on it. Also, I wouldnt consider that to be rude, I consider it effective guidance.