Globalny dostęp do okna SFML.

0

Witam!
Mam pytanie dotyczące dostępu do okna w SFML, chciałbym uniknąć używania zmiennych globalnych i przekazywanie zmiennej okna przez argumenty funkcji. Czy pytanie jest jakiś dobry sprawdzony sposób na zapewnienie dostępu do tej zmiennej? I paru innych rzeczy które mi ułatwią znacznie programowanie w SFML.
Czytałem coś o singletonie, ale myślę że to jest przerost formy nad treścią w przypadku prostego Tower Defense.

0

Cześć. Sam jestem właśnie w procesie tworzenia tej samej gry co Ty w SFML.
Ja mam w swoim kodzie kilka klas przyjmujących argument sf::RenderWindow & w metodzie draw(sf::RenderWindow &window).
Rzecz w tym, że jeżeli chcesz narysować jakiś obiekt możesz dziedziczyć w klasie tego obiektu po sf::Drawable i implementować co ma być rysowane w w tym obiekcie dzięki czemu nie musisz przekazywać do tej klasy sf::RenderWindow & tylko możesz z poziomu wyżej rysować np.

 class tower :public sf::Drawable
{
  sf::Sprite sprite;
  sf::RectangleShape shape;
  bullet bulletor;  //klasa bullet dziedziczy po sf::Drawable i też ma zaimplementowane co ma być rysowane w niej.

 public:
  void draw(sf::RenderTarget & target, sf::RenderStates states) const;  //nadpisywana metoda wirtualna
  { 
     target.draw(sprite);
     target.draw(shape);
     target.draw(bulletor);
};

W tym momencie możesz wykonywać metodę window.draw(ObiektKlasyTower).

0

Właśnie chciałem tego uniknąć, korzystam z tej metody i mi to nie odpowiada.

Przekazywanie obiektu okna do wszystkiego przez referencje jest dość irytujące.

0

Nie wiem czy to eleganckie rozwiązanie, ale jak masz na przykład klasę od GUI, to możesz jej przekazać referencję do okna a potem pisać tylko gui.draw()

0

Właśnie nie wiem też czy jest to eleganckie i dlatego poszukuję lepszego jeżeli takie jest.

1

Popatrz w ur::{...player, ...flower}, nie masz tam żadnego przekazywania okna - jawnie, ofc. Wystarczy to odpowiednio ukryć.

http://ideone.com/X0of5s

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct events {};
struct image {};

struct render_target {
	void draw(image const &image, int x, int y) {}
};


struct drawable {
	virtual void draw(render_target &target) const = 0;
	virtual ~drawable() = default;
};

struct updatable {
	virtual void update(int delta_time) = 0;
	virtual ~updatable() = default;
};

struct events_consumer {
	virtual void consume(events const &events) = 0;
	virtual ~events_consumer() = default;
};



namespace scaffolding {
	struct entity: drawable, updatable, events_consumer {
		int x, y;
		image img;
		
		entity(image img, int x, int y): img(img), x(x), y(y){}
		
		virtual void draw(render_target &target) const override {
			target.draw(img, x, y);
		}
		
		virtual void consume(events const &evts) override {}
		
		virtual void update(int dt) override {}
	};
	
	using entities = std::vector<entity>;
	
	struct game_skeleton: drawable, updatable, events_consumer {
		entities entities_container;
		
		bool is_running() const {
			return false; //normalny u'd like it to be this.is_running variable
		}
		
		virtual void update(int dt) override {
			for(auto &&e: get_entities()) {
				e.update(dt);
			}
		}
		
		virtual void draw(render_target &target) const override {
			for(auto &&e: get_entities()) {
				e.draw(target);
			}
		}
		
		virtual void consume(events const &evts) {
			for(auto &&e: get_entities()) {
				e.consume(evts);
			}
		}
		
		entities &get_entities() { return entities_container; }
		entities const &get_entities() const { return entities_container; }
		
		void register_entity(entity &&e, std::string const &id) {}
		entity &get_entity(std::string const &id) {}
		entity const &get_entity(std::string const &id) const {}
		void unregister_entity(std::string const &id) {}
	};
	
	struct game_runner {
		game_skeleton &game;
		render_target &target;
		
		int fetch_dt() {
			return {};
		}
		
		events fetch_events() {
			return {};
		}
		
		void run() {
			while(game.is_running()) {
				stream_events();
				stream_time();
			}
		}
		
		void stream_events() {
			game.consume(fetch_events());
		}
		
		void stream_time() {
			game.update(fetch_dt());
			game.draw(target);
		}
	};
}

namespace ur {
	image load_img(std::string const &) { return {}; }
	
	struct flower_entity: scaffolding::entity {
		flower_entity(int x, int y): entity(load_img("flower.png"), x, y) {}
	};
	
	struct fancy_player_entity: scaffolding::entity {
		fancy_player_entity(int x, int y): entity(load_img("sausage.png"), x, y) {}
		
		virtual void update(int dt) override {
			//apply some kind of physics mb?
		}
		
		virtual void consume(events const &) override {
			//mb handle the keyboard or smtg
		}
	};
	
	struct game: scaffolding::game_skeleton {
		game() {
			register_entity(flower_entity(5, 5), "flower-1");
			register_entity(fancy_player_entity(10, 10), "player");
			register_entity(flower_entity(5, 6), "flower-2");
		}
	};
}

int main() {
	auto target = render_target {};
	auto game = ur::game {};
	scaffolding::game_runner {game, target}.run();
	return 0;
}
0

Czegoś takiego właśnie szukałem! Dziękuje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1