Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Zmienne sie resetuja


Rekomendowane odpowiedzi

Opublikowano

witam, mam problem z zmiennymi.

 

ustawiam początkowe wartości zmiennych w konstruktorze (np. exp=100). ten program co robie to jest niby gra (taki tekstowy RPG) i mam potworki. Dla testow zrobilem zeby potworek dawal 1000 expa.

Jak zabije sie tego potwora to ma sie 10 lvl.

Co level oczywiscie statystyki sie zwiekszaja. Na 10 lvlu jest 44 DMG i 225 zycia. Potem moge sobie wykonac misje i wtedy sie sypie.

 

Teoretycznie powinienem mieć 225 zycia, ale podczas wykonywania funkcji działa ona na podstawowej wartości zmiennej (100). Po wykonaniu misji wszystko sie restuje do ustawien podstawowych (oprócz aktualnego Expa bo jest dodawany). Mój kod wygląda tak:

 

 

Main.cpp

#include <iostream>
#include <Windows.h>
#include "Gra.h"
#include "Misje.h"
using namespace std;
int main()
{
    Gra g;
   g.ekranPowitalny();
}

Gra.h

#ifndef GRA_H
#define GRA_H

class Gra
{
    protected:
    int wybor;
    int hasloDoVip;
    int zycieG;
    int maksZycie;
    int zyciePsa;
    int obrazeniaG;
    int obrazeniaPsa;
    int aktualnyExp;
    double potrzebnyExp;
    int poziom;
    public:
        Gra();
    void ekranPowitalny();
    void menuGry();
    void iStrefaVip();
    void strefaVip();
    void walczZPsem();
    void walkaZPotworami();
    void Kaplan();
    void walczZWilkiem();
    void awans();
    void misje();
};

#endif // GRA_H
 

Gra.cpp

#include <iostream>
#include <Windows.h>
#include "Gra.h"
#include <math.h>
#include "Misje.h"
using namespace std;

