Interdependent Classes

Pages: 123
Ok, so I have a class Player and a class Potion, and Potion affects Player, but Player holds and uses Potion; how do I declare them in a way that that doesn’t break? Is a forward declaration enough? The trouble is I’m using a function of Potion, so idk if that works...


Example:
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
// Player.h
//============================
class Potion;

class Player {
  // ...
  void drink(Potion p) {
    p(this);
  }
  // ...
};
//============================

// Potion.h
//============================
#include "Player.h"

class Potion {
  // ...
  void operator() (Player* p) {
    p.damage(34,"fire");
    p.setArmor(p.getArmor() + 34);
  }
  // ...
};
//============================ 
Last edited on
Why can't you do:

1
2
    p.damage(34,"fire");
    p.setArmor(p.getArmor() + 34);


in Player?
Your class hierarchy is difficult to understand.
Why do Potion and Item need to know about Player?
Easier seems:
1
2
3
4
5
6
7
8
9
10
11
12
class Potion
{};

class Player
{
public:
  void add_potion(Potion p);
  void drink_potion(); // or maybe use_potion
  bool has_potion();
private: 
  Potion potion;
}
Gah! Fell asleep f. Um. Oops, typo. The item class is unrelated. That was supposed to say class Potion, not class Item. :/ really sorry!
@rozick1 because it’s not a function of player...? What do you mean?
@Learner2

But that lacks the intended functionality completely. How is it better or easier? I don’t think I understand.
I think I can explain better when you show me all the classes and explain the game.
An important part to understand is the relationship between classes. You have 2 relationships:
is-a and has-a. For example Player has potion and Items. A weapon is an Item.
Player needs to know Item, but Item doesn't need to know Player.
All I have atm is this:

class Entity;
class Player    extends Entity;
class NonPlayer extends Entity;
class Vehicle   extends Entity;
class Object    extends Entity;
class Wall      extends Object;


class Item;
class Buff   extends Item;
class Armor  extends Item;
class Weapon extends Item;
class Potion extends Item;

class World;


I really haven’t gotten far, I just stumbled across this dilemma while looking ahead. I don’t really have Potion implementation yet, so I’m just basically anticipating stuff I guess :/


Edit: also yes I know non of that is valid C++ syntax, it’s just describing how the inheritance hierarchy will look.
Last edited on
The inheritance looks ok. Maybe distinguish between moving(i.e. acting entities) and immobile entities like wall.
To the has-a relationships:
Player has a collection of items
World has a Player, somethings seems to be missing, maybe a room or scene.
That’s why Wall is a child of Object specifically and not just straight up Entity. :)

Hm ok, so maby I should make a list of is-a has-a relationships? Also yeah I’m not sure how I’m gonna make the room class yet.. it’s an Object and has walls I guess...? World is supposed to have all entities, here, I’ll write up another list....
Em.. so maybe this?
class Entity;
class Player    extends Entity; // has Items and Buffs
class NonPlayer extends Entity; // has Items and Buffs
class Vehicle   extends Entity;
class Object    extends Entity;
class Wall      extends Object;
class Room      extends Object; // has ...Entities? 


class Item;
class Buff   extends Item;
class Armor  extends Item; // has Buffs
class Weapon extends Item; // has Buffs
class Potion extends Item; // has Buffs Edit: or actually maybe is a Buff?


class World; // has Rooms?
Last edited on
Yes, World has a player and and has rooms or scenes.
A room has a name, maybe a desciption, entities, links to rookms(exits) and maybe sth. else depending on your games.

You also need tothink about the responsibilities of the classes.
@Learner2 This is taking longer to write up than expected sorry for the long wait gaps I’ll have something tmrw.

@Alisa what does this have to do with this question? Very confused.
Take your time, there is no reason to hurry.
Thanks :)
This is what I’ve thought up so far:

class Entity;
    -    Just a mostly empty class used purely as a polymorphic container.
    -    Anything that is a physical thing in a world that can be interacted with
    -    Declares move() and damage() primitives

class Player    extends Entity;
    -    The actual Users are defined using this. 
    -    It’s a fully fledged class.
    -    can hold any Item, can move, can shoot, can talk... all that good stuff. (I couldn’t think of what else they could do.. 😬)

class NonPlayer extends Entity;
    -    All NPCs inherit from this class, it is mostly empty, adding maybe a couple more primitives like, say, react() or attack()

class Vehicle   extends Entity;
    -    Mostly a polymorphic base class like Entity and NonPlayer.
    -    Can hold any Entity
    -    Maybe defines some more primitives like start() or mount()

class Object    extends Entity;
    -    An Entity generally incapable of moving itself (so anything not alive) should be of this class.
    -    It’s just a base class like Entity and Vehicle
    -    I’ll probably define the damage() primitive as doing nothing.

class Wall      extends Object;
    -    Entirely immovable. Like Objects can be moved by ppl, but these can’t be moved at all.
    -    Can’t take damage, don’t do anything. Simply an obstacle.
    -    Literally just takes up space
    -    Fully fledged class

class Room extends Object;
    -    has Walls.
    -    has Any Entity
    -    handles detecting collisions (mostly..kinda)



class Item;
    -    basic polymorphic class like Entity.
    -    Essentially just the opposite of Entities.
    -    Declares a single primitive: typeof()

class Buff   extends Item;
    -    Basic polymorphic class like Item.
    -    add the primitives start() and stop()
    -    effects something in some undetermined way. (ehhh hard to explain..)
    -    Example: HpBuff: would add to a player’s maximum hp on start(), and subtract it on stop().

class Armor  extends Item;
    -    protects Players and NonPlayers in some way. Probably going to be like permanent HpBuffs or something idk yet. 
    -    Also a more polymorphic class like Buff or Item
    -    Probably going to add the don() and doff() primitives.

class Weapon extends Item;
    -    Purely polymorphic class like Armor or Item
    -    Damages things.
    -    adds primitive attack()

class Potion extends Item;
    -    Purely polymorphic class like Armor or Item
    -    Basically Buffs, but timed.
    -    Adds the drink() primitive



class World;
    -    has Rooms
    -    is basically just a network of Rooms



Edit: Actually I’m starting to see that Player and NonPlayer are having way to many crossovers, so I’m actually probably gonna make Player a polymorphic base class from which a class User and another polymorphic base class Character, to represent PCs and NPCs, respectively.

This is getting really complicated.
Last edited on
Is it a multi-player game or 1 player against the computer?
I see one problem. Wall->Object->Entity.
This means Wall inherits methods like move() and damage().
It's too high in the hierachy for doing nothing.
1) ehhh multiplayer is the goal, but idk the sense of the added complexity of it is kinda hard to get past.... so I guess it will begin as a one player..?? Idk if that even makes sense.

2) It does inherit them, it’s just that neither of them actually affects the Wall, they just have empty bodies. You have a good point it is pretty high, but I’m not sure how else to fit it in. The problem is it is an object, because an Object can’t move by itself, and it is an Entity because it takes up space so I’m not sure what to do there... I feel like I’d be duplicating stuff if I moved it away... where else do you suggest I put it?
Last edited on
I am not sure yet. Maybe have 2 classes inherit from the base: moving and non-moving so Wall would inherit from non-moving. I need to think more about it.
Ok.

Hum... maybe like this?

class basic_entity {
  virtual void move(double x, double y) = 0;
};

class mobile_entity extends basic_entity {
  double m_x, m_y;
  void move override(double x, double y) {
    m_x += x;
    m_y += y;
  }
};

class immobile_entity extends basic_entity {
  void move(double x, double y){}
};


Just split right up? 🤷‍♂️
Last edited on
Pages: 123