> 기능 및 특징
1. 싱글톤 ManagerData.cs
2. Chatacter.cs 상속
- Hero.cs
- Monster.cs
3. HeroInfo.cs 저장될 데이터 클래스, 선택적 매개변수 생성자 활용
4. Data파일들
- HeroData
- ClassData
- ExpData
- GoldData
- ItemData
- MonsterData
> 추후 개선시 참고사항
- UI / 기능,데이터의 명확한 역할 구분
- 매니저클래스에 제너릭 활용
- enum 및 데이터 파일 저장 등
> JSON Data
더보기
1. class_data.json
[{ "id": 100, "class_type": 0, "class_name": "초보자", "require_level": 0 }, { "id": 101, "class_type": 1, "class_name": "검사", "require_level": 10 }, { "id": 102, "class_type": 1, "class_name": "파이터", "require_level": 30 }, { "id": 103, "class_type": 1, "class_name": "크루세이더", "require_level": 50 }, { "id": 104, "class_type": 1, "class_name": "히어로", "require_level": 90 }, { "id": 105, "class_type": 1, "class_name": "하이퍼 히어로", "require_level": 120 }, { "id": 106, "class_type": 2, "class_name": "아처", "require_level": 10 }, { "id": 107, "class_type": 2, "class_name": "헌터", "require_level": 40 }, { "id": 108, "class_type": 2, "class_name": "레인저 ", "require_level": 80 }, { "id": 109, "class_type": 2, "class_name": "보우마스터", "require_level": 120 }, { "id": 110, "class_type": 2, "class_name": "하이퍼 보우마스터", "require_level": 160 } ]
2. exp_data.json
[ { "exp_id": 100000, "level": 1, "require_exp": 50 }, { "exp_id": 100001, "level": 2, "require_exp": 100 }, { "exp_id": 100002, "level": 3, "require_exp": 150 }, { "exp_id": 100003, "level": 4, "require_exp": 225 }, { "exp_id": 100004, "level": 5, "require_exp": 337 }, { "exp_id": 100005, "level": 6, "require_exp": 506 }, { "exp_id": 100006, "level": 7, "require_exp": 759 }, { "exp_id": 100007, "level": 8, "require_exp": 1139 }, { "exp_id": 100008, "level": 9, "require_exp": 1708 }, { "exp_id": 100009, "level": 10, "require_exp": 2562 }, { "exp_id": 100010, "level": 11, "require_exp": 3844 } ]
3. gold_data.json
[{ "id": 100, "name": "골드" }]
4. hero_data.json
[{ "id": 1000, "class_id": 100, "hp": 50, "mp": 30, "damage": 1.5 }]
5. item_data.json
[ { "id": 100, "name": "초록 달팽이 껍질", "resource_name": "green_snail_shell", "icon_name": "ico_green_snail_shell", "sell_price": 1, "item_type": 0 }, { "id": 101, "name": "파란 달팽이 껍질", "resource_name": "bule_snail_shell", "icon_name": "ico_bule_snail_shell", "sell_price": 1, "item_type": 0 }, { "id": 102, "name": "빨간 달팽이 껍질", "resource_name": "red_snail_shell", "icon_name": "ico_red_snail_shell", "sell_price": 1, "item_type": 0 }, { "id": 103, "name": "매소 (소 )", "resource_name": "meso_small", "icon_name": "ico_meso_small", "sell_price": 0, "item_type": 4 }, { "id": 104, "name": "매소 (중)", "resource_name": "meso_midium", "icon_name": "ico_meso_midium", "sell_price": 0, "item_type": 4 }, { "id": 105, "name": "매소 (대)", "resource_name": "meso_large", "icon_name": "ico_meso_large", "sell_price": 0, "item_type": 4 } ]
6. monster_data.json
[ { "id": 1000, "name": "초록 달팽이", "hp": 25, "damage": 2.5, "exp": 1, "drop_item_id": 100 }, { "id": 1001, "name": "파란 달팽이", "hp": 25, "damage": 2.8, "exp": 2, "drop_item_id": 101 }, { "id": 1002, "name": "빨간 달팽이", "hp": 25, "damage": 3, "exp": 3, "drop_item_id": 102 }, { "id": 2000, "name": "머쉬맘", "hp": 1000, "damage": 8, "exp": 10, "drop_item_id": 103 } ]
> Code
1. Data 클래스
더보기
class MonsterData { public int id; public string name; public int hp; public float dmage; public int exp; public int drop_item_id; }
class ItemData { public int id; public string name; public string resource_name; public string icon_name; public int sell_price; public int item_type; }
class HeroData { public int id; public int class_id; public int hp; public int mp; public float damage; public HeroData(int id, int class_id, int hp, int mp, float damage) { this.id = id; this.class_id = class_id; this.hp = hp; this.mp = mp; this.damage = damage; } }
class GoldData { public int id; public string name; }
class ExpData { public int exp_id; public int level; public int require_exp; }
class ClassData { public int id; public int class_type; public string class_name; public int require_level; }
class Character { public Character() { } public virtual void Attack(Character target) { } public virtual void Hit(float damamge) { } public virtual void Die() { } }
2. Info 클래스
더보기
class HeroInfo { public string name; public int level; public int classType; // 직업타입 public int classGrade; // 등급 id 검사or 파이터등 등급을 말하는 것? public float damage; public int hp; public int mp; public int exp; public int gold; // 선택적 매개변수 뒤쪽에 배치 필요 public HeroInfo(string name, int hp, int mp, float damage, int level = 1, int classType = 0, int classGrade = -1, int exp = 0, int gold=0) { this.name = name; this.level = level; this.classType = classType; this.classGrade = classGrade; this.hp = hp; this.mp = mp; this.damage = damage; this.exp = exp; this.gold = gold; } }
3. 싱글톤 매니저 클래스
더보기
class DataManager { private static DataManager singleTone; private Dictionary<int, HeroData> dicHeroData; private Dictionary<int, ClassData> dicClassData; private Dictionary<int, ExpData> dicExpData; private Dictionary<int, GoldData> dicGoldData; public Dictionary<int, ItemData> dicItemData; private Dictionary<int, MonsterData> dicMonsterData; public static DataManager GetInstance() { if (DataManager.singleTone == null) { DataManager.singleTone = new DataManager(); return DataManager.singleTone; } else { return DataManager.singleTone; } }// GetInstance end; public void LoadDatas() { string json = ""; string path = ""; try { // 영웅 생성 path = "./data/hero_data.json"; if (File.Exists(path)) { json = File.ReadAllText(path); this.dicHeroData = JsonConvert.DeserializeObject<HeroData[]>(json).ToDictionary(x => x.id, x => x); } // 몬스터 생성 path = "./data/monster_data.json"; if (File.Exists(path)) { json = File.ReadAllText(path); this.dicMonsterData = JsonConvert.DeserializeObject<MonsterData[]>(json).ToDictionary(x => x.id, x => x); } // 아이템 생성 path = "./data/item_data.json"; if (File.Exists(path)) { json = File.ReadAllText(path); this.dicItemData = JsonConvert.DeserializeObject<ItemData[]>(json).ToDictionary(x => x.id, x => x); } // 전직 데이터 path = "./data/class_data.json"; if (File.Exists(path)) { json = File.ReadAllText(path); this.dicClassData = JsonConvert.DeserializeObject<ClassData[]>(json).ToDictionary(x => x.id, x => x); } // 경험치 데이터 path = "./data/exp_data.json"; if (File.Exists(path)) { json = File.ReadAllText(path); this.dicExpData = JsonConvert.DeserializeObject<ExpData[]>(json).ToDictionary(x => x.exp_id, x => x); } // 골드 데이터 path = "./data/gold_data.json"; if (File.Exists(path)) { json = File.ReadAllText(path); this.dicGoldData = JsonConvert.DeserializeObject<GoldData[]>(json).ToDictionary(x => x.id, x => x); } } catch (Exception e) { Console.WriteLine(e.Message); throw; } } public HeroData GetCharacterDataById(int id) { return this.dicHeroData[id]; } public MonsterData GetMonsterDataById(int id) { return this.dicMonsterData[id]; } public ExpData GetExpDataByLevel(int level){ var result = this.dicExpData.FirstOrDefault(v => v.Value.level == level).Value; return result; } public ClassData GetClassDataByClassType(int classType){ var result = this.dicClassData.FirstOrDefault(v => v.Value.class_type == classType).Value; return result; } public GoldData GetGoldDataById(int id){ return this.dicGoldData[id]; } public ItemData GetItemDataById(int dropItemId){ return this.dicItemData[dropItemId]; } }
4. Monster / Hero 클래스
더보기
class Monster : Character { public int id; public string name; public float hp; public float damage; public int exp; public int drop_item_id; public float maxHp; public Monster(MonsterData data) { this.id = data.id; this.name = data.name; this.hp = data.hp; this.damage = data.dmage; this.exp = data.exp; this.drop_item_id = data.drop_item_id; this.maxHp = data.hp; Console.WriteLine(this.name + " 이 생성되었습니다."); } public override void Attack(Character target) { Console.WriteLine(target); target.Hit(this.damage); } public override void Hit(float damage) { Console.WriteLine("몬스터 hit"); this.hp -= damage; if (this.hp <= 0) { this.Die(); } } public override void Die() { Console.WriteLine("몬스터가 죽었습니다."); } public bool IsDie() { this.hp = 0; //강제 죽임 test if (this.hp <= 0) { return true; } return false; } }
class Hero : Character { // 데이터 변경과 에니메이션 담당 -> 외부에 결과 전달(App()) public HeroInfo info; public Hero() { Console.WriteLine("영웅이 생성되었습니다."); } public void Init(HeroInfo info) { this.info = info; } public override void Attack(Character target) { target.Hit(this.info.damage); } public override void Hit(float damage) { Console.WriteLine($"{this.info.name}이 {damage} 피해를 입어습니다."); } public override void Die() { this.info.hp = 0; Console.WriteLine("- game over 주인공이 죽었습니다."); } // 경험치 획득 public void GetExp(int getExp) { this.info.exp += getExp; Console.WriteLine($"{this.info.exp} 경험치 획득"); Console.WriteLine(); } // 경험치 확인 public void CheckExp(Hero hero) { var dataManager = DataManager.GetInstance(); var exp = hero.info.exp; // 현재 경험치 //현재 레벨로 가져온 exp데이터 var expData = dataManager.GetExpDataByLevel(hero.info.level); //다음레벨 exp데이터 var nextData = dataManager.GetExpDataByLevel(hero.info.level+1); // 레벨업 체크 if(exp >= expData.require_exp){ this.LevelUp(hero); }else{ Console.WriteLine($"-Lev{hero.info.level} / {hero.info.exp} -> -Lev{nextData.level} / {expData.require_exp} 필요"); } Console.WriteLine(); } // 레벨 업 public void LevelUp(Hero hero) { // 전직 여부 체크 var dataManager = DataManager.GetInstance(); if(hero.info.classType == 0 ){ // 초보자 일경우 Console.WriteLine("- 축하합니다. 전직이 가능합니다."); this.ClassChange(); this.HeroPrint(); }else{ // 레벨업 Console.WriteLine("- 레벨이 올랐습니다."); this.UpGrage(); this.HeroPrint(); } } // 스텟 상향 public void UpGrage(){ var dataManager = DataManager.GetInstance(); var classData = dataManager.GetClassDataByClassType(this.info.classGrade+1); this.info.classGrade = classData.id; this.info.name = classData.class_name; this.info.level +=1; } public void HeroPrint(){ var hero = this.info; Console.WriteLine($"name:{hero.name}/ Lev:{hero.level} / (hp:{hero.hp}/hp:{hero.mp})"); } // 전직 public void ClassChange() { var dataManager = DataManager.GetInstance(); var choiceClass1 = dataManager.GetClassDataByClassType(1); var choiceClass2 = dataManager.GetClassDataByClassType(2); Console.WriteLine($"1.{choiceClass1.class_name} / 2.{choiceClass2.class_name} 선택"); Console.WriteLine("1번 선택"); var userInput=1; switch (userInput) { case 1: Console.WriteLine("검사를 선택하셨습니다."); this.info.name = choiceClass1.class_name; this.info.classType = choiceClass1.class_type; this.info.classGrade = choiceClass1.id; // 검사 101 this.info.level +=1; break; case 2: Console.WriteLine("아처를 선택하셨습니다."); this.info.name = choiceClass2.class_name; this.info.classType = choiceClass2.class_type; this.info.classGrade = choiceClass2.id; // 아처 10 this.info.level +=1; break; default: break; } Console.WriteLine(); } //아이템 획득 public void PickItem(Monster target){ var dataManager = DataManager.GetInstance(); var getItem = dataManager.GetItemDataById(target.drop_item_id); Console.WriteLine($"- 아이템획득: {getItem.name} / 판매가격:{getItem.sell_price} / {getItem.resource_name}"); Console.WriteLine(); } //골드 획득 public void PickGold(int id){ var dataManagere = DataManager.GetInstance(); GoldData goldData = dataManagere.GetGoldDataById(id); this.info.gold += goldData.id; Console.WriteLine($"- {goldData.name}({goldData.id}) 획득!"); Console.WriteLine(); } }
5. App 클래스
더보기
class App { public App() { // 데이터 로드 // 영웅 생성 // 몬스터 생성 // 몬스터 공격 // 몬스터 처치 // 아이템 드랍 // 경험치, 아이템 획득 // 레벨업 // 전직 var dataManager = DataManager.GetInstance(); dataManager.LoadDatas(); Hero hero = this.CreateDefaultHero(); Monster monster = this.CreateMonster(1000); //몬스터 공격 hero.Attack(monster); Console.WriteLine($"({monster.hp}/{monster.maxHp})" ); // 죽임 monster.Die(); monster.IsDie(); // 경험치 획득 if (monster.IsDie()) { hero.GetExp(monster.exp); hero.CheckExp(hero); // 강제 레벨업 - 전직 hero.LevelUp(hero); // 아이템 획득 hero.PickItem(monster); // 골드획득 - 몬스터 고유 id 전달하여 해당 수치만큼 골드 수급 hero.PickGold(100); } } public Monster CreateMonster(int id) { var monsterData = DataManager.GetInstance().GetMonsterDataById(id); return new Monster(monsterData); } public Hero CreateDefaultHero() { var characterData = DataManager.GetInstance().GetCharacterDataById(1000); var heroInfo = new HeroInfo("홍길동", characterData.hp, characterData.mp, characterData.damage); Hero hero = new Hero(); hero.Init(heroInfo); Console.WriteLine(hero.info.name + " 님이 입장하셨습니다."); return hero; } }
'c# 강의 > 과제' 카테고리의 다른 글
20200429 - 일일보상 + 연속보상 + Date연산 (0) | 2020.05.01 |
---|---|
20200428 - 상점(판매종료일/레벨제한/구매수량제한 등) (0) | 2020.04.29 |
20200421 - File 읽기 (JSON) (0) | 2020.04.22 |
20200420 - List 과제 (0) | 2020.04.20 |
20200417 - 주말과제(요리,레시피) (0) | 2020.04.19 |