void Gra::ekranPowitalny()
{
    HANDLE hout;
    hout=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hout, FOREGROUND_GREEN|FOREGROUND_INTENSITY);
    cout << ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" << endl;
    cout << ":                                                                         :" << endl;
    cout << ":            T                                              T             :" << endl;
    cout << ":           TTT                                            TTT            :" << endl;
    cout << ":           TTT                                            TTT            :" << endl;
    cout << ":           TTT                                            TTT            :" << endl;
    cout << ":           TTT                                            TTT            :" << endl;
    cout << ":           TTT                                            TTT            :" << endl;
    cout << ":           TTT                                            TTT            :" << endl;
    cout << ":           TTT                                            TTT            :" << endl;
    cout << ":           TTT                                            TTT            :" << endl;
    cout << ":        TTTTTTTTT                                      TTTTTTTTT         :" << endl;
    cout << ":            T                                              T             :" << endl;
    cout << ":            T                                              T             :" << endl;
    cout << ":            T                                              T             :" << endl;
    cout << ":                                                                         :" << endl;
    cout << ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" << endl;
    cout << "                         ::                   ::                           " << endl;
    cout << "                         ::   1. Menu Glowne  ::                           " << endl;
    cout << "                         ::                   ::                           " << endl;
    cout << "                         ::   2. Wyjscie      ::                           " << endl;
    cout << "                         ::                   ::                           " << endl;
    cout << "                         :::::::::::::::::::::::                           " << endl;
    cout << endl;
    SetConsoleTextAttribute(hout, FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
    cout << "Wybierz co chcesz zrobic: ";
    cin >> wybor;
    switch(wybor)
    {
    case 1:
        menuGry();
    case 2:
        exit(0);
    default:
        cout << "Nie ma takiej opcji."<<endl;
        break;
    }
}
void Gra::menuGry()
{

    system("cls");
    HANDLE hout;
    hout=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hout, FOREGROUND_GREEN|FOREGROUND_BLUE);
    //cout << endl;
    cout << "1. Misje" << endl; //ToDo
    cout << "2. Informacje o strefie V.I.P" << endl; //Zrobione
    cout << "3. Kaplan (leczy zdrowie)" << endl; //ToDo
    cout << "4. Statystyki" << endl; //ToDo (pozno)
    cout << "5. Walka z potworami" << endl; //ToDo
    cout << "6. Strefa VIP" << endl;
    cout << "7. Wyjdz" <<endl <<endl;
    SetConsoleTextAttribute(hout, FOREGROUND_GREEN|FOREGROUND_INTENSITY);

    cout << "Twoja ilosc zycia: " << zycieG << "/"<<maksZycie<<"\tDMG: "<<obrazeniaG <<"\t\t Level: "<<poziom << "\t EXP:"<<aktualnyExp << "/" << potrzebnyExp<<endl << endl;
    SetConsoleTextAttribute(hout, FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
    cout << "Wybierz: ";
    cin >> wybor;
    switch(wybor)
    {
    case 1:
        misje();
        break;
    case 2:
        iStrefaVip();
        break;
    case 3:
        Kaplan();
        break;
    case 5:
        walkaZPotworami();
        break;
    case 7:
        exit(0);
        break;
    default:
        cout << "Zly wybor"<<endl;
        Sleep(1400);
        menuGry();
        break;

    }

}
void Gra::iStrefaVip()
{
    system("cls");
    cout << "Strefa Vip to specjalne pomieszczenia dajce dodatkowe opcje"<<endl;
    cout << "Aby sie dostac do strefy VIP trzeba odgadnac sekretne haslo."<<endl;
    cout << "Kazda misja da Ci wskazowki dotyczace hasla. Powodzenia!" << endl;
    cout << endl << "1.Powrot do menu\n2.Wyjscie calkowite\n\nWybierz:";
    cin >>wybor;
    switch(wybor)
    {
    case 1:
        menuGry();
        break;
    case 2:
        exit(0);
    default:
        cout << "Nie ma takiej opcji."<<endl;
        cout << "Wybierz: ";
        cin >> wybor;
        break;
    }
}
void Gra::Kaplan()
{
    system("cls");
    if(zycieG>0 && zycieG <11)
    {
        cout << "Uzdrowie Cie w imie imperium"<<endl;
        zycieG =100;
        cout << "Lepiej uwazaj na siebie w przyszlosci!";
        Sleep(2500);
        menuGry();
    }else if(zycieG>11)
    {
        cout <<"Nie moge Cie uleczyc! Lecze ludzi tylko z krytycznymi punktami zycia (1-10)" <<endl;
        Sleep(2500);
        menuGry();
    }
}
void Gra::walczZPsem()
{
    zyciePsa=40;
    obrazeniaPsa=4;
    do
    {

        if(zyciePsa>=1 && zycieG>=1)
        {
            cout << "Zatakowales Psa. Zabrales mu: " <<obrazeniaG << " punktow zycia."<<endl;
            zyciePsa-=obrazeniaG;
            cout << "Zostalo mu: " << zyciePsa << endl << endl;
            Sleep(1700);
        }
        if(zyciePsa>=1 && zycieG>=1){
            cout << "Pies Cie udrapal!" << endl;
            cout << "Zabral Ci: " << obrazeniaPsa<< endl;
            zycieG-=obrazeniaPsa;
            cout << "Zostalo Ci: " << zycieG << " punktow zycia" << endl;
            Sleep(1700);
        }


       else if (1>zyciePsa && zycieG>0)
        {
            cout << "Zabiles Psa."<<endl;
            Sleep(2500);
            aktualnyExp+=1005;
            awans();
            system("cls");
            menuGry();
        }

        else if(zyciePsa>0 && 1>zycieG)
        {
            cout << "Pies Cie zadrapal na smierc. Zginales" << endl;
            Sleep(2500);
            system("cls");
            menuGry();
        }
    }
    while(zycieG>1 || zyciePsa>1);

}

void Gra::walkaZPotworami()
{
    HANDLE hout;
    hout=GetStdHandle(STD_OUTPUT_HANDLE);

    system("cls");

    cout << "\t";
    for (int i =1; i<51; i++)
        cout << "-";

    cout << endl;
     SetConsoleTextAttribute(hout, FOREGROUND_BLUE|FOREGROUND_RED);
     cout << "1. Walcz z psem (Easy)" << endl;
     cout << "2. Walcz z Wilkiem" << endl;
     SetConsoleTextAttribute(hout, FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);
     cout << "Wybierz: ";
     cin >> wybor;
     switch(wybor){
 case 1:
    walczZPsem();
    break;
 case 2:
    walczZWilkiem();
    break;
 default:
    cout << "Blad! Nie ma takiego wyboru."<<endl;
    Sleep(1400);
    menuGry();
    break;

     }

}

