免责声明
您可以使用此模型来实现您所需的功能。请注意,与任何设计一样,它可能存在缺陷。它旨在帮助您解决问题,而不是作为解决方案。
武器
这个类代表了您应用程序中的武器。
请注意重写方法以正确实现比较、搜索和索引。
public class Weapon
{
public Weapon(WeaponName name)
{
Name = name;
}
public WeaponName Name { get; set; }
public int Priority { get; set; }
public int MaxAmmoQuantity { get; set; }
public int CurrentAmmoQuantity { get; set; }
public override string ToString()
{
return Enum.GetName(typeof(WeaponName), Name);
}
public override bool Equals(object obj)
{
if (obj == null) return false;
var other = obj as Weapon;
if (other == null) return false;
return Name == other.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
武器名称
针对武器名称的固定选项(假设,如您所说,它们的选项是有限的)
public enum WeaponName
{
Pistol,
Shotgun,
Rifle,
Bow,
RocketLauncher
}
玩家
请注意:
- 在内部,您可以按照自己喜欢的结构存储武器,但对于外部世界,只发布IEnumerable实例
- 它代表了玩家可以抓取武器或更改活动武器的事实(在此,您可以添加任何所需的操作)。通过事件,玩家向外界传达他的行动。
您正在为对象提供具有语义的方法。而不是player.Weapons.Add,您正在明确玩家的行为。
public class Player
{
private readonly IList _ownedWeapons = new List();
protected Weapon ActiveWeapon { get; private set; }
public IEnumerable<WeaponName> OwnedWeapons { get; set; }
public event EventHandler<WeaponEventArgs> WeaponGrabbed;
public event EventHandler<WeaponEventArgs> ActiveWeaponChanged;
public void InvokeActiveWeaponChanged()
{
var handler = ActiveWeaponChanged;
if (handler != null) handler(this, new WeaponEventArgs(ActiveWeapon));
}
public void InvokeWeaponGrabbed(Weapon weapon)
{
var handler = WeaponGrabbed;
if (handler != null) handler(this, new WeaponEventArgs(weapon));
}
public void SwitchWeapon(WeaponName weaponName)
{
ActiveWeapon = _ownedWeapons.Where(weapon => weapon.Name == weaponName).First();
InvokeActiveWeaponChanged();
}
public void Grab(Weapon weapon)
{
_ownedWeapons.Add(weapon);
InvokeWeaponGrabbed(weapon);
}
}
public class WeaponEventArgs : EventArgs
{
public WeaponEventArgs(Weapon weapon)
{
Weapon = weapon;
}
public Weapon Weapon { get; set; }
}
武器库
- 在您的应用程序中集中所有关于玩家可以使用的武器的知识,注册可用武器名称及其在构造函数中的创建。
- 此外,它提供了创建和查询可用武器的方法。
您可以使用WeaponsNotOwnedBy方法告诉玩家尚未拥有哪些武器。
public class WeaponRepository
{
readonly Dictionary> _availableWeapons = new Dictionary>();
public WeaponRepository()
{
_availableWeapons.Add(WeaponName.Pistol, () => new Weapon(WeaponName.Pistol) );
_availableWeapons.Add(WeaponName.Shotgun, () => new Weapon(WeaponName.Shotgun) );
}
public Weapon Create(WeaponName name)
{
return _availableWeapons[name]();
}
public IEnumerable<WeaponName> AvailableWeapons()
{
return Enum.GetValues(typeof (WeaponName)).Cast<WeaponName>();
}
public IEnumerable<WeaponName> WeaponsNotOwnedBy(Player player)
{
return AvailableWeapons().Where(weaponName => !player.OwnedWeapons.Contains(weaponName));
}
}
使用方法
- 您可以将类分配为构建和更新玩家工具栏的责任。
- 在BuildToolbar方法中,使用WeaponRepository中的AvailableWeapons方法为每个武器创建一个按钮。
- 在此类中,订阅玩家事件。这样,您可以根据需要启用/禁用/突出显示活动武器。
注意:为简洁起见,我省略了WeaponButton。
public class WeaponToolbarBuilder
{
private readonly Player _player;
private readonly WeaponRepository _weaponRepository;
private List<WeaponButton> _buttons = new List<WeaponButton>();
public WeaponToolbarBuilder(Player player, WeaponRepository weaponRepository)
{
_player = player;
_weaponRepository = weaponRepository;
_player.ActiveWeaponChanged += _player_ActiveWeaponChanged;
_player.WeaponGrabbed += _player_WeaponGrabbed;
}
void _player_WeaponGrabbed(object sender, WeaponEventArgs e)
{
var weaponButton = _buttons.Where(button => button.WeaponName == e.Weapon.Name).First();
weaponButton.Enable();
}
void _player_ActiveWeaponChanged(object sender, WeaponEventArgs e)
{
var currentActiveButton = _buttons.Where(button => button.Highlighted).First();
currentActiveButton.Highlight(false);
var newActiveButton = _buttons.Where(button => button.WeaponName == e.Weapon.Name);
newActiveButton.Highlight(true);
}
public void BuildToolbar() { ... }
}