SFML - LNK2001 game from scratch - c++

I've been lurking around these forums from time to time when I needed help throughout my university programming classes, but recently I've been having trouble, and couldn't find the answer anywhere.
I started learning to program games for a bigger project of mine through:
http://www.gamefromscratch.com/page/Game-From-Scratch-CPP-Edition-Part-3.aspx
When i compile my code, I get
1>------ Build started: Project: PANG, Configuration: Debug Win32 ------
1> Game.cpp
1>MainMenu.obj : error LNK2001: unresolved external symbol "public: static class sf::RenderStates const sf::RenderStates::Default" (?Default#RenderStates#sf##2V12#B)
1>SplashScreen.obj : error LNK2001: unresolved external symbol "public: static class sf::RenderStates const sf::RenderStates::Default" (?Default#RenderStates#sf##2V12#B)
1>G:\My Documents\Visual Studio 2012\Projects\PANG\Debug\PANG.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The thing I do not get is that I DO define SplashScreen and MainMenu in my Game.cpp...
Game.h
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
class Game
{
public:
static void Start();
static sf::RenderWindow& GetWindow();
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;
};
Game.cpp
#include "stdafx.h"
#include "Game.h"
#include "MainMenu.h"
#include "SplashScreen.h"
void Game::Start(void)
{
if(_gameState != Uninitialized)
return;
_mainWindow.create(sf::VideoMode(1024,768,32),"Pang!");
_gameState= Game::ShowingSplash;
while(!isExiting())
{
GameLoop();
}
_mainWindow.close();
}
bool Game::isExiting()
{
if(_gameState == Game::Exiting)
return true;
else
return false;
}
sf::RenderWindow& Game::GetWindow()
{
return _mainWindow;
}
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));
_mainWindow.display();
if(currentEvent.type == sf::Event::Closed)
{
_gameState = Game::Exiting;
}
if(currentEvent.type == sf::Event::KeyPressed)
{
// if(currentEvent.key.code == sf::Key::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;
SplashScreen.cpp
#include "StdAfx.h"
#include "SplashScreen.h"
void SplashScreen::Show(sf::RenderWindow & renderWindow)
{
sf::Texture texture;
if(texture.loadFromFile("images/SplashScreen.png") != true)
{
return;
}
sf::Sprite sprite(texture);
renderWindow.draw(sprite);
renderWindow.display();
sf::Event event;
while(true)
{
while(renderWindow.pollEvent(event))
{
if(event.type == sf::Event::EventType::KeyPressed
|| event.type == sf::Event::EventType::MouseButtonPressed
|| event.type == sf::Event::EventType::Closed)
{
return;
}
}
}
}
SplashScreen.h
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
class SplashScreen
{
public:
void Show(sf::RenderWindow& window);
};
MainMenu.cpp
#include "stdafx.h"
#include "MainMenu.h"
MainMenu::MenuResult MainMenu::Show(sf::RenderWindow& window)
{
sf::Texture texture;
texture.loadFromFile("images/MainMenu.png");
sf::Sprite sprite(texture);
MenuItem playButton;
playButton.rect.top = 145;
playButton.rect.height = 380;
playButton.rect.left = 0;
playButton.rect.width = 1023;
playButton.action = Play;
MenuItem exitButton;
exitButton.rect.top = 383;
exitButton.rect.left = 0;
exitButton.rect.width = 1023;
exitButton.rect.height = 560;
exitButton.action = Exit;
_menuItems.push_back(playButton);
_menuItems.push_back(exitButton);
window.draw(sprite);
window.display();
return GetMenuResponse(window);
}
MainMenu::MenuResult MainMenu::HandleClick(int x,int y)
{
std::list<MenuItem>::iterator it;
for (it = _menuItems.begin(); it != _menuItems.end(); it++)
{
sf::Rect<int>menuItemRect = (*it).rect;
if( x > menuItemRect.left
&& x < menuItemRect.left + menuItemRect.width
&& y > menuItemRect.top
&& y < menuItemRect.height + menuItemRect.top)
{
return (*it).action;
}
}
return Nothing;
}
MainMenu::MenuResult MainMenu::GetMenuResponse(sf::RenderWindow& window)
{
sf::Event menuEvent;
while(true)
{
while(window.pollEvent(menuEvent))
{
if(menuEvent.type == sf::Event::MouseButtonPressed)
{
return HandleClick(menuEvent.mouseButton.x,menuEvent.mouseButton.y);
}
if (menuEvent.type == sf::Event:: Closed)
{
return Exit;
}
}
}
}
MainMenu.h
#pragma once
#include "SFML/Window.hpp"
#include "SFML/Graphics.hpp"
#include <list>
class MainMenu
{
public:
enum MenuResult {Nothing, Exit, Play};
struct MenuItem
{
public:
sf::Rect<int> rect;
MenuResult action;
};
MenuResult Show(sf::RenderWindow & window);
private:
MenuResult GetMenuResponse(sf::RenderWindow& window);
MenuResult HandleClick(int x, int y);
std::list<MenuItem> _menuItems;
};
Any help would be greatly appreciated, Thank You !

I have found the solution. I removed SFML_STATIC from the preprocessor in properties and it worked ! thanks Adriano for the help !

Related

SFML: Platforms disappearing after push_back()

New to C++, I'm trying to make "platforms" spawn every 2 seconds and go upwards. However, the platform disappears when a new Platform is pushed onto the platforms vector.
Platform.h:
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <vector>
class Platform
{
private:
sf::RectangleShape shape;
public:
Platform() = default;
Platform(const Platform& platform);
void updatePos();
sf::RectangleShape getShape() { return shape; }
};
Platform.cpp:
#include "Platform.h"
Platform::Platform(const Platform& platform)
{
shape.setSize(sf::Vector2f(300.f, 40.f));
shape.setPosition(1920.f / 2.f - shape.getSize().x / 2.f, 1080.f);
}
void Platform::updatePos()
{
shape.move(sf::Vector2f(0.f, -5.f));
}
Game.h:
#pragma once
#include "Platform.h"
#include <iostream>
class Game
{
private:
sf::RenderWindow window{ sf::VideoMode(1920, 1080), "Dodge the Spikes", sf::Style::Fullscreen };
std::vector<Platform> platforms;
bool gameOver{};
unsigned int platformTimer{};
public:
Game() = default;
void update();
void draw();
void run();
};
Game.cpp:
#include "Game.h"
void Game::update()
{
if (!gameOver)
{
//spawn platforms
platformTimer++;
if (platformTimer >= 120)
{
platforms.push_back(Platform{});
platformTimer = 0;
}
//update platforms
for (auto i{platforms.begin()}; i < platforms.end();)
{
i->updatePos();
i++;
}
}
}
void Game::draw()
{
for (auto i{ platforms.begin() }; i < platforms.end();)
{
window.draw(i->getShape());
i++;
}
}
void Game::run()
{
while (window.isOpen())
{
sf::Event evnt;
while (window.pollEvent(evnt))
{
if (evnt.type == sf::Event::Closed)
{
window.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
{
window.close();
}
}
this->update();
window.clear();
this->draw();
window.display();
}
}

Can't draw sf::RectangleShape s stored in vector (Tetris clone)

I am trying to storesf::RectangleShape's into thestd::vectorand then draw each of them into thesf::RenderWindow.
Single rectangle shape is representing 1x1 tetromino and i would like to store it into the vector each time it reaches the bottom of the window. Then I would like to reset the position of the current tetromino to the default position.
I think I'm not even to able store it correctly. Each time the tetromino reaches the bottom it gives me this error message:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Bellow please find my current code. I just started working on it and already got stuck.
Definitions.h
#pragma once
// Point structure
struct Point
{
int dim_x;
int dim_y;
};
// Field Dimensions
const int fieldRows = 10;
const int fieldColumns = 9;
const int pointSize = 50.f;
// For checkingEdges funntion within the Tetrnomino.h
enum Edge
{
leftEdge,
rightEdge,
noneEdge
};
Game.h
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "Definitions.h"
#include "Tetromino.h"
class Game
{
public:
Game();
~Game();
// Game starter
void run();
// Accessors
bool running();
private:
// Updating and rendering the game window
void update();
void render();
// Initialization
void initVariables();
void initWindow();
void initBacgroundMusic();
// Polling
void pollEvents();
// Window logic stuff
sf::RenderWindow* _window;
sf::Event _event;
void drawStack();
// Bacground Music
sf::Music _ost;
// Tetromino + Its logic
Tetromino _T;
sf::Time delayTime = sf::milliseconds(300);
sf::Clock clock;
};
Tetromino.h
#pragma once
#include <SFML/Graphics.hpp>
#include <vector>
#include "Definitions.h"
class Tetromino
{
public:
Tetromino();
~Tetromino();
// Initialization
void initTetromino();
// Tetromonino logic
void moveTetromino();
Edge checkEdges();
// Getters & Setters
sf::RectangleShape getTetromino();
sf::RectangleShape getStackPart(int part);
int getStackSize();
void setTetromino(sf::RectangleShape &t);
private:
// The current tetromino
sf::RectangleShape _tetromino;
std::vector<sf::RectangleShape> _stack;
};
Game.cpp
#include "Game.h"
//-----Consturcotrs and Destructors-----//
Game::Game()
{
//Basic Initialization
_T.initTetromino();
initVariables();
}
Game::~Game()
{
delete _window;
}
//-----Private Functions-----//
void Game::run()
{
update();
render();
}
bool Game::running()
{
return _window->isOpen();
}
void Game::update()
{
sf::Time elapsed = clock.getElapsedTime();
pollEvents();
if (elapsed >= delayTime)
{
_T.moveTetromino();
clock.restart();
}
}
void Game::render()
{
_window->clear(sf::Color::White);
_window->draw(_T.getTetromino());
drawStack();
_window->display();
}
void Game::initVariables()
{
_window = nullptr;
initWindow();
initBacgroundMusic();
}
void Game::initWindow()
{
_window = new sf::RenderWindow(sf::VideoMode(fieldColumns * pointSize, fieldRows * pointSize), "Tetris v0.2", sf::Style::Default);
_window->setVerticalSyncEnabled(true);
_window->setFramerateLimit(60);
}
void Game::initBacgroundMusic()
{
_ost.openFromFile("../QT_SFML_Tetris/Music.ogg");
_ost.play();
_ost.setLoop(true);
_ost.setVolume(50.f);
}
void Game::pollEvents()
{
while (_window->pollEvent(_event))
{
if (_event.type == sf::Event::Closed) {_window->close();}
if (_event.type == sf::Event::KeyPressed)
{
if (_event.key.code == sf::Keyboard::Escape){_window->close();}
if (_event.key.code == sf::Keyboard::Left && _T.checkEdges() != leftEdge)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x - pointSize, t.getPosition().y);
_T.setTetromino(t);
render();
}
if (_event.key.code == sf::Keyboard::Right && _T.checkEdges() != rightEdge)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x + pointSize, t.getPosition().y);
_T.setTetromino(t);
render();
}
if (_event.key.code == sf::Keyboard::Down)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x, t.getPosition().y+ pointSize);
_T.setTetromino(t);
render();
}
}
}
}
**void Game::drawStack()**
{
for (unsigned int i = _T.getStackSize(); i > 0; --i)
{
_window->draw(_T.getStackPart(i));
}
}
main.cpp
#include <Game.h>
int main()
{
Game game;
while (game.running())
{
game.run();
}
return 0;
}
Tetromino.cpp
#include "Tetromino.h"
//-----Consturcotrs and Destructors-----//
Tetromino::Tetromino()
{
}
Tetromino::~Tetromino()
{
}
//-----Public Functions-----//
void Tetromino::initTetromino()
{
_tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
_tetromino.setSize(sf::Vector2f(pointSize, pointSize));
_tetromino.setFillColor(sf::Color::Red);
}
void Tetromino::moveTetromino()
{
_tetromino.move(0.f, pointSize);
if (_tetromino.getPosition().y > fieldRows * pointSize - pointSize)
{
_stack.push_back(_tetromino);
_tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
}
}
Edge Tetromino::checkEdges()
{
if (_tetromino.getPosition().x == 0)
{
return leftEdge;
}
else if (_tetromino.getPosition().x == (fieldColumns * pointSize) - pointSize)
{
return rightEdge;
}
else return noneEdge;
}
sf::RectangleShape Tetromino::getTetromino()
{
return _tetromino;
}
sf::RectangleShape Tetromino::getStackPart(int part)
{
return _stack[part];
}
int Tetromino::getStackSize()
{
return _stack.size();
}
void Tetromino::setTetromino(sf::RectangleShape &t)
{
_tetromino = t;
}
I think the main issue could be within this line:
_stack.push_back(_tetromino);
In the drawStack() method you try to iterate backwards.
There is a reverse iterator doing this for you.
you have an off-by one error in your index calculation, which works only with an empty vector (exactly to prevent these errors you should use the iterator!)
You may want to read about iterators in C++ here is a small example.
According to your code it will look like (note that you need also a getStack()-method in Tetromino.hpp, returning the reference of the vector):
void Game::drawStack()
{
for (auto it = _T.getStack().rbegin(); it != _T.getStack().rend(); it++)
{
_window->draw(*it);
}
}
If you want to keep the index, I this is a fix:
void Game::drawStack()
{
for (int i = _T.getStackSize()-1; i >= 0; --i)
{
_window->draw(_T.getStackPart(i));
}
}

