Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Beneroth

Alter Hase

Beiträge: 969

Wohnort: Schweiz

Beruf: Software Entwickler

  • Private Nachricht senden

21

10.07.2008, 22:27

hm, bei deinem Vorhaben..

ich schätze dass kann man entfernt mit dem weiterentickeln der pokémon vergleichen, oder?

anstatt für jeden typ ne klasse zu machen, mache (falls es bei deinem vorhaben geht) lieber eine abstrakte klasse bzw. liste von klassen, die jeweils ein einheitliche funktionen haben und ihre jeweiligen werte und bedingungsvariablen als membervariablen speichern (bzw. als Endlicher Automat implementieren?)

so ein system liesse sich auch viel einfacher auf ganz viele mutierte tiere erweitern, indem du die induviduellen eigenschaften schlicht nur als daten verwendest.

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

22

10.07.2008, 22:41

Vielleicht wäre eine einfache komposition hier die schnellste Lösung.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Tier {
virtual void test() = 0;
};
class DummTier: public Tier {
    int leben;
    DummTier() : leben(100) {}

    void test() {
        std::cout << leben << std::endl;
    }
};

class SchlauTier: public Tier {
    int hirn;
    Tier* tier;

    SchlauTier(Tier* _tier) :  hirn(10), tier(_tier) {}

    void test() {
        std::cout << tier->leben << ", " << hirn << std::endl;
    }
};

So kannst du jedes beliebige Tier um die Eigenschaften des SchauTiers erweitern. Mit Vererbung kannst du da nicht arbeiten.

PS: Zum thema java und abgestumpft.. in Java würdest du bei deinem Vorhaben eine ClassCastException kriegen

Ba'el

Alter Hase

Beiträge: 409

Wohnort: Erfurt

Beruf: Student (6 FS angew. Info. - Richtung Medieninformatik)

  • Private Nachricht senden

23

10.07.2008, 22:43

stimmt das ist irgendwie logisch ... aber ich hab das mit dem cast ja auch net vorgeschlagen ;P *schuld wegschieb*

ich würd es auch nit so machen, einfach weil ist casts nicht mag ... persönlich würd ich's warscheinlich irgendwie so machen

C-/C++-Quelltext

1
2
3
4
5
6
7
8
Tier* tier = new Tier();

//[...] Mutation


SuperTier super = new SuperTier();
super->setLebenspunkte(tier->getLebenspunkte());
//[...] noch andere Variablen

delete tier;
aktuelle Projekte:
Ruby on Rails
XNA &amp; Touchless
Progr. mobiler Endgeräte (GPS Trekking)

24

11.07.2008, 07:35

Da du das zur Laufzeit willst, würde ich dir das Strategy Pattern nochmal ans Herz legen.

Du hättest eine Klasse Tier und verschiedene Verhaltensmuster, z.B. RunBehaviour, FightBehaviour, RoarBehaviour, die dann ungefähr alle so aussehen:

Quellcode

1
2
3
4
5
class RunBehaviour 
{
public:
    virtual void run() = 0;
};



Und dein Tier schaut so aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Animal
{
private:
   RunBehaviour *rb;

public:
    Animal() 
    {
       rb = new DefaultRunBehaviour(); 
    }

    void run() 
    {
        rb->run();
    }

    void setRunBehaviour(RunBevhaviour *rb) { this->rb = rb; }
};

25

11.07.2008, 08:54

Zitat

Dynamisches Vererben geht nicht und macht auch gar keinen Sinn.
Versuchs doch mal mit Komposition.
Oder du erzeugst in dem Moment, wo das Spielobjekt sich verändert, einfach ein neues Objekt.


jein, in manchen sprachen gibt es mixins, die auch ganz nützlich sind...
damit könntest du dann sowas sogar ziemlich genau so machen, wie du es mommentan machen willst, aber in C++ geht sowas net, da das ja ordentlich kompilieren muss...(python wär so n kandidat)

bei dem vorschlag strategy würd ich n bissl drüber nachdenken...das kann das richtige sein, aber damit kannst du nur verhalten variieren, also nicht direkt überladen, nur ändern... damit denke ich, wirds schwierig, schaf+huhn zu kombinieren...
betrachte mal decorator, ev is das hier sogar besser...

