SFML community forums

Help => General => Topic started by: GroundZero on July 02, 2012, 06:34:30 pm

Title: window not declared, unable to display
Post by: GroundZero on July 02, 2012, 06:34:30 pm
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);

Code: [Select]
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
Title: Re: window not declared, unable to display
Post by: eXpl0it3r on July 02, 2012, 06:45:09 pm
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...
Title: Re: window not declared, unable to display
Post by: GroundZero on July 02, 2012, 06:52:48 pm
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 ;)
Title: Re: window not declared, unable to display
Post by: eXpl0it3r on July 02, 2012, 06:58:40 pm
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...
Title: Re: window not declared, unable to display
Post by: mateandmetal on July 03, 2012, 06:15:38 am
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);
    }

}
 
Title: Re: window not declared, unable to display
Post by: GroundZero on July 03, 2012, 02:30:12 pm
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