public void DoPlayerHitBySheep(DogPlayerController sender) { if (PlayerHitBySheepEvent != null) { PlayerHitBySheepEvent(sender); } }
const int _maxStarCount = 3; /// 환경에 생성할 수 있는 별의 총 개수 /* 초기화를 두개의 함수로 분리 * 게임시작시 단 한번 초기화해도 되는 부분(Awake 함수)과 * 게임을 재도전할때마다 초기화해야되는 부분(Start 함수)을 분리하였다. * 이를 통해 단 한번 초기화해도 되는 부분이 여러번 호출되어 CPU가 낭비되는 일이 없도록 하였다. */ /* [클린성] 가독성을 위해서 Enumeration 이용 * 코드의 가독성을 위해서 Enumeration을 적극이용하는 편이다. * 또한 int형으로도 형변환이 되어 index를 가독성있게 표현하는데 큰 역할을 한다. */ /// <summary> /// 게임 입장시, "단 한번만" 초기화해도 되는 부분을 이 함수에서 초기화한다. /// </summary> void Awake() { _playerController = GameObject.FindWithTag("Player").GetComponent <DogPlayerController>(); var minigameDataSet = GameObject.FindWithTag("Managers").GetComponentInChildren <MinigameDataSet>(); _data = minigameDataSet.GetMinigameData(MinigameType.Type.CatchGame); Initialize(); }
ItemSet _itemSet; /// 아이템 정보 /* [독립성] 이벤트 사용 * 이벤트는 클래스 간의 결합도를 낮추고, 확장성을 높이는데 매우 큰 도움이 된다. * 이벤트를 통해 객체를 직접적으로 참조하지 않아도, 그 객체의 특정함수를 호출할 수 있기 때문이다. * 또한 기존 클래스와 통신하고 싶을때, 기존 클래스와 연관된 이벤트에 연결해서 새로운 클래스를 만들면 된다. * 이 과정에서 기존 클래스(코드)를 수정할 필요가 없다. (그래서 유연성을 높이는데 큰 기여를 한다.) * * 이 장점을 살리기 위해서 나는 MVC모델들 사이의 의존도를 약하게 만들기 위한 일환으로 이벤트를 많이 사용한다. * 코드를 보면 Player관련 MVC모델과 CatchGame MVC모델이 이벤트를 통해 연결되는 과정을 볼 수 있다. * PS) 물론 이벤트를 이용할때 이벤트에 연결된 함수들의 호출순서를 통제하기 어렵다는 단점이 있다. */ /// <summary> /// 변수를 초기화하고, 이벤트를 연결한다. /// </summary> void Start() { _playerController = GameObject.FindWithTag("Player").GetComponent <DogPlayerController>(); _itemData = GameObject.FindWithTag("Managers").GetComponentInChildren <ItemData>(); _itemSet = GameObject.FindWithTag("Managers").GetComponentInChildren <ItemSet>(); _playerController.OnUpdateSheepIndicator(_model.GetNearestSheepPlayerCanHit()); _view.UpdateSheepCountPanel(_model.CurrentSheepCount); CatchGameEventPublisher.instance.PlayerAttackSheepEvent += OnPlayerAttackSheep; /// 싱글턴 패턴 사용 CatchGameEventPublisher.instance.PlayerHitBySheepEvent += OnPlayerHitBySheep; CatchGameEventPublisher.instance.AppearStarEvent += OnAppearStar; CatchGameEventPublisher.instance.DisappearStarEvent += OnDisappearStar; CatchGameEventPublisher.instance.GetStarEvent += OnGetStar; }
/* [견고성] 테스트 단위 함수 분리 * 테스트 단위로 함수를 쪼갠다. * 이를 위한 방법으로 함수 하나에는 하나의 기능(행동)만을 하도록 노력해서 코드를 짰다. * 그 기능에 문제가 생기면, 그 기능을 담당하는 함수를 바로 보면 되기 때문에 디버깅하기도 쉬워진다. */ /* [고난] 게임은 함께 만드는 것이다. * 게임은 함께 만든다는 사실은, 팀원 서로가 짠 코드를 봐야할 상황이 많다는 것을 의미한다. * 내가 코드를 짜는 시간보다 동료가 짠 코드를 보는 시간이 훨씬 더 많을 때도 비일비재했다. * * 1. * 서로의 코드를 파악하는 시간을 단축시키기 위해선 코드를 최대한 클린하게 짜야한다. * 지금 당장 코드를 클린하게 짜는 것이 시간이 좀 더 소모될 수 있으나, 장기적으로 보면 시간을 크게 단축시킨다는 것을 뼈저리게 느낀적이 많았다. * 그 이후 "클린코드"와 "C# 코딩의 기술:실전편" 책을 읽어보는 등 지금까지도 코드를 어떻게하면 클린하게 짤 수 있는지를 고민하고 있다. * * 2. * 디자인패턴 * 디자인패턴에 대해 서로가 알고 있으면, 내가 사용한 디자인패턴의 이름하나라 코드 전체 구조를 단번에 이해시킬 수 있게 된다. * 따라서 동료로 하여금 빠르게 나의 코드를 이해시킬 수 있다. */ /// <summary> /// 플레이어가 필드몬스터인 양을 공격할때, 관련변수와 UI(view)를 업데이트하고, 모든 양을 잡으면 게임 클리어시킨다. /// </summary> /// <param name="sender"></param> void OnPlayerAttackSheep(DogPlayerController sender) { _model.DecreaseSheepCount(1); if (_model.IsAppearStar()) { _model.AppearStar(); } _view.UpdateSheepCountPanel(_model.CurrentSheepCount); _playerController.OnUpdateSheepIndicator(_model.GetNearestSheepPlayerCanHit()); AudioMgr.instance.PlaySoundEffect("Kick"); if (_model.CurrentSheepCount <= 0) { OnGameClear(); } }
/// <summary> /// 플레이어가 필드몬스터인 양에게 공격받았다면, 미션실패이며 재도전할지를 물어본다. /// </summary> /// <param name="sender"></param> void OnPlayerHitBySheep(DogPlayerController sender) { _model.DeactivateAllSheeps(); _view.SwitchUI(_view.AskRestartPanel.gameObject, true); AudioMgr.instance.PlaySoundAndResumeBGM("Fail"); }