Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML] Przekazywanie RenderWindow, tworzenie nowego okna

Ostatnio zmodyfikowano 2015-02-21 10:57
Autor Wiadomość
virnik
Temat założony przez niniejszego użytkownika
[SFML] Przekazywanie RenderWindow, tworzenie nowego okna
» 2015-02-20 16:28:42
Cześć
Piszę szkielet gry w SFML'u i zaciąłem się w jednym miejscu. Generuje sobie okno "menu" następnie po kliknięciu "Play" wywołuję funkcje z RenderWindow jako argument i chcę rysować okno gry jednak nic się nie pokazuje a zużycie CPU wzrasta do 50%...

C/C++
#include "Game.h"

#include <SFML\Graphics.hpp>
#include <string>
#include <iostream>
#include <windows.h>
#include <Engine.h>

Game::Game()
{
    state = END;
   
    if( !font.loadFromFile( "data/Mecha.ttf" ) )
    {
        MessageBox( NULL, "Font not found!", "ERROR", NULL );
        return;
    }
   
    state = MENU;
}

Game::~Game()
{
    //dtor
}

void Game::runGame()
{
    while( state != END )
    {
        switch( state )
        {
        case MENU:
            menu();
            break;
        case GAME:
            Engine engine();
            state = MENU;
            break;
        }
    }
}

void Game::menu()
{
    Text title( "Coś jakaś coś", font, 80 );
    title.setStyle( Text::Bold );
   
    title.setPosition( 1280 / 2 - title.getGlobalBounds().width / 2, 20 );
   
    const int ile = 2;
    RenderWindow window( sf::VideoMode( 1280, 800, 32 ), "", Style::None );
   
    Text tekst[ ile ];
   
    string str[] = { "Play", "Exit" };
    for( int i = 0; i < ile; i++ )
    {
        tekst[ i ].setFont( font );
        tekst[ i ].setCharacterSize( 65 );
       
        tekst[ i ].setString( str[ i ] );
        tekst[ i ].setPosition( 1280 / 2 - tekst[ i ].getGlobalBounds().width / 2, 250 + i * 120 );
    }
   
    while( state == MENU )
    {
        Vector2f mouse( Mouse::getPosition( window ) );
        Event event;
       
        while( window.pollEvent( event ) )
        {
            //Wciœniêcie ESC lub przycisk X
            if( event.type == Event::Closed || event.type == Event::KeyPressed &&
            event.key.code == Keyboard::Escape )
                 state = END;
           
            //klikniêcie EXIT
            else if( tekst[ 1 ].getGlobalBounds().contains( mouse ) &&
            event.type == Event::MouseButtonReleased && event.key.code == Mouse::Left )
            {
                state = END;
            }
            else if( tekst[ 0 ].getGlobalBounds().contains( mouse ) &&
            event.type == Event::MouseButtonReleased && event.key.code == Mouse::Left )
            {
                state = GAME;
            }
        }
        for( int i = 0; i < ile; i++ )
        if( tekst[ i ].getGlobalBounds().contains( mouse ) )
             tekst[ i ].setColor( Color::Cyan );
        else tekst[ i ].setColor( Color::White );
       
        window.clear();
       
        window.draw( title );
        for( int i = 0; i < ile; i++ )
             window.draw( tekst[ i ] );
       
        window.display();
    }
}

C/C++
#include "Engine.h"
#include <SFML\Graphics.hpp>
//#include <Event.hpp
using namespace sf;
Engine::Engine( sf::RenderWindow & win )
{
    runEngine( win );
}

Engine::~Engine()
{
    //dtor
}

void Engine::runEngine( sf::RenderWindow & window )
{
    bool menu = false;
   
    while( !menu )
    {
        Event event;
        sf::Vector2f mysz( Mouse::getPosition( window ) );
       
        while( window.pollEvent( event ) )
        {
            if( event.type == Event::KeyReleased && event.key.code == Keyboard::Escape )
                 menu = true;
           
            if( event.type == Event::KeyPressed && event.key.code == Keyboard::W )
            {
               
            }
           
            else if( event.type == Event::KeyReleased )
            {
                if( event.key.code == Keyboard::W )
                    ;
               
            }
        }
       
       
        window.clear();
       
        window.display();
    }
}
P-126894
Monika90
» 2015-02-20 16:39:39