Ba'el

Alter Hase

Beiträge: 409

Wohnort: Erfurt

Beruf: Student (6 FS angew. Info. - Richtung Medieninformatik)

  • Private Nachricht senden

26

11.07.2008, 09:18

so nachdem ich ne Nacht drüber geschlafen hab, und mit erschrecken feststellen musste was ich wieder für scheiß geschrieben hab, hier mein Vorschlag vom letzten Post etwas ausführlicher und an dein vorhaben angepasst

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include<iostream>

class Tier
{
protected:
    int defence;
public:
    Tier():defence(60){}
    virtual ~Tier(){}
    int getDefence(){return defence;}
    void setDefence(int defence){this->defence = defence;}
    void mutation(Tier* ziel)
    {
        ziel->setDefence(this->defence);
    }
};

class SuperTier : public Tier
{
protected:
    int attack;
public:
    SuperTier():attack(70){}
    ~SuperTier(){}
    int getAttack(){return attack;}
    void setAttack(int attack){this->attack = attack;}
    void mutation(SuperTier* ziel)
    {
        ziel->setDefence(this->defence);
        ziel->setAttack(this->attack);
    }
};

class SuperSuperTier : public SuperTier
{
protected:
    int specialeAttack;
public:
    SuperSuperTier():specialeAttack(130){}
    ~SuperSuperTier(){}
    int getSpecialeAttack(){return specialeAttack;}
    void setSpecialeAttack(int specialeAttack){this->specialeAttack = specialeAttack;}
    void mutation(SuperSuperTier* ziel)
    {
        ziel->setDefence(this->defence);
        ziel->setAttack(this->attack);
        ziel->setSpecialeAttack(this->specialeAttack);
    }
};

class SuperSuperTierV2 : public SuperTier
{
protected:
    int specialeAttack;
public:
    SuperSuperTierV2():specialeAttack(140){}
    ~SuperSuperTierV2(){}
    int getSpecialeAttack(){return specialeAttack;}
    void setSpecialeAttack(int specialeAttack){this->specialeAttack = specialeAttack;}
    void mutation(SuperSuperTierV2* ziel)
    {
        ziel->setDefence(this->defence-10);
        ziel->setAttack(this->attack+10);
        ziel->setSpecialeAttack(this->specialeAttack);
    }
};

class EndTier : public SuperSuperTier
{
private:
    int specialeDefence;
public:
    EndTier():specialeDefence(150){}
    ~EndTier(){}
    void print()
    {
        std::cout<<this->defence<<std::endl;
        std::cout<<this->attack<<std::endl;
        std::cout<<this->specialeAttack<<std::endl;
        std::cout<<this->specialeDefence<<std::endl;
    }
};

class EndTierV2 : public SuperSuperTierV2
{
private:
    int specialeDefence;
public:
    EndTierV2():specialeDefence(140){}
    ~EndTierV2(){}
    void print()
    {
        std::cout<<this->defence<<std::endl;
        std::cout<<this->attack<<std::endl;
        std::cout<<this->specialeAttack<<std::endl;
        std::cout<<this->specialeDefence<<std::endl;
    }
};

int main()
{
    Tier* tier = new Tier();

    //Mutation


    SuperTier* sutier = new SuperTier();
    tier->mutation(sutier);
    delete tier;

    //weiere Mutation


    SuperSuperTier* susutier = new SuperSuperTier();
    sutier->mutation(susutier);
    delete sutier;

    //letzte Mutation

    EndTier* etier = new EndTier();
    susutier->mutation(etier);
    delete susutier;

    etier->print();
    delete etier;

    //anderer Mutationsstrang


    Tier* tierv2 = new Tier();

    //Mutation


    SuperTier* sutierv2 = new SuperTier();
    tierv2->mutation(sutierv2);
    delete tierv2;

    //weiere Mutation


    SuperSuperTierV2* susutierv2 = new SuperSuperTierV2();
    sutierv2->mutation(susutierv2);
    delete sutierv2;

    //letzte Mutation

    EndTierV2* etierv2 = new EndTierV2();
    susutierv2->mutation(etierv2);
    delete susutierv2;

    etierv2->print();
    delete etierv2;

    return 1;
}
aktuelle Projekte:
Ruby on Rails
XNA &amp; Touchless
Progr. mobiler Endgeräte (GPS Trekking)

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

