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

Niepoprawne działanie typu wyliczeniowego enum .

Object Storage Arubacloud
0 głosów
127 wizyt
pytanie zadane 31 października 2016 w C i C++ przez PaulW Początkujący (470 p.)
edycja 31 października 2016 przez PaulW
class Gra
{
public:
    Gra();
    enum opcje{MENU , GRA , USTAWIENIA , KONIEC};
    void uruchomGre();
    opcje stangry;
    void menu();
    void ustaw(); void ustaw1(); void ustaw2(); void ustaw3();
private:
    int wybranaopcja = 0;
    char znak;
 
 
};
#endif // gra_h

 

Tutaj zastosowałem dziedziczenie w celu uzyskania dostępu do zmiennej "stangry" typu "opcje" zadeklarowanej w klasie "Gra".

#ifndef menedzer_h
#define menedzer_h
#include <iostream>
#include "paletka.h"
#include "pilka.h"
#include "gra.h"
 
using namespace std;
 
class Menedzer:public Gra
{
public:
    Menedzer(int s , int w); // konstruktor dwuparametrowy
    ~Menedzer(); // destruktor
    void wynikUp(Paletka *gracz); // funkcja składowa klasy której parametrem jest wskaźnik na obiekt klasy Paletka
    void rysuj(); // deklaracja funkcji "rysuj"
    void wejscie(); // -//-
    void start(); // -//-
    void kolizje(); // -//-
private:
    int wysokosc , szerokosc; // zmienne określające wysokość i szerokość pola gry
    int wynik1 , wynik2; // zmienne typu int , przechowują wynik gracza I i II
    char gora1 , dol1 , gora2 , dol2; // zmienne typu char , odpowiadają za sterowanie graczami ( orzypisanie klawiszu klawiatury)
    bool koniec; // warunek sprawdzający
    Pilka *pilka; // nowy obiekt klasy Pilka tworzony dynamicznie
    Paletka *gracz1; // -//-
    Paletka *gracz2; // -//-
    void wynikReset(); // funkcja zerująca wynik meczu
    void pilkaStop();
 
};
 
#endif // menedzer_h

W konstruktorze , początkowy "stangry" ustawiam na "MENU"

void Gra::menu()
{
        while( wybranaopcja != 3 ) // jeżeli zmienna "wybranaopcja" jest różna od 3 (menu posiada tylko 3 opcje)
        {
        ustaw1();
        if( wybranaopcja == 0 ) cout << "-->Graj\n";         // opcje menu
        else cout << "Graj    \n";

        ustaw2();
        if( wybranaopcja == 1 ) cout << "-->Ustawienia\n";   // pokazuje się "-->"
        else cout << "Ustawienia    \n";

        ustaw3();
        if( wybranaopcja == 2 ) cout << "-->Wyjdz\n";        // -//-
        else cout << "Wyjdz    \n";

        znak = getch(); // odczytuje kod wciśniętego klawisza klawiatury i przechowuje go w zmiennej "znak"

        switch( znak )
        {
        case 72:                // jeżeli wciśniemy strzałkę w górę "kod ASCII = 72"
            wybranaopcja--;     // opcja menu zmniejsza się
            break;
        case 80:
            wybranaopcja++;    // jeżeli wciśniemy strzałkę w dół "kod ASCII = 80"
            break;             // opcja menu zwiększa się
        }

        if(wybranaopcja > 2 ) wybranaopcja--; // jeżeli wybrana opcja jest > 2 to zmniejsz wartość zmiennej "wybranaopcja"
        if(wybranaopcja < 0) wybranaopcja++; // jeżeli wybrana opcja jest < 0 to zwiększ wartość zmiennej "wybranaopcja"

        if(wybranaopcja == 0 && znak == 13) // jeżeli opcja == 0 ( Graj ) i wciśniemy klawisz "Enter"
        {
            stangry = GRA; // stan gry zostaje ustawiony na "GRA"
            cout << stangry;
            break;
        }

        if(wybranaopcja == 1 && znak == 13) // jeżeli opcja == 1 ( Ustawienia) i wciśniemy klawisz "Enter"
        {
            stangry = USTAWIENIA; // stan gry zostaje ustawiony na "USTAWIENIA"
            break;
        }

        if(wybranaopcja == 2 && znak == 13) // jeżeli opcja == 2 ( Koniec ) i wciśniemy klawisz "Enter"
        {
            stangry = KONIEC; // stan gry zostaje ustawiony na "KONIEC"
            cout << stangry;
            break;

        }
        }
}

Chciałem zrobić coś takiego , że w zależności od stanu wykona się dana rzecz. Wszystko działa jak należy tylko w pierwszym obiegu , później występują problemy

ważniejszy fragment menedzer.cpp
 
 void Menedzer::wejscie()
    {
        if(klawisz == 112) // P - Pauza
        {
           menu(); // chciałem tutaj zrobić tak while(stangry == GRA)
                                                {
                                                 stangry = MENU;
                                                 break;
                                                }
        }
    }

Wygląda to tak :

Stan gry ustawiony na "MENU" , zostaje uruchomiona funkcja "menu()"  , która tworzy menu . 

Po kliknięciu "enter" stan gry zostaje ustawiony na "GRA" czyli jak wynika z metody uruchomGre() :

