Reputation: 103
Note that this is not an inheritance or interface.
I have a class HP
public class HP
{
public int Base;
public int Value
{
get
{
//Need to access Monster.Level to calculate total HP.
}
}
}
And a class Monster
calling HP
public class Monster
{
public HP hp;
public int Level;
}
How can I access Monster.Level from HP?
I tried to pass Level
by reference to HP
upon instantiating.
public class HP
{
private ref int Level;
public A(ref i)
{
Level=i;
}
}
But I want to keep A as simple and clean as possible.
The reason I don't want to pass the level upon creation is Level
is a constantly changing valuable, I'll will then have to "update" the HP
every time the monster gains a level or something, which is NOT a efficient way to do things.
And there are other things accessing Level
, such as Attack
and Damage
, etc.
I currently has a method within HP
, Attack
, Damage
, etc., taking the Level
as a parameter.
public int Value(int lv)
{
return Base+10*lv;
}
But according to the a little bit of SOLID principle I know, this is a VERY BAD coding!
Upvotes: 3
Views: 138
Reputation: 816
You must look into tutorials that explain classes. It is of utmost importance that you understand the concept. But according to the a little bit of SOLID principle I know, this is a VERY BAD coding!
SOLID comes after you have understood the concepts around classes, structs, properties, interfaces, polymorphism, and acquired a general knowledge of what these things are and how they work. Forget SOLID for now, pick it up again after several months of learning.
Let me show you how to do the code properly:
First of all, you don't use its own class for HP. That makes little to no sense unless you know what you are doing and have a good reason. Keep it simple:
public class Monster
{
public int HP;
public int MaxHP;
public int Level;
}
You just tried to wrap HP into its own class, and it basically is just an integer anyway.
To answer your question about how to use it:
This is a class that contains some unit information:
public class UnitStats
{
public int HP;
public int Energy;
public int Level;
}
Now, as of your unit class:
public class Monster
{
public UnitStats Stats;
public string Name;
public void Setup (int hp, int level, string name)
{
Stats = new UnitStats (); // Create an instance/object of the class.
Stats.MaxHP = hp; // Set its values.
Stats.HP = hp;
Stats.Level = level;
Name = name;
}
}
Hint: Do not use an own class for every unit. Find a common class in which you can define every unit.
Hint 2: I intentionally didn't use properties. But normally you never use public fields, only public properties. In Unity you use public fields to expose them in the inspector, this is the only valid case I know of.
Upvotes: 0
Reputation: 117055
If you're trying to avoid inheritance, then this should do the kind of thing that you want:
public class Monster
{
public int Level { get; set; }
private MonsterHitPointCalculator _hp = new MonsterHitPointCalculator();
public int HitPoints => _hp.Compute(this);
}
public class MonsterHitPointCalculator
{
private int _base = 42;
public int Compute(Monster actor) => this._base + 10 * actor.Level;
}
But, I think, in your case inheritance is the way to go. Try this instead:
public abstract class Actor
{
protected int _base = 42;
public int Level { get; set; }
public virtual int HitPoints => _base + this.Level;
}
public class Monster : Actor
{
public override int HitPoints => _base + 10 * this.Level;
}
public class Human : Actor
{
public override int HitPoints => base.HitPoints + 20;
}
In both cases the following code can be used to get the same example result:
var monster = new Monster();
monster.Level = 1;
Console.WriteLine(monster.HitPoints);
monster.Level = 2;
Console.WriteLine(monster.HitPoints);
It outputs:
52
62
Upvotes: 1
Reputation: 11
How about a solution like this
public class HP
{
private Monster _monster;
public HP(Monster monster)
{
this._monster = monster;
}
public int Base;
public int Value
{
get
{
Console.WriteLine(_monster.Level);
}
}
}
then the monster class can be like this
public class Monster
{
public HP hp;
public int Level;
public Monster(int level)
{
this.Level = 10;//can be set to level ,this is for testing.
hp = new HP(this);
}
}
This is not a very good solution , you should really consider using inhertance imo.
Upvotes: 1
Reputation: 56
It seems like what you called HP
is more of a HPCalculator
responsible of calculating Monster's HP based on this Moster's level and possibly other data in the future, I think it seem crucial for such HPCalculator
to have access to the Monster
of which health it calculates.
In C#
classes are done by references not by values meaning you can in no problem have something like this:
public class Monster{
public HP hp;
}
public class HP{
public Monster monster;
}
Upvotes: 2