Делал текстовую игру для практики кодирования и столкнулся с действительно странной проблемой. Я искал это, но большинство людей пытаются клонировать один объект в другой, тогда как я пытаюсь указать объект B на объект A, потому что я хочу изменить свойства одного и того же объекта.
public Armor Player_Chest_Armor { get; set; }
public Armor Player_Head_Armor { get; set; }
public Armor Player_Legs_Armor { get; set; }
public Weapon Player_Weapon { get; set; }
public Spell Player_Spell { get; set; }
public List<Consumable> Consumables { get; set; }
public List<IEquipment> Inventory { get; set; }
[JsonConstructor]
public Player (string name) {
this.Name = name;
this.Consumables = new List<Consumable>();
this.Inventory = new List<IEquipment>();
this.Inventory.Add(new Weapon("bronze sword", 22, 28, 25, 1.2, false));
this.Inventory.Add(new Armor("bronze chestplate", Armor.ArmorSlot.Chest, 35, 10, 20, false));
this.Inventory.Add(new Armor("bronze helmet", Armor.ArmorSlot.Head, 12, 3, 7, false));
this.Inventory.Add(new Armor("bronze legplates", Armor.ArmorSlot.Legs, 20, 5, 10, false));
this.Consumables.Add(new Consumable("minor health potion", 3, Consumable.PotionType.Health, 50));
this.Consumables.Add(new Consumable("minor mana potion", 3, Consumable.PotionType.Mana, 50));
this.Player_Spell = new Spell("Fireball", 50, 0, 1);
}
public void EquipInitialGear() {
this.EquipWeapon(this.Inventory[0] as Weapon);
this.EquipArmor(this.Inventory[1] as Armor);
this.EquipArmor(this.Inventory[2] as Armor);
this.EquipArmor(this.Inventory[3] as Armor);
}
public void DecreaseArmorDurability() {
try {
this.Player_Chest_Armor.DecreaseDurability();
}
Это соответствующая часть кода из моего класса игрока. Player_ что угодно для вещей, которыми экипирован игрок, будь то доспехи, оружие и т. д. Я использую интерфейс IEquipment для соединения объектов доспехов и оружия в один список, поскольку инвентарь игрока должен включать все. Когда игрок создан, вызовы методов EquipWeapon и EquipArmor устанавливают эти объекты индекса инвентаря в соответствующий слот брони/оружия игрока. Код для этого ниже и для простоты предположим, что нет уже экипированного оружия, поэтому он переходит прямо к строке this.Player_Weapon = weapon.
public void EquipWeapon(Weapon weapon) {
if (weapon.IsEquipped() == true) {
Console.WriteLine("You have already equipped {0}.", weapon.GetName());
return;
}
try {
if (this.Player_Weapon.Equipped == true) {
this.UnequipWeapon(this.Player_Weapon);
}
}
catch(NullReferenceException) {}
this.Player_Weapon = weapon;
weapon.Equipped = true;
Console.WriteLine("You have equipped {0}.", this.Player_Weapon.GetName());
}
Когда я пытаюсь изменить значение свойства, скажем, Player_Weapon, оно изменяется для этого объекта, но объект в инвентаре (который должен быть таким же) имеет исходное значение свойства. Уменьшение прочности делает следующее в классе оружия:
public void DecreaseDurability() {
this.Durability -= 1;
}
В каждом раунде атаки я вызываю этот метод, чтобы уменьшить прочность оружия на 1 из максимальных 100. В режиме отладки я вижу, где this.Player_Weapon.Durability меняется со 100 до 99. Однако, если я посмотрю на что должен быть тот же объект в инвентаре, его долговечность равна 100, что заставляет меня думать, что он создает копию объекта вместо ссылки на исходный объект.
Я убежден, что это проблема с указателем, но я просто не вижу, в чем проблема. Я хочу, чтобы изменения свойств Player_Weapon также влияли на изменения того же объекта этого оружия в инвентаре, на который он должен указывать.
Отредактировано для ясности: игрок, оружие и доспехи — это все классы, а не структуры.
ref
. - person   schedule 20.12.2019Weapon
этоclass
, а неstruct
, верно? - person Fildor   schedule 20.12.2019Player.Player_Weapon
должен ссылаться на тот же экземплярWeapon
, что иPlayer.Inventory[0]
, как вы говорите. Должно быть что-то еще, где-то еще. - person Fildor   schedule 20.12.2019Player_Weapon
является r/w, а должен быть доступен только для чтения. Единственным местом, где должно быть разрешено устанавливать свойствоPlayer_Weapon
, должен быть методEquipWeapon
. Сделайте его{get; private set;}
и посмотрите, где он сломается. - person Fildor   schedule 20.12.2019Player_Weapon
вообще. Может быть, просто сохраните индекс в инвентаре, отметив предмет, который является оружием игрока. Но я забегаю вперед... - person Fildor   schedule 20.12.2019