Reputation: 309
I am trying to create a game with c++ and SMFL 2.0 and i cant get pass this error and it's driving me crazy. I have been reading around the internet and it seems like it can be caused because of forgotten includes, but I still cant see where I have gone wrong. I have included the SMFL 2.0 library in the project properties section under c++ -> general -> additional include directories and under linker -> general -> additional library directories.
I'm completely blank and this is the error message i get:
1>------ Build started: Project: Pang, Configuration: Debug Win32 ------
1> Game.cpp
1> Generating Code...
1> Skipping... (no relevant changes detected)
1> Pang.cpp
1>Game.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
1>Game.obj : error LNK2001: unresolved external symbol "private: static class PlayerPaddle Game::_player1" (?_player1@Game@@0VPlayerPaddle@@A)
1>C:\Users\Alexander\Desktop\C++\Projects\Pang\Debug\Pang.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Microsoft Visual C++ doesnt show any syntax grammar errors with red underline when im looking around the code so it looks like the syntax is ok. Here are the relevant lines of code:
I have most of my general includes here:
stdafx.h
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <map>
#include <iostream>
#include <cassert>
#include <list>
VisibleGameObject.h
#pragma once
class VisibleGameObject {
public:
VisibleGameObject();
virtual ~VisibleGameObject();
virtual void Load(std::string filename);
virtual void Draw(sf::RenderWindow &window);
virtual void SetPosition(float x, float y);
private:
sf::Sprite _sprite;
sf::Texture _image;
std::string _filename;
bool _isLoaded;
};
VisibleGameObject.cpp
#include "stdafx.h"
#include "VisibleGameObject.h"
VisibleGameObject::VisibleGameObject() {
_isLoaded = false;
}
VisibleGameObject::~VisibleGameObject() {
}
void VisibleGameObject::Load(std::string filename) {
if (_image.loadFromFile(filename) == false) {
_filename = "";
_isLoaded = false;
}
else {
_filename = filename;
_sprite.setTexture(_image);
}
}
void VisibleGameObject::Draw(sf::RenderWindow &renderWindow) {
if (_isLoaded) {
renderWindow.draw(_sprite);
}
}
void VisibleGameObject::SetPosition(float x, float y) {
if (_isLoaded) {
_sprite.setPosition(x,y);
}
}
This class helps me use the SMFL library to draw images on the rendered window.
PlayerPaddle.h
#pragma once
#include "VisibleGameObject.h"
class PlayerPaddle : public VisibleGameObject {
public:
PlayerPaddle();
~PlayerPaddle();
};
PlayerPaddle.cpp
#include "stdafx.h"
#include "VisibleGameObject.h"
#include "PlayerPaddle.h"
PlayerPaddle::PlayerPaddle() {
}
PlayerPaddle::~PlayerPaddle() {
}
Game.h
#pragma once
#include "PlayerPaddle.h"
class Game {
public:
static void Start();
private:
static bool IsExiting();
static void GameLoop();
static void ShowSplashScreen();
static void ShowMenu();
enum GameState { Uninitialized, ShowingSplash, Paused, ShowingMenu, Playing, Exiting };
static GameState _gameState;
static sf::RenderWindow _mainWindow;
static PlayerPaddle _player1;
};
Game.cpp
#include "stdafx.h"
#include "Game.h"
#include "SplashScreen.h"
#include "MainMenu.h"
void Game::Start(void) {
if(_gameState != Uninitialized) {
return;
}
_mainWindow.create(sf::VideoMode(1024,768,32),"Pang!");
//_player1.Load("images/paddle.png");
//_player1.SetPosition((1024/2)-45, 700);
_gameState = Game::ShowingSplash;
while(!IsExiting()) {
GameLoop();
}
_mainWindow.close();
}
bool Game::IsExiting() {
if(_gameState == Game::Exiting) {
return true;
}
else {
return false;
}
}
void Game::GameLoop() {
switch(_gameState) {
case Game::ShowingMenu: {
ShowMenu();
break;
}
case Game::ShowingSplash: {
ShowSplashScreen();
break;
}
case Game::Playing: {
sf::Event currentEvent;
while (_mainWindow.pollEvent(currentEvent)) {
_mainWindow.clear(sf::Color(0,0,0));
//_player1.Draw(_mainWindow);
_mainWindow.display();
if (currentEvent.type == sf::Event::Closed) {
_gameState = Game::Exiting;
}
if (currentEvent.type == sf::Event::KeyPressed) {
return;
if(currentEvent.key.code == sf::Keyboard::Escape) {
ShowMenu();
}
}
}
break;
}
}
}
void Game::ShowSplashScreen() {
SplashScreen splashScreen;
splashScreen.Show(_mainWindow);
_gameState = Game::ShowingMenu;
}
void Game::ShowMenu() {
MainMenu mainMenu;
MainMenu::MenuResult result = mainMenu.Show(_mainWindow);
switch(result) {
case MainMenu::Exit: {
_gameState = Game::Exiting;
break;
}
case MainMenu::Play: {
_gameState = Game::Playing;
break;
}
}
}
Game::GameState Game::_gameState = Uninitialized;
sf::RenderWindow Game::_mainWindow;
This code compiles and runs ONLY when those 3 lines of codes starting with _player1 in Game.cpp are commented out. When not commented out i get this LNK2001 error and I just cant get passed this and it is quite frustrating.
Would be nice if someone had input on what could be wrong here.
Best of regards, Alexander
Upvotes: 0
Views: 2999
Reputation: 492
1) Try inheriting publicily PlayerPaddle class to Game class.It works. Example
class Game:public PlayerPaddle
2) or you can use composition.Use a pointer or static pointer to PlayerPaddle in Game. Use
static PlayerPaddle* _player1;
It should work.
Upvotes: 0
Reputation: 409432
You properly define the static member variables _gameState
and _mainWindow
, but not _player1
.
Upvotes: 0
Reputation: 24956
Your game.cpp misses a definition of Game::_player1:
PlayerPaddle Game::_player1;
Upvotes: 4