-
Dear readers,
I am learning SFML, but after 2 days of struggeling I give up lol. Hopefully someone on the forums can help me out by telling me what I did wrong and -or edit my code a bit so I can see what I did wrong, and learn about the changes you made.
Anyways, the problem.
As you can see I start a level and everything runs fine (no errors so far). I just need to display all sprites using window.draw(spriteName);
startLevel.loadLevel();
But when executing my loop it says:
'window' was not declared in this scope
I tried to find out what I did wrong and -or how to solve this matter but untill now I was unable to find a solution. I hope someone can tell me what I did wrong and how to fix it, or even better, edit my current code so I can compare the two and see / learn what to do (which would be much easier for me to learn from).
Best regards
// QT
#include <QDebug>
#include <QString>
#include <QCryptographicHash>
#include <sstream>
#include <iostream>
#include <vector>
// SFML
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
// Custom headers
#include <verifyUser.h>
#include <loadLevel.h>
// set timers
sf::Clock Clock;
sf::Clock pressOnce;
sf::Clock nameTimer;
// development variables
std::string ROOT = "C:\\Users\\Angelo\\Desktop\\Projecten\\Game\\Game-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK__Debug\\debug\\";
int main()
{
// Create the main window
sf::RenderWindow window(sf::VideoMode(800, 600), "Game");
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(60);
// start a level
level startLevel(1);
// Start the game loop
while (window.isOpen())
{
// Process events
sf::Event event;
while (window.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
{
window.close();
}
}
// clock so every computer runs at the same speed
// sf::Time Time = Clock.getElapsedTime();
// float Elapsed = Time.asMilliseconds();
// if(Elapsed >= 1000){}
// Clear screen
window.clear();
// display level
startLevel.loadLevel();
// Update the window
window.display();
}
return 0;
}
// declaration of functions
level::level(int levelNr) : levelNr(levelNr), finished(false), nameDisplayed(false){}
void level::loadLevel(){
// set a vector with all needed sprites
std::vector<std::string> name;
name.push_back("background.png"); //
name.push_back("objects_1.png"); //
name.push_back("objects_2.png"); //
name.push_back("floor.png"); //
name.push_back("platform.png"); //
// loop through the sprites and add them to a vector sprite
std::vector<sf::Sprite> sprites;
for(std::vector<std::string>::iterator i = name.begin(); i != name.end(); i++)
{
sf::Texture texture;
texture.loadFromFile(ROOT + "levelLayout\\" + *i);
sf::Sprite sprite(texture);
sprites.push_back(sprite);
}
// loop through all the sprites and display them
for(std::vector<sf::Sprite>::iterator pos = sprites.begin(); pos != sprites.end(); pos++)
{
window.draw(*pos);
}
}
void level::loadNext(){
// load next level
levelNr++;
}
void level::displayName(){
// display level name
std::cout << "Level 1";
}
int verifyUser::returnValidation(){
QString tempPass = password.c_str();
QByteArray hash = QCryptographicHash::hash(tempPass.toUtf8(), QCryptographicHash::Sha1);
std::string tempFinal = tempPass.toStdString();
sf::Http http;
http.setHost("www.mysite.nl");
sf::Http::Request request("/klanten/Game/login.php?username=" + username + "&password=" + tempFinal);
sf::Http::Response responce = http.sendRequest(request);
sf::Http::Response::Status status = responce.getStatus();
if(status == sf::Http::Response::Ok)
{
std::string body = responce.getBody();
std::stringstream convert(body);
int x;
convert >> x;
switch(x)
{
case 1:
return 1; // succesfully authenticated
break;
case 2:
return 2; // unsuccesfully authenticated
break;
case 3:
return 3; // multiple accounts found error!
break;
case 4:
return 4; // account not activated
break;
case 5:
return 5; // account is banned
break;
default:
return 0;
}
}
else
{
return 0; // error request
}
}
Loadlevel header
#ifndef LOADLEVEL_H
#define LOADLEVEL_H
class level {
private:
int levelNr;
bool finished;
bool nameDisplayed;
public:
// default constructor
level( int levelNr );
// functions
void loadLevel(); // load level sprites
void loadNext(); // load next level
void displayName(); // display level name
};
#endif // LOADLEVEL_H
-
You're missing some basic C++ knowledge.
Try googling for 'scope' and/or take out a C++ book and read a bit more. ;)
The problem is, that the window gets declared in the main() function and now you're trying to acces that variable in the loadLevel(), this doesn't work since the loadLevel() has no idea what has happend in the main() function and thus has also no access to any of it's variables.
I strongly advice you to read a C++ from front to back, specially the class section should be looked at. ;)
E.g. the class definition should be placed in a .cpp file...
-
Thanks for your answer eXpl0it3r, I know about putting them in .cpp but this was easier for the time being ;)
I tought that since the function was INSIDE main() function, it was within it's scope lol... Ill try to figure out a way to fix it.
If someone can give me a example would be nice though ;)
-
Read a book! ;D
Okay here you go:
class foo
{
public:
foo(sf::RenderWindow& aWindow) :
mWindow(aWindow)
{}
bar()
{
mWindow.draw(mSprite);
}
private:
sf::RenderWindow& mWindow;
sf::Sprite mSprite;
};
int main()
{
sf::RenderWindow window(...);
foo myClass(window);
myClass.bar();
}
So your class holds a reference to the window.
It's a solution but not always appropriate...
-
You are creating and filling std::vector containers inside your load function. As soon as the function ends, your vectors are gone. Move this vectors declaration inside your level class, as private members.
And you are calling the load function every time in the main loop... wrong ;D
Create another method to display the level, this is the function you should call in the main loop
void level::draw (sf::RenderWindow &win) {
// loop through all the sprites and display them
for (std::vector<sf::Sprite>::const_iterator pos = sprites.begin(); pos != sprites.end(); ++pos)
{
win.draw (*pos);
}
}
-
Awesome answers guys, I will try to implement those things. Thank you very much :)
EDIT: Got it working now, you guys are awesome. Just 1 small question. It does display my sprites now but all sprites are white... just white squares!?
I am using .PNG files...
Any idea what could be wrong?
if(!texture.loadFromFile(ROOT + "levelLayout\\" + *i)){
std::cout << "FOUT" << std::endl;
} else {
std::cout << "LOAD: " << *i << std::endl;
}
Says everything was loaded succesfully, and the compiler dusnt give me any errors or what so ever.
Anyways, thanks so much for your help guys. I am ripping the code apart as we speak to learn every bit there is. Thanks again, and hopefully someone knows why my sprites are white ;)
I am searching into "As soon as the function ends, your vectors are gone." now, since that might be the problem I guess. But since I put them (now, didnt do that before) into my private section they should keep existing at all time untill the deconstructor is called upon right?
class level {
private:
int levelNr;
bool finished;
bool nameDisplayed;
std::vector<sf::Sprite> sprites;
public:
// default constructor
level( int levelNr );
// functions
void draw(sf::RenderWindow &win);
void loadLevel(); // load level sprites
void loadNext(); // load next level
};
void level::loadLevel(){
// set a vector with all needed sprites
std::vector<std::string> name;
// name.push_back("background.png");
// name.push_back("objects_1.png");
name.push_back("objects_2.png");
// name.push_back("floor.png");
// name.push_back("platform.png");
// loop through the sprites and add them to a vector sprite
for(std::vector<std::string>::iterator i = name.begin(); i != name.end(); i++)
{
sf::Texture texture;
///////////////////////////////////////////////////////////////
if(!texture.loadFromFile(ROOT + "levelLayout\\" + *i)){
std::cout << "FOUT" << std::endl;
} else {
std::cout << "LOAD: " << *i << std::endl;
}
///////////////////////////////////////////////////////////////
sf::Sprite sprite(texture);
sprite.setPosition(100, 200);
sprites.push_back(sprite);
}
}
Update Found out whats wrong, just as I have been told they dont exist long enough. Going to fix that now :D