EasyCastleUNITY

미션 만들기 본문

C#프로그래밍

미션 만들기

EasyCastleT 2023. 7. 31. 11:50

mission_data
item_data

고정 데이터

MissionData

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mission
{
    public class MissionData
    {
        public int id;
        public string name;
        public int goal;
        public int item_id;
        public int item_amount;
    }
}

ItemData

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mission
{
    public class ItemData
    {
        public int id;
        public string name;
    }
}

고정 데이터 관리 -----------------------------------------------------------------------------------------------------------------------------------------

DataManager

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;

namespace Mission
{
    //싱글톤 : 인스턴스가 1개다, 언제어디서든 접근이 가능
    public class DataManager
    {
        public static readonly DataManager instance = new DataManager();
        private Dictionary<int, MissionData> dicMissionDatas = new Dictionary<int, MissionData>();
        private Dictionary<int, ItemData> dicItemDatas = new Dictionary<int, ItemData>();
        //생성자
        private DataManager()
        {

        }

        public void LoadMissionDatas()
        {
            string json = File.ReadAllText("./mission_data.json");
            //역직렬화
            MissionData[] datas = JsonConvert.DeserializeObject<MissionData[]>(json);
            foreach ( MissionData data in datas )
            {
                dicMissionDatas.Add(data.id,data);
            }
            Console.WriteLine("미션 데이터 로드 완료");
        }

        public void LoadItemDatas()
        {
            string json = File.ReadAllText("./item_data.json");
            //역직렬화
            ItemData[] datas = JsonConvert.DeserializeObject<ItemData[]>(json);
            this.dicItemDatas = datas.ToDictionary(x => x.id);
            Console.WriteLine("아이템 데이터 로드 완료");
        }
        public List<MissionData> GetMissionDatas()
        {
            //새로운 List를 생성해서 반환
            return this.dicMissionDatas.Values.ToList();
        }
        public ItemData GetItemData(int id)
        {
            return dicItemDatas[id];
        }

        public MissionData GetMissionData(int id)
        {
            return dicMissionDatas[id];
        }
    }
}

버튼-----------------------------------------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mission
{
    public class Button
    {
        public string name;
        public Action onClick;

        //생성자\
        public Button(string name)
        {
            this.name= name;
        }
        //대리자 호출 
        public void Click()
        {
            Console.WriteLine("{0}이 클릭 되었습니다",this.name);
            this.onClick();
        }
    }
}

게임을 하며 변화하는 정보들, GameInfo는 변화한 정보를 저장하기 위한 클래스-------------------------------------------------------

MissionInfo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mission
{
    //미션 정보를 저장하는 저장 객체
    public class MissionInfo
    {
        public int id;
        public int count; //완료한 미션수
        //생성자
        public MissionInfo(int id, int count)
        {
            this.id = id;
            this.count = count;
        }
    }
}

GameInfo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mission
{
    //게임 정보를 저장 하는 저장 객체 
    public class GameInfo
    {
        public List<MissionInfo> missionInfos;
        //생성자
        public GameInfo()
        {

        }
        //신규유저만 호출할 것!
        public void Init()
        {
            //List 인스턴스 생성
            this.missionInfos = new List<MissionInfo>();
            //선택사항
            //기본 미션 정보 저장
            foreach(MissionData data in DataManager.instance.GetMissionDatas())
            {
                this.missionInfos.Add(new MissionInfo(data.id, 0));
            }
        }
    }
}

변화하는 정보들 관리하는 클래스 InfoManager

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;

namespace Mission
{
    public class InfoManager
    {
        //저장 객체들을 관리 하는 싱글톤 클래스
        public static readonly InfoManager instance = new InfoManager();
        private GameInfo gameInfo;
        private string GAME_INFO_FILE_PATH = "./game_info.json";
        //생성자
        private InfoManager()
        {

        }

        public void Init(GameInfo gameInfo)
        {
            this.gameInfo = gameInfo;
        }
        //신규유저인가? : game_info.json 파일이 없다
        public bool IsNewbie()
        {
            return !File.Exists(GAME_INFO_FILE_PATH); //! 부정판단 
        }
        //GameInfo 저장 
        public void SaveGameInfo()
        {
            //직렬화
            string json = JsonConvert.SerializeObject(this.gameInfo);
          //  Console.WriteLine(json);
            //파일저장
            File.WriteAllText(GAME_INFO_FILE_PATH, json);
            Console.WriteLine("./game_info.json 저장완료");
        }
        //GameInfo 불러오기 
        public void LoadGameInfo()
        {
            string json = File.ReadAllText(GAME_INFO_FILE_PATH);
            //역직렬화
            this.gameInfo = JsonConvert.DeserializeObject<GameInfo>(json);
            Console.WriteLine("./game_info.json 로드완료");
        }

        public MissionInfo GetMissionInfo(int id)
        {
            return this.gameInfo.missionInfos.Find(x => x.id == id);
        }