C/C++
case GAME:
Engine engine();
state = MENU;
break;
Engine engine(); nie tworzy obiektu lecz deklaruje funkcję.
P-126895
virnik
Temat założony przez niniejszego użytkownika
» 2015-02-20 16:48:40
C/C++
Engine engine( window );
engine.runEngine( window );

C/C++
Engine * engine = new Engine( window );
engine->runEngine( window );

Nic nie zmienia. Nie wiem, nie myślę już dzisiaj po 16h bez snu.
Przesiadka z Javy była chyba złym pomysłem.

Co robię źle? Nie potrafię tego zauważyć a to pewnie banał ;/
P-126896
Lora
» 2015-02-20 20:45:46
Po pierwsze wywal funkcję runEngine z konstruktora Engine, skoro uruchamiasz ją jeszcze raz po skonstruowaniu obiektu. Po drugie dlaczego tworzysz zmienną window w funkcji Game::menu, skoro engine włączasz w funkcji Game::runGame. Stwórz tę zmienną jako pole klasy Game.
P-126906
virnik
Temat założony przez niniejszego użytkownika
» 2015-02-20 22:51:38
Wiem, wiem... To było tak tylko, żeby sprawdzić wszystkie możliwości.
Mam pole window w Game.
Tworzę je w Game::menu żeby je wyświetlić a potem chce je przekazać dalej ale to nie wychodzi.
W javie zrobiłbym to tak:
- zadeklarował pole RenderWindow window w klasie Game (zrobione);
- w menu window = new RenderWindow(sf::VideoMode(1280, 800, 32),"",Style::None);

No ale w C++ tak to nie działa ;D
Czego nie zauważam?

@EDIT

Ogarnięte:

C/C++
#ifndef GAME_H
#define GAME_H
#include <SFML\Graphics.hpp>
#include <string>

using namespace std;
using namespace sf;


class Game
{
public:
    void runGame();
    Game();
    ~Game();
protected:
    enum GameState { MENU, GAME, GAME_OVER, END };
    GameState state;
private:
    Font font;
    RenderWindow window;
    void menu();
};

#endif // GAME_H

C/C++
#include "Game.h"

#include <SFML\Graphics.hpp>
#include <string>
#include <iostream>
#include <windows.h>
#include <Engine.h>


Game::Game()
{
    ContextSettings settings;
    settings.antialiasingLevel = 8;
   
    window.create( VideoMode( 1280, 720 ), "True Life", Style::None,
    settings );
   
    state = END;
    window.setFramerateLimit( 100 );
   
    if( !font.loadFromFile( "data/Mecha.ttf" ) )
    {
        MessageBox( NULL, "Font not found!", "ERROR", NULL );
        return;
    }
   
    state = MENU;
}

Game::~Game()
{
    //dtor
}

void Game::runGame()
{
    while( state != END )
    {
        switch( state )
        {
        case MENU:
            menu();
            break;
        case GAME:
            Engine engine( window );
            engine.runEngine();
            state = MENU;
            break;
        }
    }
}

void Game::menu()
{
    Text title( "True Life", font, 80 );
    title.setStyle( Text::Bold );
   
    title.setPosition( 1280 / 2 - title.getGlobalBounds().width / 2, 20 );
   
    const int ile = 2;
   
    Text tekst[ ile ];
   
    string str[] = { "Play", "Exit" };
    for( int i = 0; i < ile; i++ )
    {
        tekst[ i ].setFont( font );
        tekst[ i ].setCharacterSize( 65 );
       
        tekst[ i ].setString( str[ i ] );
        tekst[ i ].setPosition( 1280 / 2 - tekst[ i ].getGlobalBounds().width / 2, 250 + i * 120 );
    }
   
    while( state == MENU )
    {
        Vector2f mouse( Mouse::getPosition( window ) );
        Event event;
       
        while( window.pollEvent( event ) )
        {
            //Wciœniêcie ESC lub przycisk X
            if( event.type == Event::Closed || event.type == Event::KeyPressed &&
            event.key.code == Keyboard::Escape )
                 state = END;
           
            //klikniêcie EXIT
            else if( tekst[ 1 ].getGlobalBounds().contains( mouse ) &&
            event.type == Event::MouseButtonReleased && event.key.code == Mouse::Left )
            {
                state = END;
            }
            else if( tekst[ 0 ].getGlobalBounds().contains( mouse ) &&
            event.type == Event::MouseButtonReleased && event.key.code == Mouse::Left )
            {
                state = GAME;
            }
        }
        for( int i = 0; i < ile; i++ )
        if( tekst[ i ].getGlobalBounds().contains( mouse ) )
             tekst[ i ].setColor( Color::Cyan );
        else tekst[ i ].setColor( Color::White );
       
        window.clear();
       
        window.draw( title );
        for( int i = 0; i < ile; i++ )
             window.draw( tekst[ i ] );
       
        window.display();
    }
}

C/C++
#ifndef ENGINE_H
#define ENGINE_H
#include <SFML/Graphics.hpp>

class Engine
{
public:
    Engine( sf::RenderWindow & win );
    ~Engine();
    void runEngine();
protected:
private:
    sf::RenderWindow * window;
};

#endif // ENGINE_H

C/C++
#include "Engine.h"
#include <SFML\Graphics.hpp>
#include <iostream>
//#include <Event.hpp
using namespace sf;
Engine::Engine( sf::RenderWindow & win )
{
    window = & win;
}

Engine::~Engine()
{
    //dtor
}

void Engine::runEngine()
{
    bool menu = false;
   
    while( !menu )
    {
        Event event;
        sf::Vector2f mysz( Mouse::getPosition() );
       
        while( window->pollEvent( event ) )
        {
            if( event.type == Event::KeyReleased && event.key.code == Keyboard::Escape )
                 menu = true;
           
            if( event.type == Event::KeyPressed && event.key.code == Keyboard::W )
            {
               
            }
           
            else if( event.type == Event::KeyReleased )
            {
                if( event.key.code == Keyboard::W )
                    ;
               
            }
        }
       
       
        window->clear();
       
        window->display();
    }
}
P-126923
Lora
» 2015-02-20 23:12:34
Skoro masz pole window w klasie Game to twórz je w konstruktorze za pomocą listy inicjalizacyjnej:
C/C++
Game::Game()
    : window( sf::VideoMode( 1280, 800, 32 ), "", Style::None )
{
    state = END;
   
    if( !font.loadFromFile( "data/Mecha.ttf" ) )
    {
        MessageBox( NULL, "Font not found!", "ERROR", NULL );
        return;
    }
   
    state = MENU;
}

Wywal tę linijkę
RenderWindow window( sf::VideoMode( 1280, 800, 32 ), "", Style::None );
 z metody Game::menu.

A Game::runGame() zrób tak:
C/C++
void Game::runGame()
{
    while( state != END )
    {
        switch( state )
        {
        case MENU:
            menu();
            break;
        case GAME:
            Engine engine;
            engine.runEngine( window );
            state = MENU;
            break;
        }
    }
}
I wywal wywołanie metody runEngine z konstruktora Engine razem z argumentem RenderWindow. Najlepiej w ogóle skasuj konstruktor i pozostaw domyślny, bo i tak nic do tej klasy nie przekazujesz.

EDIT:
Ach ok. Zedytowałeś w tej samej chwili, w której wysłałem komentarz.
P-126925
virnik
Temat założony przez niniejszego użytkownika
» 2015-02-20 23:18:57
Dzięki za pomoc ;)
Coś C++ nie jest moją mocną stroną. Po javie te wskaźniki i dwie możliwości ( . -> ) dość mocno komplikują sprawę ;D

Po zmianie kodu na Twoją propozycję dostaję:
    NonCopyable(const NonCopyable&);
C:\SFML-2.2\include\SFML\System\NonCopyable.hpp|67|error: 'sf::NonCopyable::NonCopyable(const sf::NonCopyable&)' is private|

Grr, dzikie to ;D Może z z JSFML będzie łatwiej, ale nie ma być łatwiej tylko mam ogarnąć ;D
P-126926
Lora
» 2015-02-20 23:26:24
Chyba gdzieś używasz operatora przypisania do zmiennej RenderWindow albo próbujesz ją kopiować, a ta dziedziczy po klasie NonCopyable, która uniemożliwia te operacje. Tylko nie widzę właśnie gdzie. Ale skoro ten twój sposób działa to dobrze.
P-126927
« 1 » 2
  Strona 1 z 2 Następna strona