void Gra::walczZWilkiem()
{
    zyciePsa=65;
    obrazeniaPsa=7;
    do
    {

        if(zyciePsa>1 && zycieG>1)
        {
            cout << "Zatakowales Wilka. Zabrales mu: " <<obrazeniaG << " punktow zycia."<<endl;
            zyciePsa-=obrazeniaG;
            cout << "Zostalo mu: " << zyciePsa << endl << endl;
            Sleep(1700);
        }
        if(zyciePsa>1 && zycieG>1){
            cout << "Wilk Cie ugryzl. Odgryzl Ci kawalek ciala! " << endl;
            cout << "Zabral Ci: " << obrazeniaPsa<< endl;
            zycieG-=obrazeniaPsa;
            cout << "Zostalo Ci: " << zycieG << " punktow zycia" << endl;
            Sleep(1700);
        }


       else if (1>zyciePsa && zycieG>0)
        {
            cout << "Zabiles Wilka."<<endl;
            Sleep(2500);
            aktualnyExp+=20;
            awans();
            system("cls");
            menuGry();
        }

        else if(zyciePsa>0 && 1>zycieG)
        {
            cout << "Wilk Ci odgryzl wszystkie czesci ciala. Zginales" << endl;
            Sleep(2500);
            system("cls");
            menuGry();
        }

    }
    while(zycieG>1 || zyciePsa>1);

}
void Gra::awans()
{

    if(aktualnyExp>=potrzebnyExp)
    {
        do{
        poziom = poziom +1;
                potrzebnyExp = round(potrzebnyExp+potrzebnyExp*0.3);
                if(4>poziom){
                    obrazeniaG+=2;
                        maksZycie+=10;
                }else{
                obrazeniaG+=4;
                maksZycie+=15;
                }
                zycieG=maksZycie;

        }while(aktualnyExp>potrzebnyExp);
    }

}
Gra::Gra()
: zycieG(100),
maksZycie(100),
obrazeniaG(12),
aktualnyExp(1),
potrzebnyExp(100),
poziom(1)
{}
void Gra::misje()
{
    system("cls");
     HANDLE hout;
    hout=GetStdHandle(STD_OUTPUT_HANDLE);
Misje mis; //obiekt Klasy Misje
cout << "\t\t";
    for(int i=1; i<51;i++)
        cout << "-";

    cout << endl;
         SetConsoleTextAttribute(hout, FOREGROUND_BLUE|FOREGROUND_RED);

    cout << "1. Misja z dzikami(2 LvL)" << endl;
    cout << "2. XYZ Do zrobienia" <<endl;
    cout << "3. XYZ Do zrobienia" << endl;
    cout << "4. XYZ DO zrobienia" << endl;
    cout << "5. Powrot do menu" << endl<<endl;
         SetConsoleTextAttribute(hout, FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);

    cout << "Wybierz: ";
    cin >> wybor;
    switch(wybor){
case 1:
    mis.missionOneDziki();
    break;
case 5:
    menuGry();
    break;
default:
    cout << "Nie ma takiej opcji.";
    Sleep(1500);
    misje();
    break;
    }
}
 

Misje.h

#ifndef MISJE_H
#define MISJE_H
class Misje: public Gra
{

    bool czyWykonal_1,czyWykonal_2,czyWykonal_3,czyWykonal_4;
    int ileZabil;
    int krytyk;
    int obrona;
    int dMg;
    public:
        Misje();
        void missionOneDziki();
        void missionOneBossDzikow();
};

#endif // MISJE_H
 

Misje.cpp

#include <iostream>
#include <Windows.h>
#include "Gra.h"
#include "Misje.h"
#include <time.h>
using namespace std;

