观察者模式和单例模式练习
用单例模式和观察者模式试着练习写了一个模拟游戏战斗场景载入功能:
实现功能:
- 主角只有一个,不允许存在多个主角
- 主角调用方法通知怪物类做出反应
Program.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 战斗系统模拟_观察者模式练习_ 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Player myPlayer = Player.CreatPlayer("屠龙勇士",1000); 14 Console.WriteLine("-----------------事件回合A-------------------------"); 15 16 Enemy soliderEnemy = new Enemy("C级",300,myPlayer); 17 Enemy OverlandEnemy = new Enemy("B级",2000,myPlayer); 18 Enemy Boss = new Enemy("A级",5000,myPlayer); 19 myPlayer.FindEnemy(); 20 myPlayer = Player.CreatPlayer("暗黑勇士", 1000); 21 Console.WriteLine("-----------------事件回合B-------------------------"); 22 23 Enemy SuperBoss = new Enemy("S级", 10000, myPlayer);//实例化SuperBoss,向被观察者添加一名观察者 24 myPlayer.FindEnemy();//被观察者行动,通知观察者们 25 } 26 } 27 }
Player.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 战斗系统模拟_观察者模式练习_ 8 { 9 class Player 10 { 11 private string _name; 12 private float _hp; 13 private static Player myPlayer; 14 15 public string Name 16 { 17 get { return _name; } 18 } 19 20 21 //程序运行时创建一个静态只读的辅助对象 22 private static readonly object syncRoot = new object(); 23 24 public event Action IdleStateEvent;//发布一个主角诞生消息 25 26 27 private Player(string name, float hp) 28 { 29 this._hp = hp; 30 this._name = name; 31 } 32 33 public static Player CreatPlayer(string name, float hp) 34 { 35 if (myPlayer == null)//一次判断 36 { 37 lock (syncRoot)//线程控制 38 { 39 if (myPlayer == null)//二次判断 40 { 41 myPlayer = new Player(name, hp); 42 } 43 } 44 } 45 else 46 { 47 Console.WriteLine($"原主角:{myPlayer._name}已存在!无法再次创建主角:{name}"); 48 } 49 Console.WriteLine($"主角:{myPlayer._name}实例化并载入游戏场景!"); 50 return myPlayer; 51 } 52 53 public void FindEnemy()//事件 54 { 55 if (IdleStateEvent != null)//调用一个事件 56 IdleStateEvent(); 57 } 58 } 59 }
懒汉式(双锁)。
Enemy.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 战斗系统模拟_观察者模式练习_ 8 { 9 10 class Enemy 11 { 12 private string _name; 13 private float _hp; 14 private Player tempPlayer;//目标player实例对象 15 public Enemy(string name, float hp,Player player) 16 { 17 _name = name; 18 _hp = hp; 19 player.IdleStateEvent += this.IdleState; 20 tempPlayer = player; 21 Console.WriteLine($"{name}敌人实例化!HP:{_hp}"); 22 } 23 24 private void IdleState() 25 { 26 Console.WriteLine($"{_name}敌人发现主角{tempPlayer.Name},进入待机状态"); 27 } 28 } 29 }
接受玩家事件通知。
最后实现效果: