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%... #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() { }
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 ) ) { if( event.type == Event::Closed || event.type == Event::KeyPressed && event.key.code == Keyboard::Escape ) state = END; 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(); } }
#include "Engine.h" #include <SFML\Graphics.hpp>
using namespace sf; Engine::Engine( sf::RenderWindow & win ) { runEngine( win ); }
Engine::~Engine() { }
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(); } }
|
|
Monika90 |
» 2015-02-20 16:39:39
case GAME: Engine engine(); state = MENU; break;
| Engine engine(); nie tworzy obiektu lecz deklaruje funkcję. |
|
virnik Temat założony przez niniejszego użytkownika |
» 2015-02-20 16:48:40 Engine engine( window ); engine.runEngine( window );
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ł ;/ |
|
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. |
|
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: #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
#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() { }
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 ) ) { if( event.type == Event::Closed || event.type == Event::KeyPressed && event.key.code == Keyboard::Escape ) state = END; 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(); } }
#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
#include "Engine.h" #include <SFML\Graphics.hpp> #include <iostream>
using namespace sf; Engine::Engine( sf::RenderWindow & win ) { window = & win; }
Engine::~Engine() { }
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(); } }
|
|
Lora |
» 2015-02-20 23:12:34 Skoro masz pole window w klasie Game to twórz je w konstruktorze za pomocą listy inicjalizacyjnej: 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: 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. |
|
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 |
|
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. |
|
« 1 » 2 |