void Misje::missionOneDziki()
{
    HANDLE hout;
    hout=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hout, FOREGROUND_GREEN);
    cout << endl;
    cout << "Misja pierwsza: \n- zabic 3 dziki\n- zabic Bossa dzikow";
    cout << "\n\nAktualnie zabiles: " << ileZabil << " dzikow.";
    Sleep(4000);
    system("cls");
    srand(time(NULL));
    zyciePsa = 50;
    do
    {
        dMg = rand()%11+6;
        obrazeniaPsa = rand()%6+4;


        if(zyciePsa>=1 && zycieG>=1)
        {
            cout << "Zatakowales Dzika. Zabrales mu: " <<dMg << " punktow zycia."<<endl;
            zyciePsa-=dMg;
            cout << "Zostalo mu: " << zyciePsa << endl << endl;
            Sleep(1700);
        }
        if(zyciePsa>=1 && zycieG>=1)
        {
            cout << "Dzik na Ciebie zaszarzowal!" << endl;
            cout << "Zabral Ci: " << obrazeniaPsa<< endl;
            zycieG-=obrazeniaPsa;
            cout << "Zostalo Ci: " << zycieG << " punktow zycia" << endl<<endl;
            Sleep(1700);
        }


        else if (1>zyciePsa && zycieG>0)
        {
                SetConsoleTextAttribute(hout, FOREGROUND_RED);

            cout << "Zabiles Dzika."<<endl;
            ileZabil++;
            if(ileZabil<3)
            {
                Sleep(2500);
                system("cls");
                missionOneDziki();
            }
            else if(ileZabil==3){
        Sleep(1000);
        system("cls");
            SetConsoleTextAttribute(hout, FOREGROUND_BLUE|FOREGROUND_INTENSITY);
        cout << "Zostajesz uleczony o 30 punktow zdrowia, a miecz ulega zmianie."<<endl;
        Sleep(3500);
        missionOneBossDzikow();


            }

        }

        else if(zyciePsa>0 && 1>zycieG)
        {
            cout << "Dzik Cie zabil." << endl;
            Sleep(2500);
            system("cls");
            menuGry();
        }
    }while(zycieG>1 || zyciePsa>1);

}
void Misje::missionOneBossDzikow()
{
     HANDLE hout;
    hout=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hout, FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
    system("cls");
    cout << "AAAARGHHH (wychodzi z podziemia)"<<endl;
    zyciePsa=110;
    zycieG=130;
    Sleep(2500);
    srand(time(NULL));

    do{
            dMg = rand()%12+18  - 0.35*obrona;
    obrazeniaPsa = rand()%9+16;
    krytyk=rand()%5+1;
        if(zyciePsa>=1 && zycieG>=1)
        {
            cout << "Zatakowales Bossa Dzikow. Zabrales mu: " <<dMg << " punktow zycia."<<endl;
            zyciePsa-=dMg;
            cout << "Zostalo mu: " << zyciePsa << endl << endl;

        }
        Sleep(2200);
        if(zyciePsa>=1 && zycieG>=1)
        {
            if(krytyk==4){
            cout << "Boss dzikow uzyl specjalnego ataku!" << endl;
            cout << "Zabral Ci: " << 2*obrazeniaPsa<< " (krytycze)" <<endl;
            zycieG-=2*obrazeniaPsa;
            cout << "Zostalo Ci: " << zycieG << " punktow zycia" << endl;
            Sleep(2200);
            }else{
                cout << "Boss dzikow Cie zaatakowal!"<<endl;
                cout << "Zabral Ci: " << obrazeniaPsa << endl;
                zycieG-=obrazeniaPsa;
                cout << "Zostalo Ci: " << zycieG << " punktow zycia" << endl;
                Sleep(2200);
            }
        } else if (1>zyciePsa && zycieG>0)
        {
            cout << "Zabiles Bossa Dzikow."<<endl;
            Sleep(2000);
            cout << "Twoj ostatni cios zniszczyl Wielki Miecz." << endl;
            Sleep(1300);
            cout << "Otrzymujesz: 75 Expa i Miecz.." << endl;
            cout << "Dodatkowo twoje maksymalne punkty zdrowia wzrastaja o 10 i zostajesz uzdrowiony" << endl;
            maksZycie+=10;
            zycieG = maksZycie;
            aktualnyExp+=75;
            awans();
            czyWykonal_1=true;
            Sleep(3300);
            menuGry();
        }else if(zyciePsa>0 && zycieG<1)
        {
            cout << "Polegles w tej wlace.";
            Sleep(1300);
            menuGry();
        }

    }while(zycieG>1 || zyciePsa>1);

}
Misje::Misje()
: ileZabil(0),
obrona(12),
czyWykonal_1(false),
czyWykonal_2(false),
czyWykonal_3(false),
czyWykonal_4(false)
{
}
 

 

 

