• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak rozdzielić klasę na logikę i grafikę? | SFML

Object Storage Arubacloud
+2 głosów
248 wizyt
pytanie zadane 21 kwietnia 2015 w C i C++ przez Darth Perrak Początkujący (320 p.)
edycja 21 kwietnia 2015 przez Darth Perrak

Cześć wszystkim. Jestem w Trakcie przygotowywania prostej aplikacji imitującej działanie miecza świetlnego. Pokazałem to na zajęciach z programowania obiektowego na  i prowadzacy powiedział, że klasa miecza jest zbyt rozległa i powinieniem rozbić ją na części: logiczną i graficzną. Nie za bardzo wiem jak się za to zabrać. Zastanawia mnie czy w klasie odpowiedzialnej za grafikę mają być tylko tekstury, czy też obiekty rectangle? Jeśli obiekty rectangle będą w klasie grafiki, czy klasa logiczna powinna przechowywać współrzędne i rozmiary miecza?  I czy wtedy obie klasy zawrzeć w jednej większej? Czy da się to wszystko zrobić unikając zaprzyjaźniania klas? Podróżując tym tokiem rozumowania przy dodawaniu dźwięku do miecza powinienem stworzyć osobną klasę dla niego? Prosiłbym tylko o słowne wytłumaczenie, żebym mógł sam sobie rozwiązać problem. Z góry serdecznie dziękuję za udzieloną pomoc. :)



#include<iostream>
#include<SFML/Graphics.hpp>
using namespace std;

class Saber	{
	string handleType;
	string beamColor;
	string sabreName;
	sf::RectangleShape beam;
	sf::RectangleShape handle;
	sf::Texture Texture_Beam;
	sf::Texture Texture_Handle;
	bool TurnedOn;
public:
	Saber(string,string,string);
	void RenderHandle();
	sf::RectangleShape ReturnHandle();
	void RenderBeam();
	sf::RectangleShape ReturnBeam();
	bool IsTurned();
	void ChangeState(bool);
};

Saber::Saber(string sColor, string sHandle, string sName)	{
	sColor = "Data/" + sColor + ".png";
	beamColor = sColor;
	sHandle = "Data/" + sHandle + ".png";
	handleType = sHandle;
	sabreName = sName;
	RenderHandle();
	RenderBeam();
	TurnedOn = false;
}
void Saber::RenderHandle()	{
	Texture_Handle.loadFromFile(handleType);
	handle.setSize(sf::Vector2f(32, 116));
	handle.setPosition(400-16, 484);
	handle.setTexture(&Texture_Handle);
}
void Saber::RenderBeam()	{
	Texture_Beam.loadFromFile(beamColor);
	beam.setSize(sf::Vector2f(40, 395));
	beam.setPosition(380, 105);
	beam.setTexture(&Texture_Beam);
}

bool Saber::IsTurned()	{return TurnedOn;}
void Saber::ChangeState(bool state) {
	if (state == false) TurnedOn = true;
	else TurnedOn = false;
}

sf::RectangleShape Saber::ReturnHandle()	{ return handle;}
sf::RectangleShape Saber::ReturnBeam()		{ return beam; }

int main()
{
	sf::RenderWindow window(sf::VideoMode(800, 600), "LighSaber");
	window.setFramerateLimit(60);

	bool play = true;
	sf::Event event;

	Saber Onyx("red", "onyx", "Onyx");

	//States for buttons
	bool leftMousePressed = false;

	//Variables
	int mouseX = 0;
	int mouseY = 0;

	while (play == true)	{
		window.clear();
		//events
		while (window.pollEvent(event))	{

			if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left)	{
				leftMousePressed = true;
			}
			if (event.type == sf::Event::MouseMoved)	{
				mouseX = event.mouseMove.x;
				mouseY = event.mouseMove.y;
			}

			//closing app with x
			if (event.type == sf::Event::Closed)	{
				play = false;
			}
		}
		//logic
		if (leftMousePressed == true && mouseX <= 390 && mouseX >= 360 && mouseY <= 555 && mouseY >= 535)	{
			Onyx.ChangeState(Onyx.IsTurned());
			cout << Onyx.IsTurned() << "\n";
			leftMousePressed = false;
		}
		if (Onyx.IsTurned()) {
			window.draw((Onyx.ReturnBeam()));

		}
		//render

		window.draw((Onyx.ReturnHandle()));
		window.display();
	}
}


 

1 odpowiedź

+2 głosów
odpowiedź 22 kwietnia 2015 przez Ehlert Ekspert (212,710 p.)

Podstawą tego co chciałbyś zrobić jest uwzględnienie w pętli gry pętli stałokrokowej.

sf::Clock timer;
timer.restart();
while(okno.isOpen())
{
okno.clear(sf::Color::White);

//obsługa wydarzeń

if(timer.getElapsedTime().asSeconds() > 0.03)
{
//tutaj operacje logiczne
//również przesuwanie obiektów itp.

timer.restart();
}

okno.display();
}

Dzięki temu mechanizmowi apka chodzi poprawnie na każdym komputerze bez względu ile wyciągnie fpsów. 

Jeśli chodzi o logikę to ja postarałbym się zrobić jedną klasę miecza. Zawiera ona grafikę, teksturę, sprite'a. Potem zagnieżdzasz w niej mniejszą odpowiedzialną za logikę. Obsługujesz ją interfejsem set, get i inne pierdoły. W wyżej opisanym przypadku unikasz przyjaźni, dane są zabezpieczone. Mam nadzieję, że pomogłem. wink

Podobne pytania

0 głosów
2 odpowiedzi 337 wizyt
pytanie zadane 19 sierpnia 2015 w C i C++ przez kacperszo Użytkownik (860 p.)
0 głosów
1 odpowiedź 129 wizyt
pytanie zadane 20 stycznia 2017 w C i C++ przez klap Początkujący (410 p.)
+1 głos
2 odpowiedzi 471 wizyt
pytanie zadane 7 czerwca 2017 w C i C++ przez mel0n Początkujący (400 p.)

92,584 zapytań

141,434 odpowiedzi

319,670 komentarzy

61,967 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...