case GRA:
            {
             Menedzer m1(40 , 20);
             m1.start();
            } break;

W skrócie klasa Menedzer odpowiada za całą grę . Natomiast metoda start() :

 void Menedzer::start()
    {

            while(stangry != KONIEC)
            {
            rysuj();   // rysuje boisko , graczy ( 2 paletki) i piłkę itd.
            wejscie(); // "wprawia w ruch" graczy , piłkę, obługuje opcje gry itp.
            kolizje(); // odpowiada za kolizje w grze
            }
    }

Wracając do ostatniego obrazka , po powrocie do menu (kliknięciu klawisza"p") oraz ponownym naciśnięciu klawisza enter  na opcji "Graj" piłka kontynuuje ruch co ważne w dobrym kierunku . ( Poprzednio po zatrzymaniu obierała losowy kierunek nadany w metodzie "losowyKierunek":

 void Pilka::losowyKierunek()
    {
        kierunek = (stan)((rand() % 6) + 1); // przypisanie losowego kierunku zmiennej "kierunek"
    }

Także do tego momentu jest ok . Działa to za każdym razem po kliknięciu literki "p" . Niestety nie działa jak należy opcja "Wyjdź " po drugim bądź kolejnym powrocie do menu. 


 

 

1 odpowiedź

0 głosów
odpowiedź 31 października 2016 przez siof Gaduła (3,560 p.)

Jeśli dobrze rozumiem ideę po tym co przedstawiłeś to:

  • Funkcja uruchomGre uruchamiana jest tylko raz na poczatku uruchomienia programu (zakłądam tak ponieważ po wyborze 'Gra' startowany jest manager który najprawdopodobniej blokuje dalsze wywoływanie funkcji do czasu zakończenia gry)
  • funkcja Menedzer::start blokuje watek do czasu zakonczenia gry

Jeśli powyższe jest prawdziwe to najprawdopodobniej włąśnie dlatego nie działa Ci menu. Z wewnątrz funkcji Menedzer::wejscie mozesz wejsc do menu i zmodyfikowac stan gry ale nigdzie tu nie widzę obsługi nowego stanu (obsługa w tym co przedstawiłeś jest jedynie w funkcji uruchomGre która nie jest wykonywana po wystartowaniu gry).  Aby Ci program obsługiwał stany gry musiałbyś dodać obsługę jego sprawdzania gdzieś w głównej pętli gry (najprawdopodobniej na jej poczatku lub końcu ale to już sam zdecydujesz ;) ).

Jeśli jednak źle zrozumiałem działanie to rozwiń proszę jego opis

komentarz 31 października 2016 przez PaulW Początkujący (470 p.)

Dobrze myślisz :

#include <iostream>       // biblioteka wejscia / wyjscia
#include "pilka.h"        // dyrektywa #include załącza plik nagłówkowy "pilka.h"
#include "paletka.h"      // dyrektywa #include załącza plik nagłówkowy "paletka.h"
#include "menedzer.h"     // dyrektywa #include załącza plik nagłówkowy "menedzer.h"
#include "gra.h"       // dyrektywa #include załącza plik nagłówkowy "gra.h"
using namespace std;      // użycie przestrzeni nazw "std"

int main()
{

    Gra g1;
    g1.uruchomGre();
    return 0;
}

Myślałem ,że jak zrobię tak :

if(klawisz == 112) // P - Pauza
        {
            while(stangry == GRA)
            {
                stangry = MENU;
                break;
            }
        }

to wróci mi tak jakby do metody "uruchomGre" i wykona się case MENU , który wywołuje funkcje rysującą menu. Może trochę inaczej  , nie chcę w tym miejscu:

if(klawisz == 112) // P - Pauza
        {
        
        }

robić tak :

if(klawisz == 112) // P - Pauza
        {
            menu();
        }

tylko tak :

if(klawisz == 112) // P - Pauza
        {
            while(stangry == GRA)
            {
                stangry = MENU;
                break;
            }
        }

Chciałbym działanie mojej gry oprzeć na stanach

komentarz 31 października 2016 przez siof Gaduła (3,560 p.)
            while(stangry == GRA)
            {
                stangry = MENU;
                break;
            }

Tutaj chyba miał być if. Po co wsadzać niepotrzebnie while skoro i tak maksymalnie 1 raz się to wykona.

Co do stanów to najłatwiej by Ci było chyba dodać sprawdzanie stanów i odpalanie odpowiednich funkcji w metodęStart.

Niżej daje pseudokod ala cpp prezentującą przykład takiego podejścia:

while (stanGry != KONIEC)
{
    switch (stanGry)
    {
        case GRA:
            rysowanie();
            i();
            inneCuda();
            break;

        case MENU:
            menu();
            break;

        case KONIEC:
            break;
    }
}

 

Podobne pytania

0 głosów
1 odpowiedź 864 wizyt
pytanie zadane 27 kwietnia 2016 w C i C++ przez lukasz_m Obywatel (1,380 p.)
0 głosów
1 odpowiedź 217 wizyt
pytanie zadane 28 października 2016 w C i C++ przez PaulW Początkujący (470 p.)
0 głosów
4 odpowiedzi 222 wizyt

92,634 zapytań

141,505 odpowiedzi

319,883 komentarzy

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

...