Wiec w skrocie, podczas wykonywania misji wszystkie zmienne wracają do wartości ustawionych w konstrukotrze.

Screny:

Po zabiciu psa:

 

 

Po misji:

 

 

<>

Opublikowano

w misji z bossem dzikow ustawiasz zycieG na 130, ale czemu?

 

 

maksZycie+=10;
zycieG = maksZycie;

 

a wczesniej maksZycie ustawiasz na 100, wiec potem bedzie 110, nie chce mi sie tego przekopiowywac i tworzyc projektu, jedz debuggerem krok po kroku i znajdziesz blad, ale wydaje mi sie ze blad jest tutaj

Opublikowano

Dużo tego kodu. Czemu uchwyty pobierasz w każdej funkcji klasy? Możesz użyć jej jako zmiennej składowej i zainicjować ją w konstruktorze.


Pomagam w projektach dotyczących programowania (C++/C/Java/C#/inne). Jak masz jakiś problem, napisz do mnie, wspólnie poszukamy rozwiązania ;).

Opublikowano

w misji z bossem dzikow ustawiasz zycieG na 130, ale czemu?

 

 

maksZycie+=10;

zycieG = maksZycie;

 

a wczesniej maksZycie ustawiasz na 100, wiec potem bedzie 110, nie chce mi sie tego przekopiowywac i tworzyc projektu, jedz debuggerem krok po kroku i znajdziesz blad, ale wydaje mi sie ze blad jest tutaj

zmienilem to na chwile by zrobic screena do tematu, to nic nie zmienia, to resetuje zarowno lvl (raczej wszystko co jest ustawione w konstruktorze)

 

Dużo tego kodu. Czemu uchwyty pobierasz w każdej funkcji klasy? Możesz użyć jej jako zmiennej składowej i zainicjować ją w konstruktorze.

nie pomyslalem.

<>

Opublikowano

Ciężko się przegląda jak jest tyle kodu, a praktycznie nic z niego nie podchodzi dokładnie pod problem.

Znalazłem na szybko 2 linie.

zycieG =100; //w kodzie uzdrowienia
zycieG =130; //w kodzie misji

Może to.

Opublikowano

Być może wiem - to musi być związane z tym, że klasa misje jest dziedziczona po klasie gra, co jest dość dziwną implementacją...

 

No wszystko jasne, to na pewno jest z tym związane. Tworzysz tak naprawdę dwie klasy - gra i misja, która jest dziedziczona po grze, tworzysz misję, która wykonuje cały konstruktor od nowa resetując wartości i po powrocie z misji te wartości są liczone od nowa, taka jest moja teoria.

 

Utwórz odseparowaną klasę Misja, chociażby przyjaciela klasy Gra i wkomponuj go w klasę Gra, a nie twórz na jej bazie nowej klasy, bo Misja to tak naprawdę kopia klasy gra, od której pobiera wszystkie jej właściwości. W tej grze jest to bezsensowne.


Pomagam w projektach dotyczących programowania (C++/C/Java/C#/inne). Jak masz jakiś problem, napisz do mnie, wspólnie poszukamy rozwiązania ;).

Opublikowano

Ciężko się przegląda jak jest tyle kodu, a praktycznie nic z niego nie podchodzi dokładnie pod problem.

Znalazłem na szybko 2 linie.

zycieG =100; //w kodzie uzdrowienia
zycieG =130; //w kodzie misji

Może to.

To nie jest tylko do życia bo to resetuje wszystko.

 

Być może wiem - to musi być związane z tym, że klasa misje jest dziedziczona po klasie gra, co jest dość dziwną implementacją...

 

No wszystko jasne, to na pewno jest z tym związane. Tworzysz tak naprawdę dwie klasy - gra i misja, która jest dziedziczona po grze, tworzysz misję, która wykonuje cały konstruktor od nowa resetując wartości i po powrocie z misji te wartości są liczone od nowa, taka jest moja teoria.

 

Utwórz odseparowaną klasę Misja, chociażby przyjaciela klasy Gra i wkomponuj go w klasę Gra, a nie twórz na jej bazie nowej klasy, bo Misja to tak naprawdę kopia klasy gra, od której pobiera wszystkie jej właściwości. W tej grze jest to bezsensowne.

Nie jestem pewien czy to wina akurat konstruktora, ponieważ jak zadeklarowałem wartości w .h i konstruktora w ogóle nie miałem działało to tak samo. Co do tworzenia frienda to nie wiem jakbym miał zrobić by przejmował też zmienne z tej klasy.

<>

Opublikowano

To nie jest tylko do życia bo to resetuje wszystko.

 

Nie jestem pewien czy to wina akurat konstruktora, ponieważ jak zadeklarowałem wartości w .h i konstruktora w ogóle nie miałem działało to tak samo. Co do tworzenia frienda to nie wiem jakbym miał zrobić by przejmował też zmienne z tej klasy.

 

Chyba źle zinterpretowałeś to, co do ciebie mowię. Problem nie leży w konstruktorze, ale w dziedziczeniu i przez to klasa Misje JEST klasą Gra. Dokładnie ten moment:

class Misje : public Gra

Świadczy o tym, że nie za bardzo kminisz, o co biega w dziedziczeniu. Wywoływany jest wtedy konstruktor klasy Gra od nowa dla klasy Misje. Wszystkie metody, funkcje zmienne publiczne bądź prywatne będą wtedy dostępne w klasie pochodnej.


Pomagam w projektach dotyczących programowania (C++/C/Java/C#/inne). Jak masz jakiś problem, napisz do mnie, wspólnie poszukamy rozwiązania ;).

Opublikowano

Ale powinien się on wykonać na rzecz obiektu klasy Misje, a nie istniejącego obiektu klasy Gra.

 

Co nie zmienia faktu, że hierarchia jest bez sensu.

 

I nie rób tak, że wywołujesz tak funkcję (wracasz do menu) np w takim przypadku

void Gra::walczZPsem()

{

...

menuGry();

}

 

Bo

1. Jest to bez sensu, funkcja ma zrobić co do niej należy i się skończyć.

2. Jak bardzo dużo razy zawalczysz to będziesz miał stack overflow

3. Zmniejszasz czytelność kodu.

Opublikowano

Ale powinien się on wykonać na rzecz obiektu klasy Misje, a nie istniejącego obiektu klasy Gra.

 

 

No właśnie. Po utworzeniu obiektu mis wywołany został konstruktor klasy gra "resetujący" wszyskie zmienne, a tak naprawdę tworzącą nową klasę, a po wywołaniu 

Misje::missionOneDziki()

w funkcji Gra::misje() już w nim zostaje, przez co po wywołaniu funkcji menuGry() zostaje na obiekcie mis i wyświetla takie, a nie inne wartości. Wartości wywołane we wcześniejszej klasie zostają, nie resetują się wbrew pozorom, ale są zastąpione przez nową klasę, właśnie Misje.


Pomagam w projektach dotyczących programowania (C++/C/Java/C#/inne). Jak masz jakiś problem, napisz do mnie, wspólnie poszukamy rozwiązania ;).

Opublikowano

Dobra rozumiem o co ci chodzi. Że potem odnosi się do składowych instancji klasy Misja, a nie Gra. Teraz to się układa rzeczywiście.

Ale można skomplikować kod przez takie głupie dziedziczenie.

 

A autorowi radzę napisać to jeszcze raz od zera porządnie.

Opublikowano

Każda tego typu aplikacja musi zawierać pętlę nieskończoną, bo inaczej się wyłączy (poprawcie mnie jeśli się mylę). 

 

W twoim przypadku, po wykonaniu każdej misji, tworzony jest nowy obiekt klasy Misje. Misje tworzą Misje tworzą Misje...

 

Podejście marksistowskie do informatyki ( wszystko jedna klasa ) na dłuższą metę się nie sprawdza. Pamiętaj! Trzy godziny kodzenia mogą zaoszczędzić piętnaście minut myślenia! 

 

Żeby się nie zajebać potrzebujesz: 

 

1. Klasy do obsługi menu. Wyświetlanie i pobieranie informacji od gracza powtarza się dużo razy, zawsze w takiej samej formie. Opakuj to w klasę. A przynajmniej funkcję. 

 

2. Klasę reprezentującą gracza ( class Gracz - na potrzeby rozważań ) i wszystkie informacje o nim ( w tym XP, na potrzeby rozważań ). 

 

3. Teraz trzeba się zastanowić, jak powinny być reprezentowane misje. IMHO nie potrzeba do tego klasy, wystarczy funkcja. Zdefiniujmy więc function pointer type



typedef void(*FunctionMisjaPtr)(Gracz&);

4. Zaprojektowaliśmy jednolity sposób reprezentowania misji. Co się bardzo przyda, to wektor z misjami ( wektor to taka tablica o zmiennej długości ). Dzięki temu dodając nową misję, modyfikujemy jedno miejsce w kodzie, a nie dwadzieścia. 



std::vector<FunctionMisjaPtr, std::string> ListaMisjiDoZrobienia;

Tworząc nową misję, wystarczające będzie zdefiniowanie funkcji, reprezentującej przebieg misji, oraz dodanie jej do wektora: 



void ZabijPsy(Gracz& obiektGracza) {  
   .... 
   obiektGracza.DodajExp(100); 
   .... 
}
 
ListaMisjiDoZrobienia.push_back( ZabijPsy, "Nazwa misji prezentowana w menu" );

5. Teraz w "głównym kodzie", w momencie zaprezentowania użytkownikowi listy misji wystarczy przeiterować przez nasz wektor, wyświetlić nazwy misji, pobrać wybór i wywołać odpowiednią funkcję. Po jej wykonaniu, przekazany do niej obiekt Gracz ulegnie zmianie. Należy wtedy sprawadzić czy HP > 0 i dalej kontynuować. 

 

 

Omówmy co jest złego w takim rozwiązaniu ( największym plusem jest oczywiście prostota ): 

- Wszystkie misje mogą pobierać wyłącznie obiekt gracza ( brak możliwości przekazania dodatkowych informacji DO funkcji wywołującej misję ) 

- W wektorze obok wskaźników na misje przechowujemy tylko ich nazwę ( brak możliwości zamieszczenia, na przykład, fabularnego opisu czy informacji o poziomie trudności - brak możliwości pobrania informacji OD misji ) 

- W przypadku, gdybyśmy chcieli zmodyfikować którąś z powyższych dwóch cech, musimy zmodyfikować wszystkie misje na raz. 

 

Rozwiązaniem dwóch ostatnich problemów jest oczywiście polimorfizm. Deklarujemy czysto abstrakcyjną klasę bazową reprezentującą misję. Tworzymy listę abstrakcyjnych misji. Każdą misję definiujemy jako pochodną klasy abstrakcyjnej. 

 

Rozwiązanie pierwszego to stworzenie pomocniczego kontenera, który będzie zawierał informacje przesyłane do misji. Tworząc nową klasę misji (która wymaga więcej informacji, nie tylko o Graczu), rozszerzamy tylko kontener o dodatkowe pola. ( Chwilę się głowię, czy nie istnieje jakieś lepsze rozwiązanie - jeśli ktoś się nie pogubił, proszę zwrócić mi uwagę ). 

 

Trzeba jednak trochę o tym wiedzieć i przed tobą dużo nauki, wykraczającej poza zamiar tego posta. Rozwiązanie z wektorem wskaźników na funkcję powinno jednak - jak na poziom prezentowany przez twój kod - być całkowicie wystarczające. 

 

 

--- 

 

@EDIT: 

 

Potrzebujesz oczywiście mapy, a nie wektora ( ewentualnie stworzyć krotkę ): 

std::map<FunctionMisjaPtr, std::string> ListaMapy;
ListaMapy.insert( std::pair<FunctionMisjaPtr, std::string>(ZabijPsy, "Nazwa misji prezentowana w menu") );

Głupi język. 

 

 

@EDIT2: 

 

W zasadzie, jeśli już tak to robić, to tak:

 

 

typedef std::pair<FunctionMisjaPtr, std::string> MisjaZOpisem;
std::vector< MisjaZOpisem > Misje;
myVector.push_back( MisjaZOpisem(ZabijPsy, "Opis w Menu") );

Ta sygnatura jest pusta.

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...