Bardzo dziękuję za odpowiedź.
Mam problem jak poskładać wszystko do kupy, żeby było jednym "organizmem".
main.cpp
Tutaj tworzę obiekt okna, ustawiam parametry, tworzę główną pętlę "gry", obsługującą zdarzenia (wrzucając je do zmiennej event). Tutaj wywołuję instancję singletonu State machine, następnie w pętli wywołuję jej metodę handleInput, posyłając event.
#include <SFML\Window.hpp>
#include <SFML\Graphics.hpp>
#include "StateMachine.h"
using namespace sf;
int main()
{
CircleShape cir;
StateMachine* machine = StateMachine::Instance();
RenderWindow window(VideoMode(800, 600), "State machine basic");
window.setFramerateLimit(30);
while (window.isOpen())
{
Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case Event::Closed:
{
window.close();
break;
}
}
machine->handleInput(event);
}
// clear
window.clear(Color::Blue);
// draw
//window.draw(machine->_state); - tutaj bym rysował stworzoną instancję obiektu?
// display
window.display();
}
return EXIT_SUCCESS;
}
StateMachine
tutaj mam wskaźnik polimorficzny typu State, która posiada wirtualne metody, z których dziedziczą klasy Menu i Game, State przyjmuje stan obiektu potomka (początkowo ustawiony na Menu). Tutaj podaję dalej w handleInput, otrzymany event, do stanu _state->handleInput(), czyli do Menu.
.h
#pragma once
#include <SFML\Graphics.hpp>
#include <iostream>
#include "State.h"
#include "Menu.h"
#include "Game.h"
class StateMachine
{
public:
static StateMachine* Instance();
void handleInput(Event);
void changeState(State*);
protected:
StateMachine();
~StateMachine()=default;
private:
static StateMachine* _instance;
State * _state;
};
.cpp
#include "StateMachine.h"
StateMachine* StateMachine::_instance = 0;
StateMachine* StateMachine::Instance()
{
if (_instance == 0)
{
_instance = new StateMachine;
}
return _instance;
}
StateMachine::StateMachine()
:_state(Menu::Instance())
{
}
void StateMachine::handleInput(Event event)
{
_state->handleInput(event);
}
void StateMachine::changeState(State* newState)
{
_state = newState;
}
State
wirtualne metody odziedziczane przez Menu i Game:
.h
#pragma once
#include <SFML\Graphics.hpp>
#include <iostream>
using namespace sf;
class State: public Drawable
{
public:
State() {}
~State() {}
virtual void handleInput(Event) {}
virtual void draw(RenderTarget &target, RenderStates states) const {}
};
Potomkowie, tutaj się pojawia mój problem. Dziedziczą z Klasy State, jak również z klasy Drawable. Nadpisałem metodę draw, jednak gdybym ją chciał wywołać nie udaje mi się posłać tam obiektu window, ponieważ nie jest zgodny z typem, przyjmowanych parametrów przez draw. Próbowałem również dostać się do instancji _state z StaeMachine (tak jak jest to pokazane w kodzie), jednak to też nie działa. Chodzi mi tylko o użycie tej metody draw z klasy Menu albo Game.
Menu
.h
#pragma once
#include "State.h"
class Menu :public State
{
public:
static State* Instance();
void handleInput(Event);
protected:
Menu()=default;
~Menu()=default;
private:
static State* _instance;
void play();
void set();
virtual void draw(RenderTarget &target, RenderStates states) const override;
CircleShape circle;
Font font;
Text text, text2;
Vector2f screen{ 400,300 };
float radiusBall{ 15.f };
float vocity{ 8.0f };
Vector2f vocityBall{ 4.f,vocity };
};
.cpp
#include "Menu.h"
#include "StateMachine.h"
State* Menu::_instance = 0;
State* Menu::Instance()
{
if (_instance == 0)
{
_instance = new Menu;
}
return _instance;
}
void Menu::handleInput(Event event)
{
std::cout << "Menu::handleInput" << std::endl;
RenderStates* st{0};
this->set();
this->play();
/*
if (event.key.code == Keyboard::Q)
{
StateMachine* state = StateMachine::Instance();
State* game = Game::Instance();
state->changeState(game);
}*/
}
////////////////////////////////////////////////////////
void Menu::set()
{
if (!font.loadFromFile("arial.ttf"))
{
std::cout << "Font load error" << std::endl;
}
text.setFont(font);
text.setString("THE ARKANOID GAME");
text.setFillColor(Color::Cyan);
text.setOrigin(text.getGlobalBounds().width / 2, text.getGlobalBounds().height / 2);
text.setPosition(screen);
text.setScale({ 1.5f,1.5f });
text2.setFont(font);
text2.setString("Made by: Ciepano");
text2.setFillColor(Color::White);
text2.setOrigin(text.getGlobalBounds().width / 2, text.getGlobalBounds().height / 2);
text2.setPosition({ 430,570 });
circle.setFillColor(Color::Red);
circle.setRadius(radiusBall);
circle.setOrigin(radiusBall, radiusBall);
circle.setPosition({ 100,100 });
}
void Menu::play()
{
circle.move(vocityBall);
if (circle.getPosition().y + circle.getRadius() >= 600)
{
vocityBall.y = -vocity;
}
else if (circle.getPosition().y - circle.getRadius() <= 0)
{
vocityBall.y = vocity;
text.setFillColor(Color::Green);
}
if (circle.getPosition().x > 850 || Mouse::isButtonPressed(Mouse::Left))
{
// ctrl+v
StateMachine* state = StateMachine::Instance();
State* game = Game::Instance();
state->changeState(game);
}
}
void Menu::draw(RenderTarget &target, RenderStates states) const
{
target.draw(text);
target.draw(text2);
target.draw(circle);
}
Zakładam że mogę popełniać mnóstwo błędów, ponieważ jestem samoukiem, aczkolwiek staram się nieustannie z tym mierzyć i rozwijać swoją wiedzę.
Każda informacja będzie dla mnie bardzo cenna merytorycznie.