SFML VideoMode breaks application

Using SFML sf::VideoMode breaks my application, saying that "Singularity.exe has stopped working"
Specifically this line :
_mainWindow.create(sf::VideoMode(1024,768,32), "Singularity");
This line is what is causing the problem. When I remove it, the application works fine. Here is the whole code of the main class file:
#include "stdafx.h"
#include "Game.h"
void Game::Start(void)
{
if (_gameState != Uninitialized)
return;
_mainWindow.create(sf::VideoMode(1024,768,32), "Singularity");
_gameState = Game::Playing;
while (!IsExiting())
{
GameLoop();
}
_mainWindow.close();
}
bool Game::IsExiting()
{
if (_gameState == Game::Exiting)
return true;
else
return false;
}
void Game::GameLoop()
{
sf::Event currentEvent;
while (_mainWindow.pollEvent(currentEvent))
{
switch (_gameState)
{
case Game::Playing:
{
_mainWindow.clear(sf::Color(255, 0, 0));
_mainWindow.display();
if (currentEvent.type == sf::Event::Closed)
{
_gameState = Game::Exiting;
}
break;
}
}
}
}
Game::GameState Game::_gameState = Uninitialized;
sf::RenderWindow Game::_mainWindow;
Does anyone have any idea of what might be causing this or how to fix it? I am completely new to SFML, so I'm at a loss for what to do.
Thanks, Zuve