27

11.07.2008, 10:48

Pattern die sich gut eignen würden wären strategy, builder und composition.

Mal ein paar Überlegungen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
class IBehavior
{
public:
    virtual void Execute() = 0;
};


class Creature;
class CreatureMutator;

class IMutator
{
    friend class CreatureMutator;

public:
    virtual void Mutate( Creature* creature )    = 0;

private:
    virtual void NextMutator( CreatureMutator* mutator ) = 0;
};

class EatBehaviorDefault : public IBehavior
{
public:
    void Execute()
    {
        printf( "...\n" );
    }
};

class EatBehaviorCow : public IBehavior
{
public:
    void Execute()
    {
        printf( "... isst Grass\n" );
    }
};

class EatBehaviorSheep : public IBehavior
{
public:
    void Execute()
    {
        printf( "... isst Grass\n" );
    }
};

class EatBehaviorPig : public IBehavior
{
public:
    void Execute()
    {
        printf( "... isst Trueffel und Abfaelle\n" );
    }
};

class EatBehaviorChicken : public IBehavior
{
public:
    int x;
    EatBehaviorChicken( int value ) : x( value )
    {
    }

    void Execute()
    {
        printf( "... isst %d Koerner\n", x );
    }
};

enum EBehaviorAction
{
    BEHAVIOR_EAT = 0
    // weitere

};

class Creature
{

public:
    typedef IBehavior* BehaviorPtr;
    typedef std::map< EBehaviorAction, std::vector< BehaviorPtr > > BehaviorList;

    Creature()
    {
    }

    ~Creature()
    {
        // ggf aufräumen etcpp...

    }

    void PushBehavior( EBehaviorAction action, BehaviorPtr behavior )
    {
        // hier ggf noch prüfen ob _dieser_ verhaltenstyp bereits vorhanden

        m_actionMap[ action ].push_back( behavior );
    }

    void RemoveBehavior( EBehaviorAction action, BehaviorPtr behavior )
    {
        // TODO: implementieren

    }

    void ExecuteBehavior( EBehaviorAction action ) const
    {
        BehaviorList::const_iterator it = m_actionMap.find( action );

        if ( it != m_actionMap.end() )
        {
            const std::vector< IBehavior* >& tmp = ( *it ).second;
            std::for_each( tmp.begin(), tmp.end(), std::mem_fun( &IBehavior::Execute )  );
        }
    }

private:
    BehaviorList m_actionMap;
};

class CreatureMutator
{
private:
    IMutator* m_pMutationRule;   // evtl auch liste von mutatoren


public:
    CreatureMutator() : m_pMutationRule( NULL )
    {
    }

    void NextStage( Creature* creature )
    {
        if ( !m_pMutationRule )
            return;

        m_pMutationRule->Mutate( creature );
        m_pMutationRule->NextMutator( this );
    }
};


Jede 'Kreatur' bekommt eine Liste von Verhaltensaktionen. Jedes Aktion kann aus einer oder mehren Merkmalen bestehen die über die Spezialisierungen von IBehavior festgelegt werden können.

Um eine 'Kreatur' mutieren zu lassen müssen regeln definiert werden. Das kann in Speziellen IMutator Klassen gemacht werden, wobei jede dieser Klassen weiß welche Mutatoren für das nächste Stadium in Frage kommen (über NextMutator() abfragbar). Der Builder (oder CreatureMutator) erlaubt es dann Tiere, anhand dieser Richtlinie, mutieren zu lassen.

Das Ganze ist natürlich stark ausbaubar aber ziemlich flexibel. Trotzdem bleibt viel Tipparbeit und vorallem sollte man sich im Vorfeld genau überlegen was für 'Eigenschaften' für die 'Kreaturen' verfügbar sein müssen.
@D13_Dreinig

Viktor

Alter Hase

  • »Viktor« ist der Autor dieses Themas

Beiträge: 533

Wohnort: Ludwigshafen

Beruf: Student

  • Private Nachricht senden

28

11.07.2008, 11:37

Hui, vielen dank erstmal. Muss mich da jetzt erstmal durcharbeiten und schauen, was am besten passt.

Werbeanzeige