        public GameInfo GetGameInfo()
        {
            return this.gameInfo;
        }
    }
}

GameEnums  -> 미션 상황 관리

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mission
{
    public class GameEnums
    {
        //Doing : 하고 있는중
        //Done: 미션을 끝내고, 아직 보상을 받지 않은 경우
        //Complete: 미션이 끝나고, 보상까지 받은 경우
        public enum eMissionState
        {
            Doing, Done, Complete
        }
    }
}

 

Game

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mission
{
    public class Game
    {
        private Button btnMission;
        //생성자 
        public Game()
        {
            Console.WriteLine("Game 생성자 호출");
            this.btnMission = new Button("미션버튼");
            this.btnMission.onClick = () =>{
                Console.WriteLine("미션창을 보여준다");
                this.PrintMission();
            };
            //미션 버튼 클릭
        }
        public void Start()
        {
            Console.WriteLine("게임 시작");
            this.btnMission.Click();

            this.DoMission(1000, 7); //1000번 미션을 7번 실행 
            this.btnMission.Click();

            this.Claim(1000); //처음 한번만 나오도록 함

        }
        private void PrintMission()
        {
            List<MissionData> missionDatas = DataManager.instance.GetMissionDatas();
            Console.WriteLine("---------미션----------");
            foreach (MissionData data in missionDatas)
            {
                ItemData itemData = DataManager.instance.GetItemData(data.item_id);
                string strReward = string.Format("  {0}x{1}", itemData.name, data.item_amount);
                string name = string.Format(data.name, data.goal);

                MissionInfo missionInfo = InfoManager.instance.GetMissionInfo(data.id);
                
                string strProgress = string.Format("{0}/{1}", missionInfo.count, data.goal);
                Console.WriteLine("{3}\t{0}\t{1}\t{2}\t{4}"
                    , name, strProgress, strReward,data.id,(GameEnums.eMissionState)missionInfo.state);
                Console.WriteLine("--------------------------");
            }
        }
        private void DoMission(int id, int count)
        {
            MissionData missionData = DataManager.instance.GetMissionData(id);
            string name = string.Format(missionData.name, missionData.goal);
            Console.WriteLine("{0}을 {1}번 했습니다.", name, count);

            GameInfo gameInfo = InfoManager.instance.GetGameInfo();
            MissionInfo missionInfo = gameInfo.missionInfos.Find(x=> x.id == id);

            GameEnums.eMissionState state = (GameEnums.eMissionState)missionInfo.state;
            
            if(state == GameEnums.eMissionState.Done)
            {
                Console.WriteLine("이미 완료된 미션입니다");
                return;
            }
            if(state == GameEnums.eMissionState.Doing && count >= missionData.goal )
            {
                count = missionData.goal;
                //doing -> done 
                missionInfo.state = (int)GameEnums.eMissionState.Done;
            }
            missionInfo.count = count;
            InfoManager.instance.SaveGameInfo();

        }
        /// <summary>
        /// 보상을 요구하는 메서드
        /// </summary>
        /// <param name="id">미션 ID</param>
        public void Claim(int id) //mission id 
        {
            MissionInfo info =InfoManager.instance.GetMissionInfo(id);
            GameEnums.eMissionState state = (GameEnums.eMissionState)info.state;
            if(state == GameEnums.eMissionState.Done)
            {
                MissionData missionData = DataManager.instance.GetMissionData(info.id);
                ItemData itemData = DataManager.instance.GetItemData(missionData.item_id);
                Console.WriteLine("{0}:{1}를 지급 받았습니다.", itemData.id, itemData.name);
                info.state = (int)GameEnums.eMissionState.Complete;
                InfoManager.instance.SaveGameInfo();
            }
            
        }
    }
}

실행

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;

namespace Mission
{
    public class App
    {
       
        public App()
        {
            //데이터 로드 
            DataManager.instance.LoadMissionDatas();
            DataManager.instance.LoadItemDatas();
            //신규유저 기존유저 판별
            //신규유저: GameInfo 객체를 새로 생성
            //기존유저: game_info.json 읽고 역직렬화 => GameInfo 객체 
            //InfoManger에 GameInfo 객체 넣기 
            GameInfo gameInfo = null;
            if (InfoManager.instance.IsNewbie())
            {
                Console.WriteLine("신규유저");
                gameInfo = new GameInfo();
                gameInfo.Init();
                InfoManager.instance.Init(gameInfo);
                //기본 미션정보를 넣고 game_info.json으로 저장 
                InfoManager.instance.SaveGameInfo();
            }
            else
            {
                Console.WriteLine("기존유저");
                InfoManager.instance.LoadGameInfo();
            }
            Game game = new Game();
            game.Start();
        }
    }
}

미션을 실행하고 지급받은 상태 직후-> 해당 사진 이후에는 상태가 Complete가 되어 또 지급받지 않는다.
지급받고 다시 실행해본 상태, 이미 지급 받았기에 지급을 다시 받지는 않는다.