Error while linking SFML. LNK2001

i am creating a project using SFML. Everything worked fine up until now. I created a class called BufferHelper.cpp and then an error showed up.
I am working with:
Visual Studio Professional 2013
SFML 2.1
Windows 8.1
I have added all libaries
the 'sfml-lib.dll's for Release
and 'sfml-lib-d.dll's for Debug
Error log:
Error 1 error LNK2001: unresolved external symbol "public: class sf::SoundBuffer __thiscall BufferHelper::MergeBuffers(class sf::SoundBuffer,class sf::SoundBuffer)" (?MergeBuffers#BufferHelper##QAE?AVSoundBuffer#sf##V23#0#Z) C:\Users\Krisjanis\documents\visual studio 2013\Projects\BD_Test\BD_Test\main.obj BD_Test
Error 2 error LNK1120: 1 unresolved externals C:\Users\Krisjanis\documents\visual studio 2013\Projects\BD_Test\Release\BD_Test.exe BD_Test
Main.cpp
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <iostream>
#include "BufferHelper.h"
int main()
{
sf::SoundBufferRecorder recorder;
sf::SoundBufferRecorder recorder2;
sf::SoundBuffer buffer;
sf::SoundBuffer buffer2;
sf::Sound sound;
sf::Sound sound2;
int iTrackActive = 1;
bool bTrack1Active = true;
bool bTrack2Active = false;
sf::RenderWindow window(sf::VideoMode(1200, 800), "Loopify!");
//sf::RenderWindow window(sf::VideoMode(1200, 800), "Loopify!", sf::Style::Fullscreen);
sf::Texture texture;
texture.loadFromFile("images/a.png");
BufferHelper a;
sf::SoundBuffer finalbuffer = a.MergeBuffers(buffer, buffer2);
sf::Sprite sprite;
sprite.setTexture(texture);
bool recording = false;
if (!sf::SoundBufferRecorder::isAvailable())
{
std::cout << "Recorder not available";
}
else
{
std::cout << "GO AHEAD AND RECORD";
}
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Space && !recording)
{
recording = true;
recorder.start();
}
else if (event.key.code == sf::Keyboard::Space && recording)
{
recorder.stop();
recording = false;
if (iTrackActive == 1)
{
buffer = recorder.getBuffer();
sound.setBuffer(buffer);
sound.setLoop(true);
sound.play();
}
if (iTrackActive == 2)
{
buffer2 = recorder.getBuffer();
sound2.setBuffer(buffer);
sound2.setLoop(true);
sound2.play();
}
}
else if (event.key.code == sf::Keyboard::Num1)
{
iTrackActive = 1;
}
else if (event.key.code == sf::Keyboard::Num2)
{
iTrackActive = 2;
}
}
}
window.clear();
window.draw(sprite);
window.display();
}
return 0;
}
BufferHelper.cpp
#include <SFML/System.hpp>
#include <SFML/Audio.hpp>
#include "BufferHelper.h"
#include <iostream>
#include <vector>
BufferHelper::BufferHelper()
{
}
sf::SoundBuffer MergeBuffers(sf::SoundBuffer BufferOne, sf::SoundBuffer BufferTwo)
{
int iLength;
int iShortLength;
const sf::Int16* LongerSamples;
const sf::Int16* ShorterSamples;
if (BufferOne.getSampleCount() > BufferTwo.getSampleCount())
{
LongerSamples = BufferOne.getSamples();
ShorterSamples = BufferTwo.getSamples();
iLength = BufferOne.getSampleCount();
iShortLength = BufferTwo.getSampleCount();
}
else
{
LongerSamples = BufferTwo.getSamples();
ShorterSamples = BufferOne.getSamples();
iLength = BufferTwo.getSampleCount();
iShortLength = BufferOne.getSampleCount();
}
std::vector<sf::Int16> FinalSamplesVector;
FinalSamplesVector.reserve(iLength);
for (int i = 0; i < iLength; i++)
{
if (i < iShortLength)
{
double dSampleOne = (LongerSamples[i] + 32768.) / 65535.;
double dSampleTwo = (ShorterSamples[i] + 32768.) / 65535.;
double dResult = 0;
if (dSampleOne < 0.5 && dSampleTwo < 0.5)
{
dResult = 2 * dSampleOne * dSampleTwo;
}
else
{
dResult = 2 * (dSampleOne + dSampleTwo) - 2 * dSampleOne * dSampleTwo - 1;
}
FinalSamplesVector.push_back(static_cast<sf::Int16>(dResult * 65535. - 32768.));
}
else
{
FinalSamplesVector.push_back(LongerSamples[i]);
}
}
sf::SoundBuffer FinalBuffer;
FinalBuffer.loadFromSamples(&FinalSamplesVector[0], FinalSamplesVector.size(), 2, 44100);
return FinalBuffer;
}
BufferHelper::~BufferHelper()
{
}
BufferHelper.h
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
using namespace sf;
class BufferHelper
{
public:
BufferHelper();
sf::SoundBuffer MergeBuffers(sf::SoundBuffer, sf::SoundBuffer);
~BufferHelper();
};
I will be thankful to recieve any kind of feedback.
You did not declare the body of the function MergeBuffers().
This has nothing to do with SFML, just add
sf::SoundBuffer BufferHelper::MergeBuffers(sf::SoundBuffer, sf::SoundBuffer)
{
// some code
}
in your cpp file.
Edit : I realize you mistakenly re-copied your main.cpp file code. Please show the good code for BufferHelper.cpp

Can't get passed error LNK2001: unresolved external symbol, even if I seem to have included what is needed

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
Your game.cpp misses a definition of Game::_player1:
PlayerPaddle Game::_player1;
You properly define the static member variables _gameState and _mainWindow, but not _player1.
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.