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

question-closed Ustawienia gry SFML

Object Storage Arubacloud
0 głosów
681 wizyt
pytanie zadane 3 stycznia 2017 w C i C++ przez PaulW Początkujący (470 p.)
zamknięte 4 stycznia 2017 przez PaulW

Tak jak w pytaniu , chcę , aby piłka zmieniła swój kolor na taki jaki ustawię w ustawieniach gry . Jestem już bez rady i proszę o jakieś wskazówki . 

game.h
#ifndef game_h
#define game_h
#include <SFML/Graphics.hpp>

class Game
{
public:
    Game();
    ~Game();
    void uruchomGre();
private:
    sf::Texture tekstura;
    sf::Sprite tlo;
    enum stany_gry{Menu, Gra , Ustawienia , Koniec};
    stany_gry stan;
    void menu();
    sf::Font czcionka;
};

game.cpp
#include <SFML/Graphics.hpp>
#include "game.h"
#include "silnik.h"
#include "settings.h"
#include <iostream>
using namespace std;

sf::RenderWindow okno(sf::VideoMode(1920 , 1080 , 32) , "PONG SFML" , sf::Style::Default);


Game::Game()
{
     if(czcionka.loadFromFile("atari.TTF")== false)
    {
        cout << "Error";
        exit(0);
    }
    stan = Menu;
}

void Game::uruchomGre()
{
    while(stan != Koniec)
    {
        switch(stan)
        {
            case Menu:
                {
                    menu();
                }break;

            case Gra:
                {
                    Silnik silnik(okno);
                    silnik.uruchomSilnik();
                    stan = Menu;
                }break;
            case Ustawienia:
                {
                    Settings settings(okno);
                    //cout << a[0] << "Ustawienia 1" << endl;
                    settings.uruchomUstawienia();
                    //a[0] = b[0];
                    //cout << b[0] << "Test" << endl;
                    stan = Menu;
                }break;
        }
    }
}

void Game::menu()
{
    tekstura.loadFromFile("atari.png");
    tlo.setTexture(tekstura);

    sf::Text tekst[3];
    string opcje[3] = {"Play" , "Settings" , "Quit"};
    for(int i = 0 ; i < 3 ; i++)
    {
        tekst[i].setFont(czcionka);
        tekst[i].setCharacterSize(60);
        tekst[i].setString(opcje[i]);
        tekst[i].setPosition(1920 / 2 - tekst[i].getGlobalBounds().width / 2 , 100 * i + 400);
    }
    while(stan == Menu)
    {
        sf::Vector2f mysz(sf::Mouse::getPosition());
        sf::Event wydarzenie;

        while(okno.pollEvent(wydarzenie))
        {
            if(wydarzenie.type == sf::Event::Closed || tekst[2].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed && wydarzenie.key.code == sf::Mouse::Left)
                stan = Koniec;

            else if(tekst[0].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed && wydarzenie.key.code == sf::Mouse::Left)
                stan = Gra;

            else if(tekst[1].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed && wydarzenie.key.code == sf::Mouse::Left)
                stan = Ustawienia;
        }

        for(int i = 0 ; i < 3 ; i++)
        {
            if(tekst[i].getGlobalBounds().contains(mysz))
                tekst[i].setColor(sf::Color::Red);
            else
                tekst[i].setColor(sf::Color::White);
        }

        okno.clear(sf::Color::Black);
        okno.draw(tlo);
        for(int i = 0 ; i < 3 ; i++)
        {
            okno.draw(tekst[i]);
        }
        okno.display();
    }

}

silnik.h

#ifndef silnik_h
#define silnik_h
#include <SFML/Graphics.hpp>
#include "settings.h"

class Silnik:public Settings
{
public:
    Silnik();
    Silnik(sf::RenderWindow &win);
    ~Silnik();
    void uruchomSilnik();
    void zmiana_koloru();
private:
    sf::RenderWindow *window;
    sf::CircleShape pilka;
    sf::Color kolor; // zmienna przechowująca kolor piłki
};
#endif // silnik_h


silnik.cpp

#include "silnik.h"
#include <cmath>
 #include <iostream>
using namespace std;

Silnik::Silnik(sf::RenderWindow &win)
{

    if(czcionka.loadFromFile("atari.TTF")== false)
    {
        cout << "Error";
        exit(0);
    }
    window = &win;
    k = 0;
    z = 0;
}

