Notice
Tags
Recent Entries
Recent Comments
Recent Trackbacks
Archives
|
C#/수업내용 2019. 5. 7. 18:32
Animation 만들고 Mecanim Parameters 이용하여 재생, Background, Tile 반복이동
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class TestSunnyLand : MonoBehaviour { public Button idleBtn; public Button runBtn; public Button jumpBtn; public GameObject player; public GameObject backGround; public GameObject tile; private Animator anim; private bool move; private void Awake() { this.anim = this.player.gameObject.GetComponent<Animator>(); } public void Start() { this.StartGame(); } public void StartGame() { this.idleBtn.onClick.AddListener(() => { StartCoroutine(this.OnCompleteAnim("isIdle")); }); this.runBtn.onClick.AddListener(() => { StartCoroutine(this.OnCompleteAnim("isRun")); }); this.jumpBtn.onClick.AddListener(() => { StartCoroutine(this.OnCompleteAnim("isJump")); StartCoroutine(this.Jump()); }); } private IEnumerator MoveBackground() { while (this.move) { this.backGround.transform.position = new Vector3(Mathf.Repeat(Time.time, 15), this.backGround.transform.position.y, this.backGround.transform.position.z); yield return null; } } private IEnumerator MoveTile() { while (this.move) { if (this.tile.transform.position.x > -5f) { this.tile.transform.position = new Vector3(this.tile.transform.position.x - 1.5f * Time.deltaTime, this.tile.transform.position.y, this.tile.transform.position.z); yield return null; } else { this.tile.transform.position = new Vector3(0, 0, 0); } } } private IEnumerator OnCompleteAnim(string name) { var state = this.anim.GetCurrentAnimatorStateInfo(0); if(name == "isRun") { this.anim.SetBool("isIdle", false); this.anim.SetBool("isRun", true); this.move = true; StartCoroutine(this.MoveTile()); StartCoroutine(this.MoveBackground()); yield return new WaitForSeconds(this.anim.GetCurrentAnimatorStateInfo(0).length); } else if(name == "isIdle") { this.anim.SetBool("isRun", false); this.anim.SetBool("isIdle", true); this.move = false; } else if(name == "isJump") { if(state.IsName("isIdle")) { this.StopAllAnim(); this.anim.SetBool(name, true); yield return new WaitForSeconds(this.anim.GetCurrentAnimatorStateInfo(0).length); this.anim.SetBool(name, false); this.anim.SetBool("isIdle", true); } else if(state.IsName("isRun")) { this.move = true; StartCoroutine(this.MoveTile()); StartCoroutine(this.MoveBackground()); this.anim.SetBool("isIdle", false); this.anim.SetBool(name, true); yield return new WaitForSeconds(this.anim.GetCurrentAnimatorStateInfo(0).length); this.anim.SetBool(name, false); this.anim.SetBool("isRun", true); } } } private void StopAllAnim() { var state = this.anim.runtimeAnimatorController.animationClips; foreach(var anim in state) { this.anim.SetBool(anim.name, false); } } private IEnumerator Jump() { bool isJump = true; while (true) { if (isJump) { this.player.transform.position = new Vector3(this.player.transform.position.x, this.player.transform.position.y + 5f * Time.deltaTime, 0); if (this.player.transform.position.y > 1) { isJump = false; } } else if (!isJump) { this.player.transform.position = new Vector3(this.player.transform.position.x, this.player.transform.position.y - 5f * Time.deltaTime, 0); if (this.player.transform.position.y <= 0.1f) { this.player.transform.position = new Vector3(this.player.transform.position.x, 0, 0); break; } } yield return null; } } } | cs |
C#/수업내용 2019. 4. 25. 18:17
WorldToScreenPoint를 이용하여 캐릭터의 상단에 데미지 텍스트를 출력함
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | using DG.Tweening; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class TestHudText : MonoBehaviour { public Button btn; public Button btn2; public GameObject pivot; public Transform hudPoint; public Text txt0; //worldspace point public Text txt1; //viewport point public Text txt2; //spaceport point private Canvas canvas; private void Awake() { this.canvas = FindObjectOfType<Canvas>(); } private void Start() { this.btn.onClick.AddListener(() => { //프리팹 로드 var hudPre = Resources.Load<HUDDamageText>("Prefabs/Test/HUDDamageText"); //인스탄트 var screenPoint = Camera.main.WorldToScreenPoint(this.hudPoint.position); var targetLocalPos = new Vector3(screenPoint.x - Screen.width / 2, screenPoint.y - Screen.height / 2, screenPoint.z); this.pivot.GetComponent<RectTransform>().anchoredPosition = targetLocalPos; var hud = Instantiate(hudPre); //인잇 메서드 호출(텍스트랑 컬러) Color color = new Color(1, 0, 0); hud.Init("456", color); //부모 Canvas로 설정 hud.transform.SetParent(this.pivot.transform, false); //초기화 hud.transform.localPosition = Vector3.zero; //타겟 포지션 Debug.LogFormat("{0},{1},{2}", targetLocalPos.x, targetLocalPos.y, targetLocalPos.z); Debug.LogFormat("{0},{1},{2}", screenPoint.x, screenPoint.y, screenPoint.z); var target = new Vector3(0, 100, 0); DOTween.ToAlpha(() => hud.txt.color, x => hud.txt.color = x, 0, 0.5f); hud.transform.DOScale(new Vector3(2, 2, 2), 0.3f).OnComplete(() => { hud.transform.DOScale(new Vector3(1, 1, 1), 0.2f); }); hud.transform.DOLocalMove(target, 1.5f).SetEase(Ease.OutBack).OnComplete(() => { Destroy(hud.gameObject); }); }); this.btn2.onClick.AddListener(() => { Debug.LogFormat("hudPoint world coordinate : {0}", this.hudPoint.position); this.txt0.text = this.hudPoint.position.ToString(); var viewPortPoint = Camera.main.WorldToViewportPoint(this.hudPoint.position); this.txt1.text = viewPortPoint.ToString(); var screenPoint = Camera.main.WorldToScreenPoint(this.hudPoint.position); this.txt2.text = screenPoint.ToString(); }); } } | cs |
C#/Study 2019. 4. 10. 22:30
사용한 것 Singleton Pattern, Dictionary, List, Interface, DataTable, Vector, UML, 상속, FileStream, MemoryStream, BinaryFormatter (Save, Load)
인터페이스 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public interface IAttackable { bool Attack(Character target); } } | cs |
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public interface IMoveable { void Move(Vector2 targetPosition); } } | cs |
캐릭터 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Character { public CharacterInfo charInfo; //생성자 public Character(CharacterInfo info) { this.charInfo = info; } //피해메소드 public virtual bool GetDamage(int damage) { return true; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Champion : Character { //생성자 public Champion(CharacterInfo info) : base(info) { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace AniviaVsNashor { public class Anivia : Champion, IAttackable, IMoveable { private float moveSpeed = 3.25f; private DataStorage dataStorage = DataStorage.GetInstance(); private Dictionary<int, CharacterData> dicData; //생성자 public Anivia(CharacterInfo info) : base(info) { this.dicData = this.dataStorage.dicCharData; } //피해메소드 public override bool GetDamage(int damage) { Console.WriteLine("{0}의 데미지를 입었습니다!", damage); this.charInfo.remainHp -= damage; if (this.charInfo.remainHp <= 0) { Console.WriteLine("체력이 0이 되어 에그니비아로 환생합니다."); Console.WriteLine("환생까지 10턴이 소모됩니다."); Thread.Sleep(500); return false; } Console.WriteLine("현재 체력 : ({0}/{1})", this.charInfo.remainHp, this.dicData[this.charInfo.id].maxHp); return true; } //거리를 리턴해주는 메소드 public float GetDistance(Vector2 targetPosition) { return Vector2.GetDistance(this.charInfo.position, targetPosition); } #region IAttackable, IMoveable 구현부분 public bool Attack(Character target) { Thread.Sleep(500); Console.WriteLine("\n{0}을 공격합니다.", this.dicData[target.charInfo.id].name); Console.WriteLine("{0}에게 {1}의 피해를 주었습니다!", this.dicData[target.charInfo.id].name, this.dicData[this.charInfo.id].damage); var alive = target.GetDamage(this.dicData[this.charInfo.id].damage); return alive; } public void Move(Vector2 targetPosition) //애니비아 이동속도 3.25 가정한다. { var distanceVector = targetPosition - this.charInfo.position; //거리벡터 var normalizeVector = Vector2.Normalize(distanceVector); //거리벡터의 단위벡터(방향벡터) var speedVector = normalizeVector * moveSpeed; //스칼라곱을 통하여 방향벡터로 향하는 속도벡터 산출 var distance = Vector2.GetDistance(this.charInfo.position, targetPosition); //타겟과의 거리 산출 while(true) { distance = Vector2.GetDistance(this.charInfo.position, targetPosition); Thread.Sleep(500); if (distance > this.dicData[this.charInfo.id].attackRange) { Console.WriteLine("사거리가 닿지 않아 이동합니다."); this.charInfo.position += speedVector; Console.WriteLine("현재 {0}의 위치 : ({1}/{2})", this.dicData[this.charInfo.id].name, this.charInfo.position.x, this.charInfo.position.y); } else if (distance <= this.dicData[this.charInfo.id].attackRange) { Console.WriteLine("사거리 내에 바론이 있습니다. 이동을 멈춥니다."); break; } } } #endregion } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Eggnivia : Champion { private DataStorage dataStorage = DataStorage.GetInstance(); private Dictionary<int, CharacterData> dicData; private int remainTurn = 9; //생성자 public Eggnivia(CharacterInfo info) : base(info) { this.dicData = this.dataStorage.dicCharData; } //피해메소드 public override bool GetDamage(int damage) { Console.WriteLine("{0}의 데미지를 입었습니다!", damage); this.charInfo.remainHp -= damage; if (this.remainTurn > 0) { Console.WriteLine("현재 체력 : ({0}/{1})", this.charInfo.remainHp, this.dicData[this.charInfo.id].maxHp); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("애니비아의 환생까지 {0}턴 남았습니다.", this.remainTurn); Console.ForegroundColor = ConsoleColor.Gray; this.remainTurn--; return false; } Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("****에그니비아가 애니비아로 환생합니다!****"); Console.ForegroundColor = ConsoleColor.Gray; remainTurn = 9; return true; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Monster : Character { //생성자 public Monster(CharacterInfo info) : base(info) { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class NashorBaron : Monster, IAttackable { private DataStorage dataStorage = DataStorage.GetInstance(); private Dictionary<int, CharacterData> dicData; //생성자 public NashorBaron(CharacterInfo info) : base(info) { this.dicData = this.dataStorage.dicCharData; } //피해메소드 public override bool GetDamage(int damage) { this.charInfo.remainHp -= damage; if (this.charInfo.remainHp <= 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\n바론이 죽었습니다!"); return false; } Console.WriteLine("{0}의 현재 체력 : ({1}/{2})", this.dicData[this.charInfo.id].name, this.charInfo.remainHp, this.dicData[this.charInfo.id].maxHp); return true; } #region IAttackable 구현부분 public bool Attack(Character target) { Console.WriteLine("\n{0}이 {1}를 공격합니다.", this.dicData[this.charInfo.id].name, this.dicData[target.charInfo.id].name); var alive = target.GetDamage(this.dicData[this.charInfo.id].damage); return alive; } #endregion } } | cs |
데이터 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class CharacterData { public int id; public string name; public int maxHp; public int remainHp; public int damage; public float attackRange; //생성자 public CharacterData() { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class DataStorage { private static DataStorage instance; public Dictionary<int, CharacterData> dicCharData; //생성자 private DataStorage() { } //인스턴스 리턴 메서드 public static DataStorage GetInstance() { if (DataStorage.instance == null) { DataStorage.instance = new DataStorage(); } return DataStorage.instance; } } } | cs
|
인포 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class CharacterInfo { public int id; public int remainHp { get; set; } public Vector2 position; //생성자 public CharacterInfo(int id) { this.id = id; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class UserInfo { public GameInfo gameInfo; public int userId { get; set; } public string userName { get; set; } //생성자 public UserInfo(GameInfo info) { this.gameInfo = info; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class GameInfo { public List<CharacterInfo> listCharInfo; //생성자 public GameInfo() { } } } | cs |
벡터 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Vector2 { public float x; public float y; //생성자 public Vector2(float x, float y) { this.x = x; this.y = y; } //operator public static Vector2 operator +(Vector2 a, Vector2 b) { return new Vector2((a.x + b.x), (a.y + b.y)); } public static Vector2 operator -(Vector2 a, Vector2 b) { return new Vector2((a.x - b.x), (a.y - b.y)); } public static Vector2 operator *(Vector2 a, float b) { return new Vector2((a.x * b), (a.y * b)); } //calculate vector //정규화 메소드 public static Vector2 Normalize(Vector2 a) { return new Vector2((a.x / Vector2.GetLength(a)), (a.y / Vector2.GetLength(a))); } //길이리턴 메소드 public static float GetLength(Vector2 a) { return (float)Math.Sqrt(Math.Pow(a.x, 2) + Math.Pow(a.y, 2)); } //거리리턴 메소드 public static float GetDistance(Vector2 a, Vector2 b) { return (float)Math.Sqrt(Math.Pow(a.x - b.x, 2) + Math.Pow(a.y - b.y, 2)); } } } | cs |
실행부 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { class Program { static void Main(string[] args) { App app = new App(); app.Start(); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class App { private GameLauncher gameLauncher; //생성자 public App() { Console.WriteLine("App이 실행되었습니다."); this.gameLauncher = new GameLauncher(); } //앱실행 public void Start() { this.gameLauncher.Start(); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Threading; using Newtonsoft.Json; using System.Runtime.Serialization.Formatters.Binary; namespace TestEncryption { public class GameLauncher { private DataStorage dataStorage; private Anivia anivia; private NashorBaron baron; private Eggnivia eggnivia; private UserInfo userInfo; //생성자 public GameLauncher() { this.dataStorage = DataStorage.GetInstance(); } //런쳐실행 public void Start() { bool success; success = this.LoadData("./data/character_data.dat"); if (success) { Console.WriteLine("데이터 로딩에 성공했습니다!"); } success = this.LoadData("./info/user_info.dat"); if (success) { Console.WriteLine("환영합니다."); } this.SetData(); Console.WriteLine(this.userInfo.gameInfo.listCharInfo[1].remainHp); this.UpdateData(); this.GameStart(); } //데이터로드 public bool LoadData(string path) { switch (path) { case "./data/character_data.dat": { var isExist = File.Exists(path); if (isExist == false) { throw new Exception("게임을 플레이하기 위한 데이터가 없습니다"); } BinaryFormatter binaryFormatter = new BinaryFormatter(); FileStream fileStream = new FileStream(path, FileMode.Open); var temp = (byte[])binaryFormatter.Deserialize(fileStream); fileStream.Close(); MemoryStream memoryStream = new MemoryStream(); memoryStream.Write(temp, 0, temp.Length); memoryStream.Seek(0, SeekOrigin.Begin); this.dataStorage.dicCharData = (Dictionary<int, CharacterData>)binaryFormatter.Deserialize(memoryStream); memoryStream.Close(); return true; } case "./info/user_info.dat": { var isExist = File.Exists(path); if (isExist == false) { Console.WriteLine("새로운 유저의 데이터를 생성합니다."); this.userInfo = new UserInfo(new GameInfo()); this.userInfo.userId = 0; this.userInfo.userName = "유저"; this.userInfo.gameInfo.listCharInfo = new List<CharacterInfo>(); this.userInfo.gameInfo.listCharInfo.Add(new CharacterInfo(0)); this.userInfo.gameInfo.listCharInfo[0].remainHp = this.dataStorage.dicCharData[0].maxHp; this.userInfo.gameInfo.listCharInfo[0].position = new Vector2(0, 0); this.userInfo.gameInfo.listCharInfo.Add(new CharacterInfo(1)); this.userInfo.gameInfo.listCharInfo[1].remainHp = this.dataStorage.dicCharData[1].maxHp; this.userInfo.gameInfo.listCharInfo[1].position = new Vector2(0, 0); this.userInfo.gameInfo.listCharInfo.Add(new CharacterInfo(2)); this.userInfo.gameInfo.listCharInfo[2].remainHp = this.dataStorage.dicCharData[2].maxHp; this.userInfo.gameInfo.listCharInfo[2].position = new Vector2(15, 15); } else if (isExist) { BinaryFormatter binaryFormatter = new BinaryFormatter(); FileStream fileStream = new FileStream(path, FileMode.Open); var temp = (byte[])binaryFormatter.Deserialize(fileStream); fileStream.Close(); MemoryStream memoryStream = new MemoryStream(); memoryStream.Write(temp, 0, temp.Length); memoryStream.Seek(0, SeekOrigin.Begin); this.userInfo = (UserInfo)binaryFormatter.Deserialize(memoryStream); memoryStream.Close(); } return true; } default: { Console.WriteLine("경로가 잘못되었습니다."); return false; } } } //객체생성 public void SetData() { this.anivia = new Anivia(this.userInfo.gameInfo.listCharInfo[0]); this.eggnivia = new Eggnivia(this.userInfo.gameInfo.listCharInfo[1]); this.baron = new NashorBaron(this.userInfo.gameInfo.listCharInfo[2]); } //게임시작 public void GameStart() { bool aniviaAlive = true; bool baronAlive = true; Console.WriteLine("**************게임을 시작합니다*************"); while (true) { this.UpdateData(); Console.WriteLine("\n1.계속하기 2.저장하고 종료하기"); var continueKey = Console.ReadKey().Key; if (continueKey == ConsoleKey.D2) { this.SaveData(); break; } if (this.dataStorage.dicCharData[this.anivia.charInfo.id].attackRange <= this.anivia.GetDistance(this.baron.charInfo.position)) { Thread.Sleep(500); this.anivia.Move(this.baron.charInfo.position); } Thread.Sleep(500); baronAlive = this.anivia.Attack(this.baron); if (baronAlive == false) { Console.WriteLine("\n*****축하합니다. 게임을 클리어하셨습니다!*****"); break; } Thread.Sleep(1000); aniviaAlive = this.baron.Attack(this.anivia); if (aniviaAlive == false) { for (int remainTurn = 10; remainTurn > 0; remainTurn--) { Thread.Sleep(1000); this.baron.Attack(this.eggnivia); } this.anivia.charInfo.remainHp = this.dataStorage.dicCharData[this.anivia.charInfo.id].maxHp; this.eggnivia.charInfo.remainHp = this.dataStorage.dicCharData[this.eggnivia.charInfo.id].maxHp; } } Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("게임을 종료합니다."); } //데이터업데이트 (CharacterInfo List Update) public void UpdateData() { this.userInfo.gameInfo.listCharInfo[0].remainHp = this.anivia.charInfo.remainHp; this.userInfo.gameInfo.listCharInfo[0].position = this.anivia.charInfo.position; this.userInfo.gameInfo.listCharInfo[1].remainHp = this.eggnivia.charInfo.remainHp; this.userInfo.gameInfo.listCharInfo[1].position = this.eggnivia.charInfo.position; this.userInfo.gameInfo.listCharInfo[2].remainHp = this.baron.charInfo.remainHp; this.userInfo.gameInfo.listCharInfo[2].position = this.baron.charInfo.position; } //데이터를 파일로 저장 public void SaveData() { if (Directory.Exists("./info") == false) { Directory.CreateDirectory("./info"); } BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); binaryFormatter.Serialize(ms, this.userInfo); var temp = ms.ToArray(); FileStream fileStream = new FileStream("./info/user_info.dat", FileMode.Create); binaryFormatter.Serialize(fileStream, temp); fileStream.Close(); } } } | cs |
C#/과제 2019. 4. 10. 19:47
사용한 것 Singleton Pattern, Dictionary, List, Interface, Json(load, save), DataTable, Vector, UML, 상속
인터페이스 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public interface IAttackable { bool Attack(Character target); } } | cs |
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public interface IMoveable { void Move(Vector2 targetPosition); } } | cs |
캐릭터 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Character { public CharacterInfo charInfo; //생성자 public Character(CharacterInfo info) { this.charInfo = info; } //피해메소드 public virtual bool GetDamage(int damage) { return true; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Champion : Character { //생성자 public Champion(CharacterInfo info) : base(info) { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace AniviaVsNashor { public class Anivia : Champion, IAttackable, IMoveable { private float moveSpeed = 3.25f; private DataStorage dataStorage = DataStorage.GetInstance(); private Dictionary<int, CharacterData> dicData; //생성자 public Anivia(CharacterInfo info) : base(info) { this.dicData = this.dataStorage.dicCharData; } //피해메소드 public override bool GetDamage(int damage) { Console.WriteLine("{0}의 데미지를 입었습니다!", damage); this.charInfo.remainHp -= damage; if (this.charInfo.remainHp <= 0) { Console.WriteLine("체력이 0이 되어 에그니비아로 환생합니다."); Console.WriteLine("환생까지 10턴이 소모됩니다."); Thread.Sleep(500); return false; } Console.WriteLine("현재 체력 : ({0}/{1})", this.charInfo.remainHp, this.dicData[this.charInfo.id].maxHp); return true; } //거리를 리턴해주는 메소드 public float GetDistance(Vector2 targetPosition) { return Vector2.GetDistance(this.charInfo.position, targetPosition); } #region IAttackable, IMoveable 구현부분 public bool Attack(Character target) { Thread.Sleep(500); Console.WriteLine("\n{0}을 공격합니다.", this.dicData[target.charInfo.id].name); Console.WriteLine("{0}에게 {1}의 피해를 주었습니다!", this.dicData[target.charInfo.id].name, this.dicData[this.charInfo.id].damage); var alive = target.GetDamage(this.dicData[this.charInfo.id].damage); return alive; } public void Move(Vector2 targetPosition) //애니비아 이동속도 3.25 가정한다. { var distanceVector = targetPosition - this.charInfo.position; //거리벡터 var normalizeVector = Vector2.Normalize(distanceVector); //거리벡터의 단위벡터(방향벡터) var speedVector = normalizeVector * moveSpeed; //스칼라곱을 통하여 방향벡터로 향하는 속도벡터 산출 var distance = Vector2.GetDistance(this.charInfo.position, targetPosition); //타겟과의 거리 산출 while(true) { distance = Vector2.GetDistance(this.charInfo.position, targetPosition); Thread.Sleep(500); if (distance > this.dicData[this.charInfo.id].attackRange) { Console.WriteLine("사거리가 닿지 않아 이동합니다."); this.charInfo.position += speedVector; Console.WriteLine("현재 {0}의 위치 : ({1}/{2})", this.dicData[this.charInfo.id].name, this.charInfo.position.x, this.charInfo.position.y); } else if (distance <= this.dicData[this.charInfo.id].attackRange) { Console.WriteLine("사거리 내에 바론이 있습니다. 이동을 멈춥니다."); break; } } } #endregion } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Eggnivia : Champion { private DataStorage dataStorage = DataStorage.GetInstance(); private Dictionary<int, CharacterData> dicData; private int remainTurn = 9; //생성자 public Eggnivia(CharacterInfo info) : base(info) { this.dicData = this.dataStorage.dicCharData; } //피해메소드 public override bool GetDamage(int damage) { Console.WriteLine("{0}의 데미지를 입었습니다!", damage); this.charInfo.remainHp -= damage; if (this.remainTurn > 0) { Console.WriteLine("현재 체력 : ({0}/{1})", this.charInfo.remainHp, this.dicData[this.charInfo.id].maxHp); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("애니비아의 환생까지 {0}턴 남았습니다.", this.remainTurn); Console.ForegroundColor = ConsoleColor.Gray; this.remainTurn--; return false; } Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("****에그니비아가 애니비아로 환생합니다!****"); Console.ForegroundColor = ConsoleColor.Gray; remainTurn = 9; return true; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Monster : Character { //생성자 public Monster(CharacterInfo info) : base(info) { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class NashorBaron : Monster, IAttackable { private DataStorage dataStorage = DataStorage.GetInstance(); private Dictionary<int, CharacterData> dicData; //생성자 public NashorBaron(CharacterInfo info) : base(info) { this.dicData = this.dataStorage.dicCharData; } //피해메소드 public override bool GetDamage(int damage) { this.charInfo.remainHp -= damage; if (this.charInfo.remainHp <= 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\n바론이 죽었습니다!"); return false; } Console.WriteLine("{0}의 현재 체력 : ({1}/{2})", this.dicData[this.charInfo.id].name, this.charInfo.remainHp, this.dicData[this.charInfo.id].maxHp); return true; } #region IAttackable 구현부분 public bool Attack(Character target) { Console.WriteLine("\n{0}이 {1}를 공격합니다.", this.dicData[this.charInfo.id].name, this.dicData[target.charInfo.id].name); var alive = target.GetDamage(this.dicData[this.charInfo.id].damage); return alive; } #endregion } } | cs |
데이터 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class CharacterData { public int id; public string name; public int maxHp; public int remainHp; public int damage; public float attackRange; //생성자 public CharacterData() { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class DataStorage { private static DataStorage instance; public Dictionary<int, CharacterData> dicCharData; //생성자 private DataStorage() { } //인스턴스 리턴 메서드 public static DataStorage GetInstance() { if (DataStorage.instance == null) { DataStorage.instance = new DataStorage(); } return DataStorage.instance; } } } | cs
|
인포 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class CharacterInfo { public int id; public int remainHp { get; set; } public Vector2 position; //생성자 public CharacterInfo(int id) { this.id = id; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class UserInfo { public GameInfo gameInfo; public int userId { get; set; } public string userName { get; set; } //생성자 public UserInfo(GameInfo info) { this.gameInfo = info; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class GameInfo { public List<CharacterInfo> listCharInfo; //생성자 public GameInfo() { } } } | cs |
벡터 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class Vector2 { public float x; public float y; //생성자 public Vector2(float x, float y) { this.x = x; this.y = y; } //operator public static Vector2 operator +(Vector2 a, Vector2 b) { return new Vector2((a.x + b.x), (a.y + b.y)); } public static Vector2 operator -(Vector2 a, Vector2 b) { return new Vector2((a.x - b.x), (a.y - b.y)); } public static Vector2 operator *(Vector2 a, float b) { return new Vector2((a.x * b), (a.y * b)); } //calculate vector //정규화 메소드 public static Vector2 Normalize(Vector2 a) { return new Vector2((a.x / Vector2.GetLength(a)), (a.y / Vector2.GetLength(a))); } //길이리턴 메소드 public static float GetLength(Vector2 a) { return (float)Math.Sqrt(Math.Pow(a.x, 2) + Math.Pow(a.y, 2)); } //거리리턴 메소드 public static float GetDistance(Vector2 a, Vector2 b) { return (float)Math.Sqrt(Math.Pow(a.x - b.x, 2) + Math.Pow(a.y - b.y, 2)); } } } | cs |
실행부 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { class Program { static void Main(string[] args) { App app = new App(); app.Start(); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AniviaVsNashor { public class App { private GameLauncher gameLauncher; //생성자 public App() { Console.WriteLine("App이 실행되었습니다."); this.gameLauncher = new GameLauncher(); } //앱실행 public void Start() { this.gameLauncher.Start(); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Threading; using Newtonsoft.Json; namespace AniviaVsNashor { public class GameLauncher { private DataStorage dataStorage; private Anivia anivia; private NashorBaron baron; private Eggnivia eggnivia; private UserInfo userInfo; //생성자 public GameLauncher() { this.dataStorage = DataStorage.GetInstance(); } //런쳐실행 public void Start() { bool success; success = this.LoadData("./data/character_data.json"); if(success) { Console.WriteLine("데이터 로딩에 성공했습니다!"); } success = this.LoadData("./info/user_info.json"); if (success) { Console.WriteLine("환영합니다."); } this.SetData(); this.UpdateData(); this.GameStart(); } //데이터로드 public bool LoadData(string path) { switch(path) { case "./data/character_data.json": { var isExist = File.Exists(path); if(isExist == false) { throw new Exception("게임을 플레이하기 위한 데이터가 없습니다"); } this.dataStorage.dicCharData = new Dictionary<int, CharacterData>(); var temp = File.ReadAllText(path); var dataJson = JsonConvert.DeserializeObject<CharacterData[]>(temp); for (int index = 0; index < dataJson.Length; index++) { this.dataStorage.dicCharData.Add(index, dataJson[index]); } return true; } case "./info/user_info.json": { var isExist = File.Exists(path); if(isExist == false) { Console.WriteLine("새로운 유저의 데이터를 생성합니다."); this.userInfo = new UserInfo(new GameInfo()); this.userInfo.userId = 0; this.userInfo.userName = "유저"; this.userInfo.gameInfo.listCharInfo = new List<CharacterInfo>(); this.userInfo.gameInfo.listCharInfo.Add(new CharacterInfo(0)); this.userInfo.gameInfo.listCharInfo[0].remainHp = this.dataStorage.dicCharData[0].maxHp; this.userInfo.gameInfo.listCharInfo[0].position = new Vector2(0, 0); this.userInfo.gameInfo.listCharInfo.Add(new CharacterInfo(1)); this.userInfo.gameInfo.listCharInfo[1].remainHp = this.dataStorage.dicCharData[1].maxHp; this.userInfo.gameInfo.listCharInfo[1].position = new Vector2(0, 0); this.userInfo.gameInfo.listCharInfo.Add(new CharacterInfo(2)); this.userInfo.gameInfo.listCharInfo[2].remainHp = this.dataStorage.dicCharData[2].maxHp; this.userInfo.gameInfo.listCharInfo[2].position = new Vector2(15, 15); } else if(isExist) { Console.WriteLine("기존 유저의 데이터를 불러옵니다."); var temp = File.ReadAllText(path); var dataJson = JsonConvert.DeserializeObject<UserInfo>(temp); this.userInfo = dataJson; } return true; } default: { Console.WriteLine("경로가 잘못되었습니다."); return false; } } } //객체생성 public void SetData() { this.anivia = new Anivia(this.userInfo.gameInfo.listCharInfo[0]); this.eggnivia = new Eggnivia(this.userInfo.gameInfo.listCharInfo[1]); this.baron = new NashorBaron(this.userInfo.gameInfo.listCharInfo[2]); } //게임시작 public void GameStart() { bool aniviaAlive = true; bool baronAlive = true; Console.WriteLine("**************게임을 시작합니다*************"); while(true) { this.UpdateData(); Console.WriteLine("\n1.계속하기 2.저장하고 종료하기"); var continueKey = Console.ReadKey().Key; if(continueKey == ConsoleKey.D2) { this.SaveData(); break; } if (this.dataStorage.dicCharData[this.anivia.charInfo.id].attackRange <= this.anivia.GetDistance(this.baron.charInfo.position)) { Thread.Sleep(500); this.anivia.Move(this.baron.charInfo.position); } Thread.Sleep(500); baronAlive = this.anivia.Attack(this.baron); if(baronAlive == false) { Console.WriteLine("\n*****축하합니다. 게임을 클리어하셨습니다!*****"); break; } Thread.Sleep(1000); aniviaAlive = this.baron.Attack(this.anivia); if(aniviaAlive == false) { for(int remainTurn = 10; remainTurn > 0; remainTurn--) { Thread.Sleep(1000); this.baron.Attack(this.eggnivia); } this.anivia.charInfo.remainHp = this.dataStorage.dicCharData[this.anivia.charInfo.id].maxHp; this.eggnivia.charInfo.remainHp = this.dataStorage.dicCharData[this.eggnivia.charInfo.id].maxHp; } } Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("게임을 종료합니다."); } //데이터업데이트 (CharacterInfo List Update) public void UpdateData() { this.userInfo.gameInfo.listCharInfo[0].remainHp = this.anivia.charInfo.remainHp; this.userInfo.gameInfo.listCharInfo[0].position = this.anivia.charInfo.position; this.userInfo.gameInfo.listCharInfo[1].remainHp = this.eggnivia.charInfo.remainHp; this.userInfo.gameInfo.listCharInfo[1].position = this.eggnivia.charInfo.position; this.userInfo.gameInfo.listCharInfo[2].remainHp = this.baron.charInfo.remainHp; this.userInfo.gameInfo.listCharInfo[2].position = this.baron.charInfo.position; } //데이터를 파일로 저장 public void SaveData() { if(Directory.Exists("./info") == false) { Directory.CreateDirectory("./info"); } var dataJson = JsonConvert.SerializeObject(this.userInfo); File.WriteAllText("./info/user_info.json", dataJson); } } } | cs |
C#/Problems 2019. 4. 10. 03:26
BinaryFormatter와 FileStream을 이용하여 Serialize, Deserialize까지는 무난하게 구현했다. 후에 AES-128 암호화 방식을 이용하여 암호화된 값으로 직렬화를 하고, 복호화를 이용하여 역직렬화해서 파일로는 값을 못보고, 내부에서만 사용할 수 있게끔 만드려고 했다. 처음에는 AES-128을 API를 이용하지 않고 구현하려고 했으나, AES 알고리즘 과정 중 SubByte(State Array의 값들을 S-Box의 값과 치환하는 과정)에서 막혀서 API를 이용했다. 암호화까지에는 성공했으나, 복호화 과정에서 지속적으로 스트림에서 오류가 발생했다. 위처럼 Deserialize하는 스트림이 계속 비어있다고 뜨는데, 도무지 해답을 찾지 못하겠다. (이건 아마 내가 Stream에 대한 지식이 부족한 것 같다) 국내 사이트부터 외국 사이트, Docs, 논문 다 봤는데 모르겠다.
string형으로도 받아보고, byte[]형으로도 받아보려했으나, 자꾸 저 에러가 뜬다. 내일은 stream 공부 더해보고 오류 수정해야겠다. 이젠 진짜 자야겠다. 내일 늦으면 안되는데
AES만드려고 작성하던 Backup.cs 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Security.Cryptography; namespace TestMin { public static class Backup { //Serialize Method public static bool Serialize<T>(T obj, string path) { if (obj == null) { return false; } BinaryFormatter binaryFormatter = new BinaryFormatter(); FileStream fileStream = new FileStream(path, FileMode.Create); binaryFormatter.Serialize(fileStream, obj); fileStream.Close(); return true; } //Deserialize Method public static T Deserialize<T>(string path) { var isExists = File.Exists(path); if (isExists) { BinaryFormatter binaryFormatter = new BinaryFormatter(); FileStream fileStream = new FileStream(path, FileMode.Open); var temp = binaryFormatter.Deserialize(fileStream); fileStream.Close(); return (T)temp; } else { return default(T); } } //AES-256 Encryption public static void EncryptionToAES<T>(T obj) { BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream memoryStream = new MemoryStream(); binaryFormatter.Serialize(memoryStream, obj); byte[,] keyArr = new byte[4, 4] { {0x54, 0x4B, 0x20, 0x53 }, {0x48, 0x49, 0x4D, 0x45 }, {0x45, 0x4E, 0x49, 0x4F }, {0x20, 0x47, 0x4E, 0x4B } }; var plainText = memoryStream.ToArray(); byte[,] stateArr = new byte[4, 4] { {plainText[0], plainText[4], plainText[8], plainText[12] }, {plainText[1], plainText[5], plainText[9], plainText[13] }, {plainText[2], plainText[6], plainText[10], plainText[14] }, {plainText[3], plainText[7], plainText[11], plainText[15] } }; } //State sub S-Box public static void SubByte() { } //Take Round Key public static void KeyExpansion() { } //ShiftRow public static void ShiftRow(byte[] state) { for (int row = 1; row < 4; row++) //row1 ~ row3 { //byte[1] temp } } public static void KeySchedule() { //4의 배수 //Key 4열 추출 //1칸 Shift //S-Box와 치환 //Key+1열에서 -4열 추출 //-4열 XOR 치환열 XOR RCON } public static void MixColumn() { //(a(0,0)*02) XOR (a(1,0)*03) XOR (a(2,0)*01) XOR (a(3,0)*01) } } } | cs |
직렬화, 역직렬화, 암호화, 복호화 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Security.Cryptography; using System.Runtime.Serialization; namespace TestMin { public static class Minseok { //Serialize Method public static bool Serialize<T>(T obj, string path) { if (obj == null) { return false; } BinaryFormatter binaryFormatter = new BinaryFormatter(); FileStream fileStream = new FileStream(path, FileMode.Create); binaryFormatter.Serialize(fileStream, obj); fileStream.Close(); return true; } //Deserialize Method public static T Deserialize<T>(string path) { var isExists = File.Exists(path); if (isExists) { BinaryFormatter binaryFormatter = new BinaryFormatter(); FileStream fileStream = new FileStream(path, FileMode.Open); var temp = binaryFormatter.Deserialize(fileStream); fileStream.Close(); return (T)temp; } else { return default(T); } } //AES-128 Encryption public static byte[] EncryptionToAES<T>(T obj) { //Key byte[] keyArr = new byte[] { 0x54, 0x48, 0x45, 0x20, 0x4B, 0x49, 0x4E, 0x47, 0x20, 0x4D, 0x49, 0x4E, 0x53, 0x45, 0x4F, 0x4b }; //Convert obj to byte array BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream memoryStream = new MemoryStream(); binaryFormatter.Serialize(memoryStream, obj); var plainArr = memoryStream.ToArray(); memoryStream.Close(); //Initialization Vector (IV 생성) byte[] iV = Encoding.UTF8.GetBytes("THEJOEUNCOMPUTER"); //Encryption Aes aes = Aes.Create(); aes.KeySize = 128; aes.Key = keyArr; aes.Padding = PaddingMode.PKCS7; //padding 방법 aes.IV = iV; //대칭 Vector = default Vector ICryptoTransform aesForm = aes.CreateEncryptor(aes.Key, aes.IV); //암호화 기본 작업 인터페이스 변수에 Key, Iv를 가진 암호화 개체 생성 MemoryStream enMemoryStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(enMemoryStream, aesForm, CryptoStreamMode.Write); StreamWriter streamWriter = new StreamWriter(cryptoStream); streamWriter.Write(plainArr); byte[] chiperArr = enMemoryStream.ToArray(); enMemoryStream.Close(); return chiperArr; } //AES-128 Decryption public static T DecryptionByte<T>(byte[] chiperArr) { //Key byte[] keyArr = new byte[] { 0x54, 0x48, 0x45, 0x20, 0x4B, 0x49, 0x4E, 0x47, 0x20, 0x4D, 0x49, 0x4E, 0x53, 0x45, 0x4F, 0x4b }; ////Convert obj to byte array //BinaryFormatter binaryFormatter = new BinaryFormatter(); //MemoryStream memoryStream = new MemoryStream(); //binaryFormatter.Serialize(memoryStream, obj); //var plainArr = memoryStream.ToArray(); //memoryStream.Close(); //Initialization Vector (IV 생성) byte[] iV = Encoding.UTF8.GetBytes("THEJOEUNCOMPUTER"); //Decryption Aes aes = Aes.Create(); aes.KeySize = 128; aes.Key = keyArr; aes.Padding = PaddingMode.PKCS7; //padding 방법 aes.IV = iV; //대칭 Vector = default Vector ICryptoTransform dcryp = aes.CreateDecryptor(aes.Key, aes.IV); MemoryStream ms = new MemoryStream(); CryptoStream decrypStream = new CryptoStream(ms, dcryp, CryptoStreamMode.Write); decrypStream.Write(chiperArr, 0, chiperArr.Length); decrypStream.FlushFinalBlock(); ms.Position = 0; byte[] temp = new byte[ms.Length]; ms.Read(temp, 0, temp.Length); ms.Close(); BinaryFormatter formatter = new BinaryFormatter(); MemoryStream ms2 = new MemoryStream(temp, 0, temp.Length); formatter.Deserialize(ms2); return (T)temp; //ICryptoTransform cryptoTransform = aes.CreateDecryptor(aes.Key, aes.IV); //암호화 기본 작업 인터페이스 변수에 Key, Iv를 가진 복호화 개체 생성 //MemoryStream memoryStream = new MemoryStream(chiperArr); //CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read); //StreamReader streamReader = new StreamReader(cryptoStream); //MemoryStream memory2 = new MemoryStream(); //memory2.Write() //var ICustomFormatter = new BinaryFormatter(); //ICustomFormatter.Deserialize(streamReader); //var plainObject = streamReader.ReadToEnd(); //ICryptoTransform descrypt = aes.CreateDecryptor(aes.Key, aes.IV); //MemoryStream ms1 = new MemoryStream(chiperArr); //CryptoStream cryptoStream = new CryptoStream(ms1, descrypt, CryptoStreamMode.Read); //byte[] temp = new byte[chiperArr.Length]; //cryptoStream.Write(temp, 0, temp.Length); //StreamReader ms1Reader = new StreamReader(cryptoStream); //ms1Reader. //StreamWriter ms1Writer = new StreamWriter(cryptoStream); //ms1Writer.Write(chiperArr); //ms1.Read(temp, 0, temp.Length); //MemoryStream ms2 = new MemoryStream(temp); //ms2.Write(temp, 0, temp.Length); //IFormatter formatter = new BinaryFormatter(); //ms2.Seek(0, SeekOrigin.Begin); //T obj = (T)formatter.Deserialize(ms1); //return obj; } } } | cs |
C#/과제 2019. 4. 8. 21:16
1. Champion(애니비아)가 Monster(바론남작)을 향해 Move, Attack, MoveAttack(어택땅)하는 것을 구현 2. Vector를 이용하여 이동 속도, 이동 거리, 사거리 계산 및 구현 3. Json을 통하여 저장 및 불러오기가 가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace CharacterSystem { public class Character { public int Hp { get; set; } public int Damage { get; set; } public int AttackRange { get; set; } public string Name { get; set; } public float MoveSpeed { get; set; } public Vector2 position { get; set; } public Vector2 targetPosition { get; set; } private Vector2 movePoint; //매개변수 3개 생성자 public Character(int hp, int damage, int attackRange) { this.Hp = hp; this.Damage = damage; this.AttackRange = attackRange; } //이동 메서드 public virtual void Move(Vector2 movePoint) { this.movePoint = movePoint; var distanceVector = new Vector2(this.movePoint.x - this.position.x, this.movePoint.y - this.position.y); //거리벡터(C) var normalizationVector = Vector2.Nomrmalization(distanceVector); //거리벡터의 단위벡터(방향벡터) var speedVector = new Vector2(normalizationVector.x * this.MoveSpeed, normalizationVector.y * this.MoveSpeed); //A벡터가 방향벡터로 이동하는 속도벡터 while (true) { Thread.Sleep(300); this.position += speedVector; Console.WriteLine("{0}의 현재위치 : ({1}, {2})", this.Name, this.position.x, this.position.y); distanceVector = new Vector2(this.movePoint.x - this.position.x, this.movePoint.y - this.position.y); //거리벡터(C) if (distanceVector.x <= 0 && distanceVector.y <= 0) { this.position = new Vector2(movePoint.x, movePoint.y); Console.WriteLine("도착지점에 도착했습니다."); Console.WriteLine("{0}의 현재위치 : ({1}, {2})", this.Name, this.position.x, this.position.y); break; } else { continue; } } } //공격 메서드 public virtual void Attack(Character target, int attackCount) { var distanceVector = new Vector2(target.position.x - this.position.x, target.position.y - this.position.y); var distance = Vector2.GetLenght(distanceVector); if (distance <= this.AttackRange) { for(int i=0; i<attackCount; i++) { target.TakeDamage(this.Damage); Console.WriteLine("{0}회차 공격! {1}에게 {2}의 데미지를 입혔습니다!", i+1, target.Name, this.Damage); Thread.Sleep(300); Console.WriteLine("{0}의 남은 체력 : {1}", target.Name, target.Hp); } } else { Console.WriteLine("사거리가 닿지 않습니다."); } } //피해 메서드 public virtual void TakeDamage(int damage) { this.Hp -= damage; } //이동공격 메서드 public virtual void MoveAttack(Character target) { this.targetPosition = target.position; var distanceVector = new Vector2(target.position.x - this.position.x, target.position.y - this.position.y); //거리벡터 var normalizationVector = Vector2.Nomrmalization(distanceVector); //거리벡터의 단위벡터 var speedVector = new Vector2(normalizationVector.x * this.MoveSpeed, normalizationVector.y * this.MoveSpeed); //A벡터가 이동하는 속도벡터 var distance = Vector2.GetDistance(this.targetPosition, this.position); var selectAttackContinue = ConsoleKey.D1; while (selectAttackContinue != ConsoleKey.N) { Thread.Sleep(300); distance = Vector2.GetDistance(this.targetPosition, this.position); if(target.Hp <= 0) { Console.WriteLine("{0}가 죽었습니다.", target.Name); break; } if (distance <= this.AttackRange) { Console.WriteLine("{0}이 {1}의 공격사거리안에 들어왔습니다.\n공격을 시작합니다.", target.Name, this.Name); for(int i=0; target.Hp > 0; i++) { target.Hp -= this.Damage; Console.WriteLine("\n{0}회차 공격! {1}에게 {2}의 데미지를 입혔습니다!", i + 1, target.Name, this.Damage); Console.WriteLine("{0}의 남은 체력 : {1}", target.Name, target.Hp); Console.Write("계속 공격하시겠습니까? (Y/N) : "); selectAttackContinue = Console.ReadKey().Key; if(selectAttackContinue != ConsoleKey.Y) { Console.WriteLine("공격을 중지합니다."); Thread.Sleep(1000); break; } } } else if(distance >= this.AttackRange) { Console.WriteLine("사거리가 닿지 않아 타겟을 향해 이동합니다."); this.position += speedVector; } } } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CharacterSystem { public class Champion : Character { //매개변수 3개 생성자 public Champion(int hp, int damage, int attackRange) : base(hp, damage, attackRange) { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; namespace CharacterSystem { public class Anivia : Champion { //매개변수 3개 생성자 public Anivia(int hp, int damage, int attackRange) : base(hp, damage, attackRange) { this.Name = "애니비아"; this.MoveSpeed = 1.5f; this.position = new Vector2(0, 0); Console.WriteLine("애니비아 데미지 {0}", this.Damage); } //JsonConstructor [JsonConstructor] public Anivia(Vector2 position, Vector2 targetPosition, int hp, int damage, int attackRange, string name, float moveSpeed) : base(hp, damage, attackRange) { this.position = position; this.targetPosition = targetPosition; this.Name = name; this.MoveSpeed = moveSpeed; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CharacterSystem { public class Monster : Character { //매개변수 3개 생성자 public Monster(int hp, int damage, int attackRange) : base (hp, damage, attackRange) { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; namespace CharacterSystem { public class BaronNashor : Monster { //매개변수 3개 생성자 public BaronNashor(int hp, int damage, int attackRange) : base(hp, damage, attackRange) { this.Name = "내셔남작"; this.position = new Vector2(15, 15); this.targetPosition = new Vector2(0, 0); } //저장된 데이터 기반 생성자 public BaronNashor(int hp, int damage, int attackRange, string name, Vector2 position) : base(hp, damage, attackRange) { this.Name = name; this.position = position; } public override void Move(Vector2 movePoint) { Console.WriteLine("{0}은 이동할 수 없습니다."); } [JsonConstructor] public BaronNashor(Vector2 position, Vector2 targetPosition, int hp, int damage, int attackRange, string name, float moveSpeed) : base(hp, damage, attackRange) { this.position = position; this.targetPosition = targetPosition; this.Name = name; this.MoveSpeed = moveSpeed; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CharacterSystem { public class Vector2 { public float x; public float y; //생성자 public Vector2(float x, float y) { this.x = x; this.y = y; } //Vector2 Class Operator Overload public static Vector2 operator+(Vector2 a, Vector2 b) { return new Vector2(a.x + b.x, a.y + b.y); } public static Vector2 operator -(Vector2 a, Vector2 b) { return new Vector2(a.x - b.x, a.y - b.y); } public static Vector2 operator *(Vector2 a, Vector2 b) { return new Vector2(a.x * b.x, a.y * b.y); } public static Vector2 operator /(Vector2 a, Vector2 b) { return new Vector2(a.x / b.x, a.y / b.y); } //Distance public static float GetDistance(Vector2 position, Vector2 targetPosition) { return (float)Math.Sqrt(Math.Pow(position.x - targetPosition.x, 2) + Math.Pow(position.y - targetPosition.y, 2)); } //Nomalization public static Vector2 Nomrmalization(Vector2 vector) { return new Vector2(vector.x / Vector2.GetLenght(vector), vector.y / Vector2.GetLenght(vector)); } //Lenght public static float GetLenght(Vector2 vector) { return (float)Math.Sqrt((vector.x * vector.x) + (vector.y * vector.y)); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using System.Threading; using System.IO; namespace CharacterSystem { public class GameLauncher { public ConsoleKey menuKey; public ConsoleKey secondMenuKey; private DataStorage dataStorage; private BaronNashor baron; private Anivia anivia; //생성자 public GameLauncher(DataStorage dataStorage) { Console.WriteLine("GameLauncher 생성자 호출"); this.dataStorage = dataStorage; } //게임실행 메서드 public void Start() { while (menuKey != ConsoleKey.D3) { Console.WriteLine("바론남작 죽이기 게임"); Console.WriteLine("1.새로하기 2.불러오기 3.종료하기"); menuKey = Console.ReadKey().Key; if(menuKey == ConsoleKey.D3) { Console.WriteLine("바론남작 죽이기 게임을 종료합니다."); break; } else if(menuKey == ConsoleKey.D1 || menuKey == ConsoleKey.D2) { this.CreateData(menuKey); Console.WriteLine("게임을 시작합니다."); Thread.Sleep(1000); } else { Console.WriteLine("잘못된 입력입니다."); continue; } while(secondMenuKey != ConsoleKey.D7) { this.ChoiceSecondMenu(); switch(secondMenuKey) { case ConsoleKey.D1: Console.WriteLine("현재 {0}의 위치 : ({1}, {2})", this.baron.Name, this.baron.position.x, this.baron.position.y); Console.WriteLine("나와의 거리 : {0}", Vector2.GetDistance(this.anivia.position, this.baron.position)); Console.ReadKey(); break; case ConsoleKey.D2: Console.WriteLine("현재 나의 위치 : ({0}, {1})", this.anivia.position.x, this.anivia.position.y); Console.WriteLine("바론과의 거리 : {0}", Vector2.GetDistance(this.anivia.position, this.baron.position)); Console.ReadKey(); break; case ConsoleKey.D3: Console.Write("어디까지 이동하시겠습니까?(x y공백으로 구분하여 입력) : "); int x, y; var tempStr = Console.ReadLine(); string[] tempStrArr = tempStr.Split(' '); Int32.TryParse(tempStrArr[0], out x); Int32.TryParse(tempStrArr[1], out y); anivia.Move(new Vector2(x, y)); break; case ConsoleKey.D4: Console.Write("몇회 공격하시겠습니까? (최대 10회) : "); int attackCount; if (Int32.TryParse(Console.ReadLine(), out attackCount)) { anivia.Attack(baron, attackCount); } else { Console.WriteLine("잘못된 입력입니다."); } break; case ConsoleKey.D5: this.anivia.MoveAttack(baron); break; case ConsoleKey.D6: this.UpdateData(); var aniviaJson = JsonConvert.SerializeObject(this.anivia); File.WriteAllText("./data/anivia_data.json", aniviaJson, Encoding.UTF8); var baronJson = JsonConvert.SerializeObject(this.baron); File.WriteAllText("./data/baron_data.json", baronJson, Encoding.UTF8); //this.UpdateData(); //var json = JsonConvert.SerializeObject(this.dataStorage.listCharacter); //File.WriteAllText("./data/character_data.json", json, Encoding.UTF8); //Console.WriteLine("저장을 완료했습니다! 게임을 종료합니다."); Thread.Sleep(1000); secondMenuKey = ConsoleKey.D7; menuKey = ConsoleKey.D3; break; default: Console.WriteLine("잘못된 입력입니다."); break; } } } } //데이터 생성 Method public void CreateData(ConsoleKey menuKey) { if(menuKey == ConsoleKey.D1) { //새로하기일 경우 초기값의 인스턴스 생성 this.baron = new BaronNashor(10000, 100, 10); Console.WriteLine("{0}생성, 체력:{1}, 데미지:{2}, 사거리:{3}", baron.Name, baron.Hp, baron.Damage, baron.AttackRange); this.anivia = new Anivia(550, 25, 5); Console.WriteLine("{0}생성, 체력:{1}, 데미지:{2}, 사거리:{3}", anivia.Name, anivia.Hp, anivia.Damage, anivia.AttackRange); Directory.CreateDirectory("./data/"); } else if(menuKey == ConsoleKey.D2) { if(!(File.Exists("./data/anivia_data.json") || File.Exists("./data/baron_data.json"))) { Console.WriteLine("저장된 데이터가 없습니다."); Directory.CreateDirectory("./data/"); this.baron = new BaronNashor(10000, 100, 10); Console.WriteLine("{0}생성, 체력:{1}, 데미지:{2}, 사거리:{3}", baron.Name, baron.Hp, baron.Damage, baron.AttackRange); this.anivia = new Anivia(550, 25, 5); Console.WriteLine("{0}생성, 체력:{1}, 데미지:{2}, 사거리:{3}", anivia.Name, anivia.Hp, anivia.Damage, anivia.AttackRange); } else { //애니비아 데이터 불러오기 var aniviaStr = File.ReadAllText("./data/anivia_data.json"); var aniviaArr = JsonConvert.DeserializeObject<Anivia>(aniviaStr); this.anivia = aniviaArr; //바론 데이터 불러오기 var baronStr = File.ReadAllText("./data/baron_data.json"); var baronArr = JsonConvert.DeserializeObject<BaronNashor>(baronStr); this.baron = baronArr; //생성 확인 Console.WriteLine("{0}생성, 체력:{1}, 데미지:{2}, 사거리:{3}", baron.Name, baron.Hp, baron.Damage, baron.AttackRange); Console.WriteLine("{0}생성, 체력:{1}, 데미지:{2}, 사거리:{3}", anivia.Name, anivia.Hp, anivia.Damage, anivia.AttackRange); } } } //공격, 이동, 어택땅 선택 Method public void ChoiceSecondMenu() { Console.WriteLine("1.바론위치보기 2.내위치보기 3.이동하기 4.공격하기 5.어택땅 6.저장하고 돌아가기"); this.secondMenuKey = Console.ReadKey().Key; } //데이터 업데이트 Method public void UpdateData() { this.dataStorage.listCharacter.Add(this.anivia); this.dataStorage.listCharacter.Add(this.baron); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CharacterSystem { public class App { private GameLauncher gameLauncher; private DataStorage dataStorage; public App() { Console.WriteLine("App 생성자 호출"); this.DataLoad(); this.gameLauncher = new GameLauncher(this.dataStorage); } public void Start() { this.gameLauncher.Start(); } public void DataLoad() { this.dataStorage = DataStorage.GetDataStorage(); } } } | cs |
Anivia Class 와 BaronNashor Class에서 [JsonConstructor]라는 것이 있다. 이는 Newtonsoft.Json에서 지원하는 기능 중 하나로, JsonFile을 로드하여 그 File의 값을 통해 인스턴스를 생성할 때, 그에 맞는 Json전용 Constructor(생성자)를 선언할 수 있게 해주는 도구이다.
JsonConstructorAttribute (NewtonJson) https://www.newtonsoft.com/json/help/html/JsonConstructorAttribute.htm
C#/과제 2019. 4. 7. 21:16
Inventory 저장 및 불러오기 기능 + DataStorage Singleton 패턴으로 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _0407 { public class WeaponData { public int id; public int count; public string name; public int damage; public WeaponData(int id, int count, string name, int damage) { this.id = id; this.count = 1; this.name = name; this.damage = damage; } } } | cs |
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _0407 { public class WeaponInfo : ItemInfo { public WeaponInfo(int id) : base(id) { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _0407 { public class WeaponItem : Item { new public WeaponInfo info; public WeaponItem(WeaponInfo info) : base(info) { this.info = info; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _0407 { public class ItemInfo { public int id; public int count; public ItemInfo(int id) { this.id = id; this.count = 1; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _0407 { public class Item { public ItemInfo info; public Item(ItemInfo info) { this.info = info; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _0407 { public class InventoryInfo { private List<WeaponItem> itemList; public InventoryInfo(List<WeaponItem> list) { itemList = list; } public List<WeaponItem> ReturnList() { return this.itemList; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using System.IO; namespace _0407 { public class Inventory { private List<WeaponItem> itemList; private DataStorage storage; public InventoryInfo info; public Inventory(InventoryInfo info) { this.info = info; this.itemList = info.ReturnList(); this.storage = DataStorage.MakeDataStorage(); } //추가 메서드 public bool AddItem(string name) { var index = FindIndex(name); if (index != -1) { foreach(var item in itemList) { if(item.info.id == index) { item.info.count++; return true; } } var weapon = new WeaponItem(new WeaponInfo(index)); this.itemList.Add(weapon); Console.WriteLine("{0}이 인벤토리에 등록되었습니다.", name); return true; } Console.WriteLine("존재하지 않는 아이템입니다."); return false; } //dictionary key찾는메서드 public int FindIndex(string name) { for (int index = 0; index < storage.dicWeaponData.Count; index++) { if (storage.dicWeaponData[index].name == name) { return index; } } return -1; } //출력메서드 public void PrintInventory() { foreach(var item in itemList) { Console.WriteLine("{0}x{1}",storage.dicWeaponData[item.info.id].name, item.info.count); } } //삭제메서드 public bool RemoveItem(string name, int count) { var dicKey = FindIndex(name); int index = 0; if(dicKey != -1) { foreach (var item in itemList) { if (item.info.id == dicKey) { if(item.info.count<=count) { Console.WriteLine("{0}를 {1}개 버렸습니다.", name, item.info.count); itemList.RemoveAt(index); return true; } Console.WriteLine("{0}를 {1}개 버렸습니다.", name, count); item.info.count -= count; return true; } index++; } } return false; } public void SaveInventory() { var json = JsonConvert.SerializeObject(this.itemList); File.WriteAllText("./inventory_info.json", json, Encoding.UTF8); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _0407 { public class GameLauncher { private Inventory inventory; public GameLauncher(Inventory inventory) { this.inventory = inventory; } public void GameStart() { var menuKey = ConsoleKey.D5; while (menuKey!=ConsoleKey.D6) { Console.WriteLine("1.아이템제작 2.인벤토리보기 3.아이템꺼내기 4.저장후 종료"); menuKey = Console.ReadKey().Key; switch (menuKey) { case ConsoleKey.D1: Console.WriteLine("프람베르그 / 무라마사 / 다마스커스 / 슈팅스타 / 등뒤를 베는자"); Console.Write("제작하실 아이템 이름을 입력하세요 : "); var inputName = Console.ReadLine(); int createCount; Console.Write("몇개 제작하시겠습니까?"); Int32.TryParse(Console.ReadLine(), out createCount); for(int count=0; count<createCount; count++) { inventory.AddItem(inputName); } break; case ConsoleKey.D2: inventory.PrintInventory(); break; case ConsoleKey.D3: Console.Write("버리실 아이템 이름을 입력하세요 : "); var dropItemName = Console.ReadLine(); int dropCount; Console.Write("몇개 버리시겠습니까?"); Int32.TryParse(Console.ReadLine(), out dropCount); var success = inventory.RemoveItem(dropItemName, dropCount); if (success == false) { Console.WriteLine("인벤토리에 {0}이 존재하지 않습니다.", dropItemName); } break; case ConsoleKey.D4: inventory.SaveInventory(); Console.WriteLine("저장이 완료되었습니다."); Console.WriteLine("프로그램을 종료합니다."); menuKey = ConsoleKey.D6; break; } } } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _0407 { public class DataStorage { private static DataStorage instance; public Dictionary<int, WeaponData> dicWeaponData = new Dictionary<int, WeaponData>(); protected DataStorage() { } public static DataStorage MakeDataStorage() { if(instance == null) { instance = new DataStorage(); } return instance; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using Newtonsoft.Json; namespace _0407 { public class App { private GameLauncher gameLauncher; private DataStorage storage; public App() { this.gameLauncher = new GameLauncher(CreateInventory()); } //시작 메서드 public void Start() { this.LoadData(); this.GameStart(); } //데이터로드 메서드 public void LoadData() { this.storage = DataStorage.MakeDataStorage(); var str = File.ReadAllText("./weapon_item_data.json"); var arrJson = JsonConvert.DeserializeObject<WeaponData[]>(str); foreach(var addJson in arrJson) { storage.dicWeaponData.Add(addJson.id, addJson); } } //인벤토리 제작 메서드 public Inventory CreateInventory() { var isExist = File.Exists("./inventory_info.json"); if (isExist) { var str = File.ReadAllText("./inventory_info.json"); var arrJson = JsonConvert.DeserializeObject<List<WeaponItem>>(str); return new Inventory(new InventoryInfo(arrJson)); } else { List<WeaponItem> list = new List<WeaponItem>(); return new Inventory(new InventoryInfo(list)); } } //런쳐시작 메서드 public void GameStart() { this.gameLauncher.GameStart(); } } } | cs |
C#/수업내용 2019. 4. 4. 16:52
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class RawData { public int id; public RawData() { } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class WeaponData : RawData { public string name; public int level; public int damage_min; public int damage_max; public WeaponData(int id, string name, int level, int min, int max) { this.id = id; this.name = name; this.level = level; this.damage_min = min; this.damage_max = max; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class WeaponInfo { public int id; public int damage; public WeaponInfo(int id, int damage_min, int damage_max) { Random rand = new Random(); this.id = id; this.damage = rand.Next(damage_min, damage_max); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class WeaponItem { public WeaponInfo info; public WeaponItem(WeaponInfo info) { this.info = info; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class ArmorData :RawData { public string name; public int level; public int armor_min; public int armor_max; public ArmorData(int id, string name, int level, int min, int max) { this.id = id; this.name = name; this.level = level; this.armor_min = min; this.armor_max = max; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class ArmorInfo :RawData { public int armor; public ArmorInfo(int id, int armor_min, int armor_max) { Random rand = new Random(); this.id = id; this.armor = rand.Next(armor_min, armor_max); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class ArmorItem { public ArmorInfo info; public ArmorItem(ArmorInfo info) { this.info = info; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class CharStatData :RawData { public string name; public int main_stat_id; public float main_stat_val; public int sub_stat_id; public float sub_stat_val; public CharStatData(int id, string name, int main_stat_id, float main_stat_val, int sub_stat_id, float sub_stat_val) { this.id = id; this.name = name; this.main_stat_id = main_stat_id; this.main_stat_val = main_stat_val; this.sub_stat_id = sub_stat_id; this.sub_stat_val = sub_stat_val; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Study_0404 { public class StatData :RawData { public string name; public StatData(int id, string name) { this.id = id; this.name = name; } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using Newtonsoft.Json; namespace Study_0404 { public class App { public Dictionary<int, WeaponData> dicWeaponItem; public Dictionary<int, ArmorData> dicArmorItem; public Dictionary<int, StatData> dicStatData; public Dictionary<int, CharStatData> dicCharStatData; public App() { dicWeaponItem = new Dictionary<int, WeaponData>(); dicArmorItem = new Dictionary<int, ArmorData>(); dicStatData = new Dictionary<int, StatData>(); dicCharStatData = new Dictionary<int, CharStatData>(); } public void Start() { LoadData("./Data/weapon_data.json", dicWeaponItem); LoadData("./Data/armor_data.json", dicArmorItem); LoadData("./Data/stat_data.json", dicStatData); LoadData("./Data/char_stat_data.json", dicCharStatData); for(int i = 0; i < 5; i++) { Console.WriteLine("{0}",dicWeaponItem[i].name); } for (int i = 0; i < 5; i++) { Console.WriteLine("{0}",dicArmorItem[i].name); } for (int i = 100; i < 105; i++) { Console.WriteLine("{0}",dicStatData[i].name); } for (int i = 0; i < 5; i++) { Console.WriteLine("{0}{1}",dicCharStatData[i].id, dicCharStatData[i].name); } } //data load method public void LoadData<T>(string path, Dictionary<int, T> dictionary) where T : RawData { var str = File.ReadAllText(path); var arrJson = JsonConvert.DeserializeObject<T[]>(str); foreach(var json in arrJson) { dictionary.Add(json.id, json); } } //아이템 인스턴스화 /* public WeaponItem CreateItem(int id, int type) { Random rand = new Random(); if(type == 0) { int damageOrArmor = rand.Next(dicWeaponItem[id].damage_min, dicWeaponItem[id].damage_max); ItemInfo info = new ItemInfo(id, type, damageOrArmor); return new WeaponItem(info); } else if(type == 1) { int damageOrArmor = rand.Next(dicArmorItem[id].armor_min, dicArmorItem[id].armor_max); ItemInfo info = new ItemInfo(id, type, damageOrArmor); return new WeaponItem(info); } return default(WeaponItem); } */ } } | cs |
|