void Silnik::uruchomSilnik()
{
    bool menu = false;

    float szybkosc = 1.5;
    float x = -1;
    float y = 0;
    zmiana_koloru();

    pilka.setRadius(5);
    pilka.setFillColor(kolor);
    pilka.setPosition(1920 / 2 - pilka.getGlobalBounds().width / 2 , 1080 / 2 - pilka.getGlobalBounds().height / 2);

    while(menu != 1)
    {

        sf::Event wydarzenie;
        while(window->pollEvent(wydarzenie))
        {
            if(wydarzenie.type == sf::Event::KeyReleased && wydarzenie.key.code == sf::Keyboard::Escape)
                menu = true;
        }

        window->clear();
        window->draw(pilka);
        window->display();

    }
}

void Silnik::zmiana_koloru()
{
    kolor = kolor1; // przypisuje zmiennej kolor , "kolor1" z klasy Settings
}
settings.h

#ifndef settings_h
#define settings_h
#include <SFML/Graphics.hpp>

class Settings
{
public:
    Settings(sf::RenderWindow &win);
    void uruchomUstawienia();
    sf::Color kolor1 = sf::Color::Blue;
private:
    sf::RenderWindow *window;
    sf::Font czcionka;
    sf::RectangleShape prostokat[3];
};
#endif // settings_h

settings.cpp

#include "settings.h"
#include <iostream>
using namespace std;

Settings::Settings(sf::RenderWindow &win)
{
    window = &win;
    if(czcionka.loadFromFile("atari.TTF")== false)
    {
        cout << "Error";
        exit(0);
    }
}

void Settings::uruchomUstawienia()
{
    bool ustawienia = false;

    string opcje[3] = {"Kolor" , "Dzwiek" , "Tlo"};
    sf::Text tekst[3];
    for(int i = 0 ; i < 3 ; i++)
    {
        tekst[i].setFont(czcionka);
        tekst[i].setCharacterSize(60);
        tekst[i].setString(opcje[i]);
        tekst[i].setPosition(1920 / 2 - tekst[i].getGlobalBounds().width / 2 , 150 * i + 400);
    }

    for(int i = 0 ; i < 3 ; i++)
    {
        prostokat[i].setSize(sf::Vector2f(60 , 20));
        prostokat[i].setPosition(840 + 100 * i , 510);
    }
    prostokat[0].setFillColor(sf::Color::Red);
    prostokat[1].setFillColor(sf::Color::Green);
    prostokat[2].setFillColor(sf::Color::Blue);

    while(ustawienia != 1)
    {
        sf::Vector2f mysz(sf::Mouse::getPosition());
        sf::Event wydarzenie;

        while(window->pollEvent(wydarzenie))
        {
            if(wydarzenie.type == sf::Event::KeyReleased && wydarzenie.key.code == sf::Keyboard::Escape)
                ustawienia = true;

        }

            if(prostokat[0].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed)
            {

                kolor1 = sf::Color::Red; // tutaj zmieniam kolor piłki na czerwony
                prostokat[0].setOutlineThickness(5);
                prostokat[0].setOutlineColor(sf::Color::White);
            }
            else if (prostokat[0].getGlobalBounds().contains(mysz) == false && wydarzenie.type == sf::Event::MouseButtonPressed)
            {
                prostokat[0].setOutlineThickness(0);
                prostokat[0].setFillColor(sf::Color::Red);
            }

        window->clear(sf::Color::Black);
        for(int i = 0 ; i < 3 ; i++)
            window->draw(tekst[i]);
        for(int i = 0 ; i < 3 ; i++)
            window->draw(prostokat[i]);
        window->display();
    }
}

 

komentarz zamknięcia: Problem rozwiązany !! :-)
komentarz 3 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Żebyś jeszcze pokazał, w którym miejscu próbujesz przypisywać kolor.... 5 raz czytam kod i znalazłem tylko coś co wypisuje prostokąty na ekran:

prostokat[0].setFillColor(sf::Color::Red);
prostokat[1].setFillColor(sf::Color::Green);
prostokat[2].setFillColor(sf::Color::Blue);
komentarz 3 stycznia 2017 przez PaulW Początkujący (470 p.)
W tym miejscu:

if(prostokat[0].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed)

            {

                kolor1 = sf::Color::Red; // tutaj zmieniam kolor piłki na czerwony

                prostokat[0].setOutlineThickness(5);

                prostokat[0].setOutlineColor(sf::Color::White);

            }
komentarz 3 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Mamy to w settings.h

sf::Color kolor1 = sf::Color::Blue;

Oraz w silnik.h

sf::Color kolor; // zmienna przechowująca kolor piłki

Tutaj przypisujesz kolor:

 kolor1 = sf::Color::Red; // tutaj zmieniam kolor piłki na czerwony

Tylko czy sf::Color zwraca poprawną wartość, którą można przypisać do kolor1?

komentarz 3 stycznia 2017 przez PaulW Początkujący (470 p.)
Problem jest w tym , że po kliknięciu w  czerwony prostokąt:

if(prostokat[0].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed)
            {
                a[0] = 1;
                kolor1 = sf::Color::Red;
                prostokat[0].setOutlineThickness(5);
                prostokat[0].setOutlineColor(sf::Color::White);
            }

a następnie kliknięciu Escape:

if(wydarzenie.type == sf::Event::KeyReleased && wydarzenie.key.code == sf::Keyboard::Escape)
            {
                //a[0] = b[0] = 3;
                //cout << b[0] << "Escape" << endl;
                ustawienia = true;
            }

kolor1 przestaje pamiętać swoją wartość

Próbuję teraz zwracać jego wartość poprzez getter i przekazać do głównej funkcji gry.
komentarz 3 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Zgaduję, ale może referencja potrzebna jest na ten kolor, bo zmiana koloru zachodzi w funkcji, a po wyjściu z niej przywracany jest dawny kolor.
komentarz 3 stycznia 2017 przez PaulW Początkujący (470 p.)
edycja 3 stycznia 2017 przez PaulW
Próbowałem przez referencję , ale nie wychodziło mi przez dość długi czas i się poddałem . Może ty wiesz jak to dokładnie zrobić ?
komentarz 3 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Dopatrzyłem się czegoś takiego:

W klasie Settings.h masz składową public: sf::Color kolor1 = sf::Color::Blue;

Dalej mamy: class Silnik:public Settings czyli klasa Silnik dziedziczy publicznie po klasie Settings. I w tej klasie Silnik.h masz składową private: sf::Color kolor; // zmienna przechowująca kolor piłki

W klasie silnik.h masz też

void Silnik::zmiana_koloru()
{
    kolor = kolor1; // przypisuje zmiennej kolor , "kolor1" z klasy Settings
}

Nie mogę się jeszcze doszukać, gdzie w którejś klasie np. game.h dodajesz tą informację, że kolor został zmieniony.

komentarz 3 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Jeśli składowa w Silnik.h informująca o kolorze jest private, to nie jest widoczna też dla klasy game.h, chyba, że udostępniasz jej to przez metodę, czego też nie znalazłem.
komentarz 3 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
W klasie game.cpp wywołujesz metodę settings.uruchom ustawienia a ona się nie odnosi do pliku silnik.h w którym zmieniany jest kolor.
komentarz 4 stycznia 2017 przez PaulW Początkujący (470 p.)

Masz rację . 

Dla przykładu :

Silnik::Silnik(sf::RenderWindow &win)
{

    if(czcionka.loadFromFile("atari.TTF")== false)
    {
        cout << "Error";
        exit(0);
    }
    window = &win;
    k = 0;
    z = 0;
    //a = getB();
    cout << "Kolor ma wartosc " << a <<endl;
    kolor = getKolor1();
}

sf::Color Silnik::setKolor(sf::Color &color)
{
    kolor = color;
}

class Settings
{
public:
    Settings();
    Settings(sf::RenderWindow &win);
    ~Settings();
    void uruchomUstawienia();
    sf::Color& getKolor1();
    int getB();
private:
    sf::RenderWindow *window;
    sf::Font czcionka;
    sf::RectangleShape prostokat[3];
    sf::Color kolor1 = sf::Color::Green;
    int b;
};

sf::Color& Settings::getKolor1()
{
    return kolor1;
}

Jeżeli przypiszę na początku wartość zmiennej "kolor1" , wszystko działa jak należy . Cały czas problem jest taki , że tutaj :

 while(window->pollEvent(wydarzenie))
        {
            if(wydarzenie.type == sf::Event::KeyReleased && wydarzenie.key.code == sf::Keyboard::Escape)
                ustawienia = true;

            if(prostokat[0].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed)
            {
                kolor1 = sf::Color::Red;
                prostokat[0].setOutlineThickness(5);
                prostokat[0].setOutlineColor(sf::Color::White);
            }

Nie ustawia mi "kolor1" na czerwony. 

komentarz 4 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Sprawdzałeś debugerem czy w ogóle ta pętla while(windows->pollEvent(wydarzenie)) się wywołuje i warunek if ze zmianą koloru?
komentarz 4 stycznia 2017 przez PaulW Początkujący (470 p.)

Sprawdziłem poprzez wyświetlanie tekstu . Po kliknięciu w ten prostokąt wyświetla się tekst : 

  if(prostokat[0].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed)
            {
                cout << "tekst";
                b = 2;
                prostokat[0].setOutlineThickness(5);
                prostokat[0].setOutlineColor(sf::Color::White);
            }

 

Co ciekawe , jak wykonuje sprawdzenie na tablicach wszystko jest ok. Ustawia wartość i zmienia po kliknięciu w inny prostokąt . Problem być może jest w tym , że początkowo nie ma żadnej wartości i piłka na ekranie się wyświetla na czarno ? Zmiana później w ustawieniach niczego nie zmienia .

komentarz 4 stycznia 2017 przez maly Nałogowiec (37,190 p.)
kolor1 = sf::Color::Red;

Przecież zmieniasz tylko wartość zmiennej kolor1, bez wywołania dla konkretnego prostokąta metody setFillColor nie zmienisz jego koloru.

komentarz 4 stycznia 2017 przez PaulW Początkujący (470 p.)

Uruchamiam program , wchodzę w "Ustawienia" klikam w czerwony prostokąt i ustawiam wartość zmiennej "kolor1" na czerwony . Później uruchamiam grę , wywołuje się konstruktor 

Silnik::Silnik(sf::RenderWindow &win)
{

    if(czcionka.loadFromFile("atari.TTF")== false)
    {
        cout << "Error";
        exit(0);
    }
    window = &win;
    k = 0;
    z = 0;
    //a = getB();
    cout << "Kolor ma wartosc " << a <<endl;
    kolor = getKolor1();
}
sf::Color& Settings::getKolor1()
{
    return kolor1;
}

a następnie uruchamiana jest funkcja uruchomSilnik() w której nadaję kolor piłce

void Silnik::uruchomSilnik()
{

   pilka.setRadius(5);
    pilka.setFillColor(kolor);

...

 

3 odpowiedzi

0 głosów
odpowiedź 3 stycznia 2017 przez playerony Pasjonat (15,240 p.)
W klasie Setting można by zrobić gettera zwracającego wybrany kolor, po czym przesłać go do klasy odpowiadajacej za gre poprzez konstruktor bądź jakieś setter.
komentarz 3 stycznia 2017 przez PaulW Początkujący (470 p.)
Mógłbyś przybliżyć , jak przesłać go do klasy odpowiadającej za grę ?
komentarz 3 stycznia 2017 przez playerony Pasjonat (15,240 p.)
1. W klasie Settings robisz zmienna prywatną, która będzie zawierać wybrany kolor i będzie on zmieniany w zalezności od wyboru.

2. Do wyżej wspomnianej klasy wrzucasz getter zwracajacy zmienna przechowującą kolor.

3. No dalej już chyba dasz rade, w klasie gry robisz znowu zmienna prywatną przechowującą kolor, ale tu zamiast gettera robisz setter do ustawienia wartości.

 

Ważne przy tym sposobie jest to by mieć dostęp do obiektu klasy settings gdzie przechowywany jest kolor.
komentarz 3 stycznia 2017 przez PaulW Początkujący (470 p.)

Problem właśnie jest w tym , że nie wiem jak zrobić setter . Jak ma się getter klasy Settings do settera klasy Silnik ?

Mam coś takiego:
 

...

 if(prostokat[0].getGlobalBounds().contains(mysz) && wydarzenie.type == sf::Event::MouseButtonPressed)
            {
                kolor3 = sf::Color::Red;
                prostokat[0].setOutlineThickness(5);
                prostokat[0].setOutlineColor(sf::Color::White);
            }

...

sf::Color Settings::getKolor3()
{
    return kolor3;
}

silnik.cpp

sf::Color Silnik::setKolor4()
{
    kolor4 = getKolor3();
}
void Silnik::uruchomSilnik()
{
    bool menu = false;
    float szybkosc = 1.5;
    float x = -1;
    float y = 0;
    setKolor4();

    pilka.setRadius(5);
    pilka.setFillColor(kolor4);

...

}

 

0 głosów
odpowiedź 3 stycznia 2017 przez maly Nałogowiec (37,190 p.)
W metodzie Settings::uruchomUstawienia() wszystkie if-y są poza pętlą event-ów.
komentarz 3 stycznia 2017 przez PaulW Początkujący (470 p.)
Nawet , jeżeli są w pętli eventów "gubi" kolor przechowany w zmiennej "kolor1"
0 głosów
odpowiedź 4 stycznia 2017 przez PaulW Początkujący (470 p.)
Problem rozwiązany , pozbyłem się zbędnej klasy settings i zrobiłem wszystko w dwóch i działa !! :D

Podobne pytania

+4 głosów
0 odpowiedzi 145 wizyt
pytanie zadane 31 lipca 2023 w Nasze projekty przez Bondrusiek Maniak (61,370 p.)
+3 głosów
0 odpowiedzi 225 wizyt
+1 głos
1 odpowiedź 171 wizyt
pytanie zadane 29 października 2018 w C i C++ przez Poczprogramista123 Bywalec (2,900 p.)

92,620 zapytań

141,468 odpowiedzi

319,792 komentarzy

62,002 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!

...