public void ImageChange()
    {
        // 이미지 컴포넌트
        var myImage = GameObject.FindObjectOfType<Image>();

        // Sprite 파일 laod
        var swordImage = Resources.Load("Texteres/icon_sword", typeof(Sprite)) as Sprite;

        // 이미지 컴포넌트 sprite 에 load한 파일 체인지
        myImage.GetComponent<Image>().sprite = swordImage;
    }

 

대리자 콜백 부분이랑 / 이펙트가 에니메이션이 아니고 파티클 시스템이라 시간 많이 잡아 먹음 ㅜㅜ

시간 관계상 누르면 도끼 생성해서 던지는것으로 대체 

> 다시 복습하는 차원에서, 다시 본다. 

- gameobject -> hero 빈 프리팹 만들어 놓고, 클론하는 방법인데 / 빈 hero 프리팹 없이 가능한건가? 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Ingame : MonoBehaviour
{
    public Hero hero;
   
    public void Init(int characterId)
    {
        var data = DataManager.GetInstance().GetCharacterDataById(characterId);

        var path = string.Format("Prefabs/{0}", data.res_name);
        var prefab = Resources.Load(path) as GameObject;
        var modelGo = Instantiate(prefab);
        // 캐릭터 프리팹
        
        var heroPrefab = Resources.Load<GameObject>("Prefabs/hero");
        var heroGo = Instantiate<GameObject>(heroPrefab);
        this.hero = heroGo.AddComponent<Hero>();
        // 클론 상위 프리팹

        // 클론 hero 컴포넌트에 캐릭터 컴포넌트 붙이기 
        modelGo.transform.SetParent(this.hero.transform);

    }
    
    public static void log(object data) { Debug.Log(data); }
}

 

> 예제

using UnityEngine;
using UnityEngine.SceneManagement;

public class ExampleCode : MonoBehaviour
{
    void Start()
    {
    	  DonDestroyOnLoad();
        // Start는 최초 씬에서만 호출된다.
    }

    void OnEnable()
    {
    	  // 씬 매니저의 sceneLoaded에 체인을 건다.
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    // 체인을 걸어서 이 함수는 매 씬마다 호출된다.
    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        Debug.Log("OnSceneLoaded: " + scene.name);
        Debug.Log(mode);
    }

    void OnDisable()
    {
        SceneManager.sceneLoaded -= OnSceneLoaded;
    }
}

 

> 로비 씬에서 인게임 씬에 데이터 넘겨주기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;

public class Lobby : MonoBehaviour
{
    public Button btn1;
    public Button btn2;
    public int id;


    // Start is called before the first frame update
    void Start()
    {
        this.btn1.onClick.AddListener(() =>
        {
            log("1");
            SceneManager.sceneLoaded += SceneLoad; // 씬 로드 될 때 실행
            SceneManager.LoadScene("Ingame");
        });

        this.btn2.onClick.AddListener(() =>
        {
            log("2");
            SceneManager.sceneLoaded += SceneLoad;
            SceneManager.LoadScene("Ingame");
        });
    }

    private void SceneLoad(Scene scene, LoadSceneMode mode)
    {

        log("[Lobby] 델리게이트");
        this.id = 100;
        GameObject inGameGo = GameObject.Find("Ingame");
        var ingame = inGameGo.GetComponent<Ingame>();
        ingame.Init(this.id);
    }

    // Update is called once per frame
    void Update()
    {
    }

    public static void log(object data) { Debug.Log(data); }
}

'c# 강의 > 유니티' 카테고리의 다른 글

▶ 유니티/싱글톤 - DataManager  (0) 2020.05.12
▶ 마우스 이벤트  (0) 2020.05.11
20200511 - 현재까지 패키지 구성  (0) 2020.05.11
20200511 - Scene  (0) 2020.05.11
20200511 - FindWithTag (자주 쓰이는 예제 필요)  (0) 2020.05.11

> 정리

> 클래스
- : MonoBehaviour 삭제

> 생성자 
- private DataManager()  디셔너리 초기화

> 멤버
- private static DataManager instance;
- priavte Dictionary<int, data타입> dic타입datas;

> 인스턴스 메소드
- public static DataManager GetInstance(){
    if(DataManager.instance == null) DataManager.instance = new DataManager();
    return DataManager.instance;
}

> JSON Data 파일 직렬화
- LoadDatas();
- Resources.Load("Data/chacacter_data") <-- Object 타입 리턴
- Json파일은 TextAsset타입으로 받을수 있다.
- TextAsset textAsset = Resources.Load("Data/character_data") as TextAsset;
- string json = textAsset.text;
- data.cs 만들어논 타입[]로 직렬화 
- 디셔너리 =  타입[].ToDictionary( x => x.id);

> data 값 리턴해주는 메소드들 작성

 

> code 참고

더보기
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Newtonsoft.Json;

public class DataManager
{
    private static DataManager instance;
    private Dictionary<int, CharacterData> dicCharacterDatas;


    private DataManager()
    {
        this.dicCharacterDatas = new Dictionary<int, CharacterData>();
    }

    public DataManager GetInstance()
    {
        if (DataManager.instance == null)
        {
            DataManager.instance = new DataManager();
        }
        return DataManager.instance;
    }

    public void LoadData()
    {
        TextAsset textAsset = Resources.Load("data/character_data") as TextAsset;
        string json = textAsset.text;
        Debug.Log(json);

        CharacterData[] arrCharacterData = JsonConvert.DeserializeObject<CharacterData[]>(json);

        this.dicCharacterDatas = arrCharacterData.ToDictionary(x => x.id);

    }

    public CharacterData GetCharacterDataById(int id)
    {
        return this.dicCharacterDatas[id];
    }


}

'c# 강의 > 유니티' 카테고리의 다른 글

20200512 - 델리게이트 / 대리자  (0) 2020.05.12
▶ 마우스 이벤트  (0) 2020.05.11
20200511 - 현재까지 패키지 구성  (0) 2020.05.11
20200511 - Scene  (0) 2020.05.11
20200511 - FindWithTag (자주 쓰이는 예제 필요)  (0) 2020.05.11
public class ExampleClass : MonoBehaviour {
    void Update() { 
        //  0, 1, 2에 따라 마우스 [왼쪽버튼], [오른쪽버튼], [휠버튼]

        if (Input.GetMouseButton (0))
            Debug.Log("마우스 버튼을 누르는 동안");
        
        if (Input.GetMouseButtonDown (1))
            Debug.Log("마우스 버튼을 누른 순간");
        
        if (Input.GetMousebuttonUp (2))
            Debug.Log("마우스 버튼을 눌렀다 때는 순간.");
     // Input.mousePositio  마우스 클릭한 좌표값 얻을수 있음
    }
}
Assets
ㄴ ArtResources
ㄴ Resources
    ㄴ Data
    ㄴ Prefabs
ㄴ Scenes
ㄴ Scripts
    ㄴ Data
ㄴ Textures

 

'c# 강의 > 유니티' 카테고리의 다른 글

▶ 유니티/싱글톤 - DataManager  (0) 2020.05.12
▶ 마우스 이벤트  (0) 2020.05.11
20200511 - Scene  (0) 2020.05.11
20200511 - FindWithTag (자주 쓰이는 예제 필요)  (0) 2020.05.11
20200508 - 프리팹  (0) 2020.05.08

 

> 정리


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using Newtonsoft.Json;

public class App : MonoBehaviour
{
    float timer;
    int logoWaitingTime;
    int titleWaitingTime;

    private void Awake()
    {
          UnityEngine.Object.DontDestroyOnLoad(this);
    }

    void Start()
    {
        this.timer = 0.0f; // 타이머
        this.logoWaitingTime = 1; // 로고 시간
        this.titleWaitingTime = 1; // 타이틀 시간
    }

    // Update is called once per frame
    void Update()
    {
        this.timer += Time.deltaTime;

        if (this.timer > logoWaitingTime){
            SceneManager.LoadScene("Logo");
        }

        if (this.timer > titleWaitingTime){
            SceneManager.LoadScene("Title");
            this.timer = 0.0f;
        }
    }
}

 

 

> 씬 적용 순서

 

 

 


강의중 기록

 

 

 

App - 로고 - 타이틀 - 로딩화면 - 로비 - 인게임

App: 진입씬

여러가지 씬들은 전환될수 있다

 

  • 씬 (로고, 타이틀)
  • 팝업: 닫기 버튼이 무조건 있음
  • 페이지: 뒤로가기가 무조건 있음

// 팝업과 페이지는 씬으로 보지 않음


 

 

 

 

 

 

 


 

 

 

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class App : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // logo 씬으로 전환
        SceneManager.LoadScene("logo");
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void log(object data)
    {
        Debug.Log(data);
    }
}

 

> app -> logo -> title 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class App : MonoBehaviour
{
    // Start is called before the first frame update

    private void Awake()
    {
        UnityEngine.Object.DontDestroyOnLoad(this);
    }

    void Start()
    {
        // logo 씬으로 전환
        SceneManager.LoadScene("logo");
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void log(object data)
    {
        Debug.Log(data);
    }
}

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Title : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            this.log("down click");

            SceneManager.LoadScene("Lobby");
        }

        if (Input.GetMouseButtonUp(0))
        {
            this.log("up click");
            SceneManager.LoadScene("Lobby");

        }
    }

    void log(object data)
    {
        Debug.Log(data);
    }
}

 

 

    private void Awake()
    {
       var mainCamGo = GameObject.FindWithTag("Player");

        Debug.Log(mainCamGo.name);
    }

'c# 강의 > 유니티' 카테고리의 다른 글

20200511 - 현재까지 패키지 구성  (0) 2020.05.11
20200511 - Scene  (0) 2020.05.11
20200508 - 프리팹  (0) 2020.05.08
20200507 - 캐릭터 생성 및 무기 장착  (0) 2020.05.08
20200508 - 벡터1  (0) 2020.05.08

> 사용법

글쓰기 -> 코드블럭

 

코드블럭 사용법 C++ 로 선택하면되고 C#과 크게 차이 없음


> 적용법 

 

적용하면 코드블럭 쉽게 사용가능

 

(티스토리 플러그인 사용해도 되지만 좌측 라인넘버라던가 뭔가 불편해서 직접 CDN 적용) 

코드블럭  변경1


> 전체 드래그해서 복붙

<!-- 색상 등 css파일  -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.2/styles/atelier-dune-dark.min.css">

<!-- 하이라이트 적용  -->
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.2/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

<!-- 코드 줄 번호 적용  -->
<script src="//cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.7.0/highlightjs-line-numbers.min.js"></script>
<script>hljs.initLineNumbersOnLoad();</script>

<!-- 코드 블럭 내 폰트 [종류] 및 [폰트크기] 변경  -->
<link href='https://fonts.googleapis.com/css?family=Fira Mono' rel='stylesheet'>
<style>
    pre>code {
        font-family: 'Fira Mono' !important; 
        font-size: 14px !important;
    }
</style>

 

복붙 후


> 폰트 종류 및 크기 변경

폰트 종류 확인 - 가독성 좋은 Mono 타입 중에 선택 추천

https://fonts.google.com/?category=Monospace

 

Google Fonts

Making the web more beautiful, fast, and open through great typography

fonts.google.com

 

IBM Plex Mono  추천

 


> 코드블럭 테마 변경

https://highlightjs.org/static/demo/

 

highlight.js demo

 

highlightjs.org

 

맘에 드는 테마를 확인 한다.

 

위에 테마 붙여넣기 한  Html 편집하는 부분  css파일 이름을 바꿔주면 된다. 

※ 위의 테마명에서 대문자소문자띄어쓰기- 로변경한다.    Atom One Drak → atom-one-dark

styles/      .min.css      사이에 변환한 테마명을 넣고 저장하면 끝

 

 


- 좀 더 쉽게 활용 할 수 있는 방법 있으시면 공유 해주세요.

> GameObject 가 파일화 된 것

 

 

 

클론 프리팹 연결 해제

 

폴더 이름 대소문자 까지 같아야함 위치는 상관없음

 

Prefabs 폴더 생성

 

 


> 리소스 불러오기

public GameObject heroPrefab;

void Start(){
this.heroPrefab =  Resources.Load("Prefabs/ch_01_01") as GameObject;
        Debug.Log(this.heroPrefab);
        
        }

 

 

 


 

 

1. prefab을 로드 한다(Hero, ch_01_01 )

-> Resources.Load(경로) 확장자 제외 Assets/Resources 까지 상위 폴더 경로 필요

    Resources.Load(경로) as GameObject;

-> Resources.Load<GameObject>(path) 가능하다.

 

2. Hero 프리팹을 Instantiate 한다 -> Hero 프리팹의 Clone게임오브젝트 생성됨.

 

3. Hero컴포넌트를 부착

  ->  this.heroPrefab.AddComponent<Hero>();

 

4. Model(ch_01_01) 프리팹을 Instantiate 한다

-> ch_01_01 프리팹의 Clone 게임오브젝트 생성됨

 

5. ch_01_01게임 오브젝트(Clone)의 부모로 Hero 게임 오브젝트 (Clone) 를 설정

 this.transform.SetParent(paransfrom);

this.transform.SetParent(paransfrom, false);

 

'c# 강의 > 유니티' 카테고리의 다른 글

20200511 - Scene  (0) 2020.05.11
20200511 - FindWithTag (자주 쓰이는 예제 필요)  (0) 2020.05.11
20200507 - 캐릭터 생성 및 무기 장착  (0) 2020.05.08
20200508 - 벡터1  (0) 2020.05.08
20200508 - 복습  (0) 2020.05.08

 

 

 

 


 

> Code

더보기

> App.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class App : MonoBehaviour
{
    public Button btn;
    public GameObject heroPrefab;
    public GameObject weaponPrefab;

    private void Start()
    {
        this.btn.onClick.AddListener(() => {
            var heroModelGo = this.CreateModel();
            var weaponGo = this.CreateWeapon();
            var dummyRHand = heroModelGo.GetComponent<HeroModel>().dummyRHand;
            weaponGo.transform.SetParent(dummyRHand, false);
        });
    }

    private GameObject CreateModel()
    {
        return Instantiate(this.heroPrefab);
    }
    private GameObject CreateWeapon()
    {
        return Instantiate(this.weaponPrefab);
    }

}

 

>HeroModel.cs 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HeroModel : MonoBehaviour
{

    public Transform dummyRHand;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

'c# 강의 > 유니티' 카테고리의 다른 글

20200511 - FindWithTag (자주 쓰이는 예제 필요)  (0) 2020.05.11
20200508 - 프리팹  (0) 2020.05.08
20200508 - 벡터1  (0) 2020.05.08
20200508 - 복습  (0) 2020.05.08
20200507 - 오브젝트 생성 및 부모설정(Instantiate)  (0) 2020.05.08
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class App : MonoBehaviour
{

    public GameObject hero;
    public GameObject monster;

    void Start()
    {
        float distance = Vector3.Distance(this.hero.transform.position, this.monster.transform.position);

        Vector3 c = this.hero.transform.position - this.monster.transform.position;
        // 방향은 모른다.
        Debug.Log(c.magnitude);

        // 정규화 시켜서 길이를 1로 만든다. 그럼 방향을 알수 있다.
        Debug.Log(c.normalized);
        
    }
}

ctor3 distance 는 벡터의 길이
길이가 1인 벡터를 만든다. 단위 벡터 
비교하기 쉽게하기 위해

'c# 강의 > 유니티' 카테고리의 다른 글

20200508 - 프리팹  (0) 2020.05.08
20200507 - 캐릭터 생성 및 무기 장착  (0) 2020.05.08
20200508 - 복습  (0) 2020.05.08
20200507 - 오브젝트 생성 및 부모설정(Instantiate)  (0) 2020.05.08
20200507 - 애니메이션2  (0) 2020.05.08

> gameObject의 App 컴포넌트가 비활성화시 Awake 함수 호출됨

그러나 gameObject 가 비활성화시 Awake 함수 호출안됨

App 컴포넌트가 활성화 되면 Start함수는 한번만 호출됨

App 컴포넌트가 활성화 되면 update 매프레임마다 호출되지만 비활성화시 update함수 호출 안됨

App 컴포넌트에 ㅂ줕어 있는 gameObject가 비활성화시 update함수 호출 안됨

플레이를 멈췄을 경우 Ppp컴포넌트의 OnDestory 함수 호출됨

 

 

 

 

 


 

> 오브젝트,스크립트 설정

 

 


> App.cs

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class App : MonoBehaviour
{
    public Hero hero;
    public GameObject[] arrHeroModels;
    public string modelName;

    // Start is called before the first frame update
    void Start()
    {
      //  this.modelName = "";
        Debug.Log(this.modelName.ToString());

        this.hero.Init(this.CreateModel(this.modelName));
    }

    private GameObject CreateModel(string modelName)
    {
        GameObject foundModel = null;
        foreach (GameObject model in this.arrHeroModels)
        {
            if (model.name == modelName)
            {
                foundModel = model;
                break;
            }
        }
        Debug.LogFormat("model: {0}", foundModel);

        //게임오브젝트를 생성함 
        var newModel = UnityEngine.Object.Instantiate(foundModel);
        return newModel;
    }
}

 

> Hero.cs

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hero : MonoBehaviour
{
    public GameObject hero;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    public void Init(GameObject newModel)
    {
        //newModel.transform.SetParent(this.transform);
        newModel.transform.SetParent(this.transform, false);
        Debug.Log("zzzz"); 
    }
    
}

'c# 강의 > 유니티' 카테고리의 다른 글

20200508 - 벡터1  (0) 2020.05.08
20200508 - 복습  (0) 2020.05.08
20200507 - 애니메이션2  (0) 2020.05.08
20200507 - 애니메이션  (0) 2020.05.07
20200507 - 유니티(MonoBehaviour), 라이프사이클  (0) 2020.05.07

 

> 타격 프레임 code

더보기
public GameObject model;
public Button btn;
public int attackFrame;

private Animation anim;
private AnimationState state;

public int attackFrame;
private float totalFrames;
private float attackTime;
private float elapsedTimeAttack;  //타격 시간 
private float elapsedTimeAttackComplete;  //공격 애니메이션 종료 시간 
private bool isAttackAnimationPlaying;  //공격애니메이션 실행중인지 
private bool isAttack;  //공격을 했는지 

void Start()
{
    this.anim = this.model.GetComponent<Animation>();
    this.state = this.anim["attack_sword_01"];
    this.totalFrames = state.length * state.clip.frameRate;
    // fps의 뜻 (60fps, 30fps, 29.97fps, 24fps) 
    // 영상에서 매 초당 보여지는 이미지 장면의 수, 즉 프레임이 재생되는 속도

    // 22 : 8 = 0.733 : x 
    // 8 * 0.733 / 22 = x 
    this.attackTime =
        this.attackFrame * state.length / this.totalFrames;

}

void Update()
{
    //공격 애니메이션 실행 중이라면 
    if (this.isAttackAnimationPlaying)
    {
        //경과시간 누적 
        this.elapsedTimeAttack += Time.deltaTime;
        if (this.elapsedTimeAttack >= this.attackTime)
        {
            if (!this.isAttack)
            {
                //공격을 했는지 
                Debug.Log("타격!");
                this.isAttack = true;
            }
        }

        this.elapsedTimeAttackComplete += Time.deltaTime;

        if (this.elapsedTimeAttackComplete >= this.state.length)
        {
            //공격 애니메이션 종료 
            this.elapsedTimeAttack = 0;
            this.elapsedTimeAttackComplete = 0;
            this.isAttack = false;
            this.isAttackAnimationPlaying = false;
            this.anim.Play("idle@loop");
            Debug.Log("공격 애니메이션 종료");
        }
    }
}

 

> 이동

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
 
public class App : MonoBehaviour
{
    public Animation anim;
    public Button btnMoveForward;
    public Button btnMoveBack;
    public Button btnMoveLeft;
    public Button btnMoveRight;
    public Button btnStop;
    public float speed;
 
    private bool isMove;
    private Vector3 dir;
 
 
    void Start()
    {
        this.btnMoveForward.onClick.AddListener(() => {
            this.Move(Vector3.forward);
        });
 
        this.btnMoveBack.onClick.AddListener(() => {
            this.Move(Vector3.back);
        });
 
        this.btnMoveRight.onClick.AddListener(() => {
            this.Move(Vector3.right);
        });
 
        this.btnMoveLeft.onClick.AddListener(() => {
            this.Move(Vector3.left);
        });
 
 
        this.btnStop.onClick.AddListener(() => {
            Debug.Log("Stop");
            this.Stop();
        });
    }
 
    private void Move(Vector3 dir) {
        this.dir = dir;
        this.anim.Play("run@loop");
        this.isMove = true;
    }
 
    private void Stop() {
        this.isMove = false;
        this.anim.Play("idle@loop");
    }
 
    private void Update()
    {
        if (this.isMove) {
            this.anim.gameObject.transform.Translate(this.dir * this.speed * Time.deltaTime);
        }
    }
}

* 방향, 속도, 시간

 

> 오브젝트와의 거리 계산

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
 
public class App : MonoBehaviour
{
    public GameObject model;
    public GameObject target;
    public Button btnMove;
 
    private bool isMove;
    private Animation anim;
 
    void Start()
    {
        this.anim = this.model.GetComponent<Animation>();
 
        this.btnMove.onClick.AddListener(() => {
            this.Move();
        });
    }
 
    private void Move() {
        this.isMove = true;
        this.anim.Play("run@loop");
    }
 
    private void Stop() {
        this.isMove = false;
        this.anim.Play("idle@loop");
    }
 
    private void Update()
    {
        if (this.isMove) {
            //float
            var distance = Vector3.Distance(model.transform.position,
                target.transform.position);
 
            //move
            var speed = 1.2f;
            var dir = Vector3.forward;
            this.model.transform.Translate(speed * dir * Time.deltaTime);
 
            Debug.Log(distance);
 
            if (distance <= 0.03f)
            {
                this.model.transform.position = this.target.transform.position;
                this.Stop();
            }
        }
 
    }
}

 

> 히트&다이(프레임계산 적용)

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
 
public class App : MonoBehaviour
{
    public GameObject model;
    public GameObject target;
    public Button btnMove;
    public float attackDely;
 
    private bool isMove;
    private bool isAttack;
    private Animation heroAnim;
    private Animation monsterAnim;
    private float elapsedTime;
    private int attackFrame;
    private float totalFrames;
    private float attackTime;
    private int attackCount;    //공격 몇번 했는지 카운트 
    private bool isImpact;   //타격 했나?
    private AnimationState attackAnimState;
    private bool isMonsterHit;
    private float monsterHitElapsedTime;
    private float monsterAttackDamageAnimLength;
    private float attackDelayElapsedTime;
    private bool isContinousAttack;
    private bool isMonsterDie;
    private float monsterDieElapsedTime;
    private float monsterDieAnimationLength;
 
 
    void Start()
    {
        //init
        this.attackFrame = 8;
        this.heroAnim = this.model.GetComponent<Animation>();
        this.monsterAnim = this.target.GetComponent<Animation>();
        this.monsterAttackDamageAnimLength = this.monsterAnim["Anim_Damage"].length;
        this.monsterDieAnimationLength = this.monsterAnim["Anim_Death"].length;
 
        this.attackAnimState = this.heroAnim["attack_sword_01"];
        this.totalFrames = this.attackAnimState.length * this.attackAnimState.clip.frameRate;
        //22 : 8 = 0.733 : x 
        // x = 8 * 0.733 / 22
        this.attackTime = this.attackFrame * this.attackAnimState.length / this.totalFrames;
 
        this.btnMove.onClick.AddListener(() => {
            this.Move();
        });
    }
 
    private void Move() {
        this.isMove = true;
        this.heroAnim.Play("run@loop");
    }
 
    private void Stop() {
        this.isMove = false;
        this.Idle();
    }
 
    private void Idle() {
        this.heroAnim.Play("idle@loop");
    }
 
    private void Attack() {
        this.isAttack = true;
        this.heroAnim.Play("attack_sword_01");
    }
 
    private void MonsterHit() {
        this.isMonsterHit = true;
        this.monsterAnim.Play("Anim_Damage");
    }
 
    private void MonsterIdle() {
        this.isMonsterHit = false;
        this.monsterAnim.Play("Anim_Idle");
    }
 
    private void Update()
    {
        if (this.isMove) {
            //float
            var distance = Vector3.Distance(model.transform.position,
                target.transform.position);
 
            //move
            var speed = 1.2f;
            var dir = Vector3.forward;
            this.model.transform.Translate(speed * dir * Time.deltaTime);
 
            if (distance <= 0.5f)
            {
                this.Stop();
                this.Attack();
            }
        }
 
        if (this.isAttack) {
 
            this.elapsedTime += Time.deltaTime;
            if (this.elapsedTime >= attackTime)
            {
                if (this.isImpact == false) {
                    isImpact = true;
                    this.MonsterHit();
                }
            }
 
            if (this.elapsedTime >= this.attackAnimState.length) {
                //공격 완료 
                this.isAttack = false;
                this.isImpact = false;
                this.elapsedTime = 0;
                this.attackCount++;
 
                Debug.Log(this.attackCount);
                
                this.Idle();
 
                if (this.attackCount >= 3) {
                    this.isContinousAttack = false;
                    this.MonsterDie();
                }
 
                
            }
        }
 
 
        if (this.isMonsterHit) {
            this.monsterHitElapsedTime += Time.deltaTime;
            if (this.monsterHitElapsedTime >= monsterAttackDamageAnimLength)
            {
                this.monsterHitElapsedTime = 0;
                this.MonsterIdle();
                this.isContinousAttack = true;
            }
        }
 
        if (this.isContinousAttack) {
            this.attackDelayElapsedTime += Time.deltaTime;
            if (this.attackDelayElapsedTime >= this.attackDely) {
                this.attackDelayElapsedTime = 0;
                this.isContinousAttack = false;
                this.Attack();
            }
        }
 
        if (this.isMonsterDie) {
            this.monsterDieElapsedTime += Time.deltaTime;
            if (this.monsterDieElapsedTime >= this.monsterDieAnimationLength) {
                UnityEngine.Object.Destroy(this.target.gameObject);
            }
        }
 
    }
 
    private void MonsterDie()
    {
        this.monsterAnim.Play("Anim_Death");
        this.isMonsterDie = true;
    }
}
 

 

using UnityEngine.UI; // 버튼 사용하려면  2019.3.7

public class App : MonoBehaviour
{
    public GameObject model; //구멍을 뚫어
    public Button btn; // 버튼 인스턴스

 

> 버튼 클릭시 리스너

 this.btn.onClick.AddListener(메소드());
        this.btn.onClick.AddListener(() =>
        {
            Debug.Log("test1");
        });

> 프레임 시간

timer += Time.deltaTime;

 

> 애니메이션 컴포넌트 먼저가져와야함(model은 GameObaect)

  var anim = this.model.GetComponent<Animation>(); // 애니 컴포넌트 가져와

 

> 애니메이션

var state = anim["attack_sword_01"]; // 애니메이션 컴포넌트 활용

 anim.Play("attack_sword_01"); //애니메이션 실행

 


 

MonoBehaviour

Awake - Start - Update

 

> Awake

- 인스턴스가 메모리에 오라가고,  로딩 될 때, 호출

- 마치 생성자와 같다.
- 미리 정의되어 있다. 

- 종료 될 때까지 한 번만 실행된다. 

 

 

> start (스크립트가 실행 될 때 한번)

Start는 Update메소드가 처음 호출되기 바로 전에 호출됩니다.

 

 

> Update

- Update는 MonoBehaviour가 활성화 되어 있는 경우에, 매 프레임마다 호출됩니다.

- Update는 게임 동작을 수행하기위해 가장 흔하게 사용되는 기능입니다.

지난 Update호출로부터의 경과시간을 받아오고 싶은 경우에, Time.deltaTime을 사용합니다. Behaviour가 활성화 되어있는 경우에만 호출됩니다. 사용자 컴포넌트의 기능을 제공하기 위해 함수를 오버라이드(override)해서 사용할 수 있습니다.

 

 


> 라이프사이클

 

 

> 정리 코드 - 참고

더보기
public class App : MonoBehaviour
{
    //인스턴스가 로딩될때 한번만 호출됨 
    //게임오브젝트가 비활성화 일경우 호출 안됨 
    //게임오브젝트가 활성화 이고 컴포넌트가 비활성화 일경우 호출됨 
    private void Awake()
    {
        Debug.Log("App::Awake");
    }
 
    //게임오브젝트가 활성화 되었을경우 호출됨 
    //게임오브젝트가 비활성화 일경우 호출 안됨 
    //게임오브젝트가 활성화 이고 컴포넌트가 비활성화 일경우도 호출 안됨 
    private void OnEnable()
    {
        Debug.Log("App::OnEnable");
    }
 
    //오브젝트가 활성화 상태일경우 업데이트 함수 호출전에 한번만 호출됨 
    void Start()
    {
        Debug.Log("App::Start");
    }
 
    //오브젝트가 활성화 상태일경우 매프레임마다 호출됨 
    void Update()
    {
        Debug.Log("App::Update");
    }
 
    //오브젝트가 비활성화 일경우 호출됨 
    //인스턴스화 될때 게임오브젝트가 비활성화, 컴포넌트가 비활성일경우 호출안됨 
    //인스턴스화 되고 오브젝트또는 컴포넌트가 활성화에서 비활성화 되었을경우 호출됨 
    private void OnDisable()
    {
        Debug.Log("App::OnDisable");
    }
 
    //Object.Destroy 
    //씬 종료
    //오브젝트 존재의 마지막 프레임에 대해 모든 프레임 업데이트를 마친 후 이 함수가 호출됩니다. 
 
    //오브젝트 활성화, 컴포넌트 활성화 : 
    //Awake - OnEnable - Staret - Update - OnDisable - OnDestory 
 
    //오브젝트 활성화, 컴포넌트 비활성화 : 
    //Awake - OnDestory 
 
    //오브젝트 비활성화, 컴포넌트 활성화 : X 
 
 
    private void OnDestroy()
    {
        Debug.Log("App::OnDestroy");
    }
}

'c# 강의 > 유니티' 카테고리의 다른 글

20200507 - 오브젝트 생성 및 부모설정(Instantiate)  (0) 2020.05.08
20200507 - 애니메이션2  (0) 2020.05.08
20200507 - 애니메이션  (0) 2020.05.07
20200506 - 설정2  (0) 2020.05.06
20200506 - 설정1  (0) 2020.05.06

> 구조

- 좌표를 가지는 구조체 백터

- 게임 오브젝트가 구조체 멤버로 가짐

- 캐릭터와 타일은 게임오브젝트를 상속받고 캐릭터는 좌표값을 받아 위치 값을 설정 할 수 있다.

 


내용 추가

 


> 맵 좌표

 

 

> 튜플 (인덱스 <=> 포지션)

 

> 매개변수 한정자

더보기

 

해설 코드

int initializeInMethod;
OutArgExample(out initializeInMethod);
Console.WriteLine(initializeInMethod);     // value is now 44

void OutArgExample(out int number)
{
    number = 44;
}

※ out 키워드를 사용하면 참조를 통해 인수를 전달할 수 있습니다.

 

 

 

 

 

 

 

 

 

그리드  - 1유닛 작은 상작

 

 

 

 

더보기

 

 

 

 

 

 

> 후기

- winfrom 을 스터디 하고 싶었던 차에 2048을 winfrom으로 만들어보기로 했다.

- 역시 마쏘는 어마어마한 형들이다.  사용하기 쉽게? 만든느낌을 받으며 적용시킬수 있었다.

- 아카데미시절 눈물나게했던,  JAVA Swing.. 요놈으로 게임만들어본 경험이 큰도움이 됬다.

- 아무래도 수학적인 머리가 부족해서, 2차원배열 정렬하는데, 애좀 먹었다. ㄷㄷ 

- 특히 좌우 정렬 공간지각능력 부족인가 ㅜㅜ

- 자바스크립트의 forEach 관련 메소드들이 있엇다면 좀더 쉽게 했을텐데, 머리가 나쁘면 몸이 고생하는것 을 다시 느꼈다.

- 스코어 누적은 잘되는지, 2048만들어서 클리어 해봐야하는데 검증 할 기력이 없다. ㄷㄷ

- 개똥같읕 코드로 반복문과 분기문이 아주 지저분한데, 가볍게 잘돌아가는것 같아 신기했다. 

 

> 실행파일

lioncho_2048.exe
0.15MB

 

> 게임 이미지

더보기
시작 화면

 

스코어 및 연산

 

칸 다차면 종료

 

 

> code

더보기
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _20200502
{
    public partial class form : Form
    {
        Random random;

        int[,] array;
        bool start = true;
        int totalScore;

        int x;
        int y;
        int randomNum1;
        int randomNum2;

        Control newNumTemp;


        public form()
        {
            InitializeComponent();

            this.Init();
            this.StartGame();

            this.TableInit();

            this.IsNumberBackgroundColor();

        }

        public void Init()
        {
            this.random = new Random();
            this.newNumTemp = new Control();
        }

        // up 버튼 입력시 해당 방향으로 재정렬
        public void UpDataSort()
        {
            int[,] newArr = new int[4, 4];

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (this.array[i, j] > 0)
                    {
                        for (int k = 0; k < newArr.GetLength(1); k++)
                        {
                            if (newArr[k, j] == 0)
                            {
                                if (k != 0)
                                {
                                    if (newArr[k - 1, j] == this.array[i, j])
                                    {
                                        newArr[k - 1, j] = this.array[i, j] * 2;
                                        this.totalScore += newArr[k - 1, j];
                                        break;
                                    }
                                }
                                newArr[k, j] = this.array[i, j];
                                break;
                            }
                        }
                    }
                }
            }
            this.array = newArr;
        }

        //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

        // down 버튼 입력시 해당 방향으로 재정렬
        public void DownDataSort()
        {
            int[,] newArr = new int[4, 4];


            for (int i = 3; i >= 0; i--)
            {
                for (int j = 3; j >= 0; j--)
                {
                    if (this.array[i, j] > 0)
                    {
                        for (int k = 3; k >= 0; k--)
                        {
                            if (newArr[k, j] == 0)
                            {
                                if (k != 3)
                                {
                                    if (newArr[k + 1, j] == this.array[i, j])
                                    {
                                        newArr[k + 1, j] = this.array[i, j] * 2;
                                        this.totalScore += newArr[k + 1, j];
                                        break;
                                    }
                                }
                                newArr[k, j] = this.array[i, j];
                                break;
                            }
                        }
                    }
                }
            }
            this.array = newArr;
        }

        //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

        // left 버튼 입력시 해당 방향으로 재정렬
        public void LeftDataSort()
        {
            int[,] newArr = new int[4, 4];

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    // 값있을 경우
                    if (this.array[j, i] > 0)
                    {

                        // 행 
                        for (int k = 0; k < newArr.GetLength(1); k++)
                        {

                            if (newArr[j, k] == 0)
                            {
                                if (k != 0)
                                {
                                    if (newArr[j, k - 1] == this.array[j, i])
                                    {
                                        newArr[j, k - 1] = this.array[j, i] * 2;
                                        this.totalScore += newArr[j, k - 1];
                                        break;
                                    }
                                }
                                newArr[j, k] = this.array[j, i];
                                break;
                            }
                        }
                    }
                }
            }
            this.array = newArr;
        }

        //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

        // right 버튼 입력시 해당 방향으로 재정렬
        public void RightDataSort()
        {
            int[,] newArr = new int[4, 4];

            for (int i = 3; i >= 0; i--)
            {
                for (int j = 0; j < 4; j++)
                {
                    // 값있을 경우
                    if (this.array[j, i] > 0)
                    {
                        // 행 
                        for (int k = 3; k >= 0; k--)
                        {

                            if (newArr[j, k] == 0)
                            {
                                if (k != 3)
                                {
                                    if (newArr[j, k + 1] == this.array[j, i])
                                    {
                                        newArr[j, k + 1] = this.array[j, i] * 2;
                                        this.totalScore += newArr[j, k + 1];
                                        break;
                                    }
                                }
                                newArr[j, k] = this.array[j, i];
                                break;
                            }
                        }
                    }
                }
            }
            this.array = newArr;
        }

        //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

        // 뷰테이블에 있는 데이터, 로직 배열과 동기화
        public void TableInit()
        {
            this.array = new int[4, 4];

            foreach (Control ctrl in tableLayoutPanel1.Controls)
            {
                if (ctrl is Label)
                {
                    var row = tableLayoutPanel1.GetRow(ctrl);
                    var col = tableLayoutPanel1.GetColumn(ctrl);

                    this.array[row, col] = 0;

                    // 값 있는 경우
                    if (ctrl.Text.Length > 0)
                    {
                        int myNum = int.Parse(ctrl.Text);
                        this.array[row, col] = myNum;
                    }
                }
            }
            this.IsNumberBackgroundColor();
        }


        // 뷰 라벨 테이블 비우고 데이터 배열 초기화
        public void NewTable()
        {
            foreach (Control ctrl in tableLayoutPanel1.Controls)
            {
                if (ctrl is Label)
                {
                    ctrl.Text = "";
                }
            }
            this.array = new int[4, 4];
        }

        // 게임 스타트시 초기값 발생
        public void StartGame()
        {
            this.RandomXY();
            this.RandomNum();
            tableLayoutPanel1.GetControlFromPosition(y, x).Text = randomNum2.ToString();

            this.RandomXY();
            this.RandomNum();
            tableLayoutPanel1.GetControlFromPosition(y, x).Text = randomNum1.ToString();
        }

        // 처음에 주어지는 숫자 위치 정하기
        public void RandomXY()
        {
            // 낮은 확률로 처음 주어지는 숫자 위치 중첩 방지
            while (true)
            {
                int tempX = random.Next(0, 4);
                int tempY = random.Next(0, 4);

                if (this.x != tempX && this.y != tempY)
                {
                    this.x = tempX;
                    this.y = tempY;
                    break;
                }
            }
        }


        // 처음에 주어지는 숫자 2,4 난수 발생 로직
        public void RandomNum()
        {
            while (true)
            {
                int tempNum1 = random.Next(2, 5);
                int tempNum2 = random.Next(2, 5);

                bool cheeck1 = false;
                bool cheeck2 = false;

                // 처음만 두개의 숫자 발생
                if (this.start)
                {
                    if (tempNum2 == 2 || tempNum2 == 4)
                    {
                        this.randomNum1 = tempNum2;
                        cheeck1 = true;
                    }
                }

                if (tempNum1 == 2 || tempNum1 == 4)
                {
                    this.randomNum2 = tempNum1;
                    cheeck2 = true;
                }

                if (cheeck1 && cheeck2)
                {
                    break;
                }
            }

        }

        // 턴 이후 지급되는 랜덤 숫자 생성
        public void CreateNewNum()
        {
            while (true)
            {
                this.RandomXY();
                if (this.array[this.x, this.y] == 0)
                {
                    break;
                }
            }
            this.newNumTemp.ForeColor = Color.Black;
            this.RandomNum();
            this.array[this.x, this.y] = this.randomNum2;
            tableLayoutPanel1.GetControlFromPosition(y, x).Text = this.randomNum2.ToString();

            tableLayoutPanel1.GetControlFromPosition(y, x).ForeColor = Color.IndianRed;

            this.newNumTemp = tableLayoutPanel1.GetControlFromPosition(y, x);

            logBox.Items.Add($"신규랜덤난수:[{x},{y}]:{this.randomNum2}");
        }



        // new버튼 이벤트 발생시 초기화
        public void GameReset()
        {
            this.array = new int[4, 4];
            this.start = true;
            this.totalScore = 0;


            this.ViewReset();
            this.StartGame();
            this.TableInit();
            this.SetScoreView();
        }

        // 전체 테이블 라벨 지우고, log창 지우기
        public void ViewReset()
        {
            foreach (Control ctrl in tableLayoutPanel1.Controls)
            {
                if (ctrl is Label)
                {
                    ctrl.Text = "";
                }
            }
            logBox.Items.Clear();
        }

        // sort된 배열, 뷰 테이블라벨에 재적용
        public void UpdateView()
        {
            foreach (Control ctrl in tableLayoutPanel1.Controls)
            {
                if (ctrl is Label)
                {
                    var row = tableLayoutPanel1.GetRow(ctrl);
                    var col = tableLayoutPanel1.GetColumn(ctrl);
                    ctrl.Text = "";

                    // 값 있는 경우
                    if (this.array[row, col] > 0)
                    {
                        ctrl.Text = this.array[row, col].ToString();
                    }
                }
            }
        }

        // 빈배열 있는지 체크
        public bool EndGameCheck()
        {
            foreach (var item in this.array)
            {
                if (item == 0)
                {
                    return true;
                }
            }
            return false;
        }

        // 게임 클리어 체크
        public bool ClearGameCheck()
        {
            foreach (var item in this.array)
            {
                if (item.Equals(2048))
                {
                    return true;
                }
            }
            return false;
        }

        // 연산값에 대한 뷰 컬러처리
        public void IsNumberBackgroundColor()
        {
            int checkNum = 0;
            foreach (Control ctrl in tableLayoutPanel1.Controls)
            {
                if (ctrl is Label)
                {
                    ctrl.BackColor = Color.Gainsboro;

                    if (ctrl.Text != "")
                    {
                        checkNum = int.Parse(ctrl.Text);

                        if (checkNum == 8)
                        {
                            ctrl.ForeColor = Color.WhiteSmoke;
                            ctrl.BackColor = Color.LightSalmon;
                        }
                        else if (checkNum == 16)
                        {
                            ctrl.ForeColor = Color.WhiteSmoke;
                            ctrl.BackColor = Color.LightCoral;
                        }
                        else if (checkNum == 32)
                        {
                            ctrl.ForeColor = Color.WhiteSmoke;
                            ctrl.BackColor = Color.Coral;
                        }
                        else if (checkNum >= 64)
                        {
                            ctrl.ForeColor = Color.WhiteSmoke;
                            ctrl.BackColor = Color.Tomato;
                        }
                        else
                        {
                            ctrl.BackColor = Color.Silver;
                            ctrl.ForeColor = Color.Black;
                        }
                    }

                    if (ctrl.Text == "")
                    {
                        ctrl.BackColor = Color.Silver;
                        ctrl.ForeColor = Color.Black;
                    }
                }
            }
        }

        // 스코어 뷰에 누계 적용
        public void SetScoreView()
        {
            scoreLabel.Text = this.totalScore.ToString();
        }

        // 개발시 배열 확인용 매소드
        public void ArrayPrint()
        {
            for (int i = 0; i < this.array.GetLength(0); i++)
            {
                for (int j = 0; j < this.array.GetLength(1); j++)
                {
                    Console.Write("[{0}, {1}]:{2} ㅣ", i, j, this.array[i, j]);
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }

        //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 방향킼 버튼 이벤트 리스너 ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
        private void UpBtn_Click(object sender, EventArgs e)
        {
            if (ClearGameCheck()) { MessageBox.Show("게임 클리어!!"); }
            if (EndGameCheck())
            {
                this.UpDataSort();
                this.UpdateView();
                this.CreateNewNum();
                this.IsNumberBackgroundColor();
                this.SetScoreView();
            }
            else
            {
                MessageBox.Show("게임 종료");
            }
        }

        private void DownBtn_Click(object sender, EventArgs e)
        {
            if (ClearGameCheck()) { MessageBox.Show("게임 클리어!!"); }
            if (EndGameCheck())
            {
                this.DownDataSort();
                this.UpdateView();
                this.CreateNewNum();
                this.IsNumberBackgroundColor();
                this.SetScoreView();
            }
            else
            {
                MessageBox.Show("게임 종료");
            }
        }

        private void LeftBtn_Click(object sender, EventArgs e)
        {
            if (ClearGameCheck()) { MessageBox.Show("게임 클리어!!"); }
            if (EndGameCheck())
            {
                this.LeftDataSort();
                this.UpdateView();
                this.CreateNewNum();
                this.IsNumberBackgroundColor();
                this.SetScoreView();
            }
            else
            {
                MessageBox.Show("게임 종료");
            }
        }

        private void RightBtn_Click(object sender, EventArgs e)
        {
            if (ClearGameCheck()) { MessageBox.Show("게임 클리어!!"); }
            if (EndGameCheck())
            {
                this.RightDataSort();
                this.UpdateView();
                this.CreateNewNum();
                this.IsNumberBackgroundColor();
                this.SetScoreView();
            }
            else
            {
                MessageBox.Show("게임 종료");
            }
        }

        // ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ new 버튼  ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

        // newGame 버튼 클릭시 비우고 난수 발생하기
        private void button1_Click(object sender, EventArgs e)
        {
            this.GameReset();
        }

        //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ ?? ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
        private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
        {

        }

    }
}

프로퍼티에 관리 파일이 있다.

 

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _20200502
{
    public partial class form : Form
    {
        public form()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Version version = Assembly.GetEntryAssembly().GetName().Version;
            this.Text = "Title: "+ version;

        }
    }
}

 위 프로퍼티의 어셈블리 버전 불러와 타이틀에 적용시킬수 있다.

 

 


> 예제 1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _20200502
{
    public partial class form : Form
    {
        public form()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string title = "lion";
            DateTime buildDate = Convert.ToDateTime("2020-04-30");
            Version version = Assembly.GetEntryAssembly().GetName().Version;
   
            this.Text = string.Format("{0} Ver {1}.{2} / Build Time ({3})",
                title,
                version.Major, version.Minor,
                buildDate.ToString("yyyy-MM-dd")
                ); 
        }
    }
}

 

'■ c# > WinForm' 카테고리의 다른 글

[winform] - ICON 프로그래실행 아이콘 / 폼 아이콘  (0) 2020.05.02

> 프로그램 실행 아이콘 설정

솔루션, 우클릭 속성

 

 


 

> 폼 상단 아이콘 설정

폼 선택

 

'■ c# > WinForm' 카테고리의 다른 글

[winform] - 타이틀 버전 관리  (0) 2020.05.02

연속 출석 했을때 받는 보상을, 누적하면 추가로 주는 보너스 보상으로 생각했었다.

가장 최근에 했던 검은사막m 했던 기억이 나를 지배했다. ㄷㄷ 좀더 귀를 열고 강사님 말씀에 집중해야 할 듯

최근에 과제를 하면서, 확실이 게임 개발은 각 기능의 알고리즘을 이해하는것이 특히나 중요한 것 같다.  

 

 

> 결과

더보기
실행시킨 일자부터 28후 이벤트 종료 / 출석 / 누적 카운트 / 출석or다음날접속 시 today +1

 

2번 다음날 접속시, 하루 소요
같은 아이템 보상시 수량만 추가

 

누적 연속 출석시 추가 보상 

 

하루 소요시, 연속보상 누적 카운트는 초기화

 

만약 5일차 연속보상 수령했는데, 초기화 후 다시 누적해도 해당 연속 보상은 받을수 없다.

 

 

 

> 코드

1. Data.cs

더보기
    class EverydayData
    {
        public int id;
        public int everyday_date;
        public int everyday_item;
        public int everyday_item_amount;
    }
    class ItemData
    {
        public int id;
        public string item_name;
        public string icon_item_image;
        public int amount;
    }

 

 

2. DataManager.cs

더보기
    class DataManager
    {
        private static DataManager singleTone;

        private Dictionary<int, ItemData> dicItemData;
        private Dictionary<int, EverydayData> dicEverydataData;

        private DataManager()
        {
            this.dicEverydataData = new Dictionary<int, EverydayData>();
            this.dicItemData = new Dictionary<int, ItemData>();
        }

        public bool LoadDatas()
        {
            bool reuslt = false;
            string path = "";
            string json = "";

            try
            {
                path = "./data/everyday_data.json";
                if (File.Exists(path))
                {
                    json = File.ReadAllText(path);
                    //   Console.WriteLine(json);
                    this.dicEverydataData = JsonConvert
                        .DeserializeObject<EverydayData[]>(json)
                        .ToDictionary(v => v.id, v => v);
                }

                path = "./data/item_data.json";
                if (File.Exists(path))
                {
                    json = File.ReadAllText(path);
                    this.dicItemData = JsonConvert
                           .DeserializeObject<ItemData[]>(json)
                           .ToDictionary(v => v.id, v => v);
                }
                reuslt = true;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
                throw;
            }
            return reuslt;
        }

        public static DataManager GetInstance()
        {
            if (DataManager.singleTone == null)
            {
                DataManager.singleTone = new DataManager();
                return DataManager.singleTone;
            }
            else
            {
                return DataManager.singleTone;
            }
        }

        public Dictionary<int, EverydayData> GetEverydataDatas()
        {
            return this.dicEverydataData;
        }

        public EverydayData GetEverydayData(int id)
        {
            return this.dicEverydataData[id];
        }

        public Dictionary<int, ItemData> GetItemDatas()
        {
            return this.dicItemData;
        }

        public ItemData GetItemData(int id)
        {
            return this.dicItemData[id];
        }
    }

 

 

3. App.cs

더보기
    class App
    {
        DataManager dm;
        UserInfo info;

        public static DateTime TODAY;
        DateTime endDay;


        public App()
        {
            this.Init();
            this.endDay = TODAY.AddDays(28);

            while (true)
            {
                this.Login();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.Write("* test 입력 (1번 출석 / 2번 다음날 접속): ");
                string input = Console.ReadLine();
                Console.WriteLine();
                if (TODAY > this.endDay)
                {
                    Console.WriteLine("!!!!! 출석 이벤트 종료 !!!!!");
                    return;
                }
                this.View(input);
                Console.WriteLine();
                TODAY = TODAY.AddDays(1);
                this.info.SaveUserInfoData();

            }
        }

        public void Init()
        {
            dm = DataManager.GetInstance();
            dm.LoadDatas();
            TODAY = DateTime.Now;
            this.info = new UserInfo();
        }

        public void GetItemPrint(ItemData item)
        {
            Console.WriteLine("ㅡㅡㅡㅡ 일간 출석 보상 ㅡㅡㅡㅡ");
            Console.WriteLine("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■");
            Console.WriteLine($"- {this.info.dayCount}일자 아이템 입니다. 아이템 우편으로 획득");
            Console.WriteLine($"{item.item_name}({item.amount})");
            Console.WriteLine("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■");
        }

        public void ChainDayPrint(int eventDay, ItemData chainItem, int amount)
        {
            Console.WriteLine("ㅡㅡㅡㅡ 연속 보상 ㅡㅡㅡㅡ");
            Console.WriteLine("□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□");
            Console.WriteLine($"- 누적{this.info.rewardedCount}일 입니다. 아이템 추가증정");
            Console.WriteLine($"{chainItem.item_name}({amount})");
            Console.WriteLine("□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□");
            this.info.RewardedItem(this.info.userId, chainItem);
        }


        public void View(string check)
        {
            var data = dm.GetEverydataDatas();
            List<int> list = new List<int>(data.Keys);

            if (check != "1")
            {
                Console.WriteLine("ㅡㅡㅡ 하루소요 ㅡㅡㅡ");
                Console.WriteLine($"오늘날짜:[{TODAY.Month}월{TODAY.Day}일] / 이벤트 남은일자:[{(this.endDay - TODAY).Days}일]");
                return;
            }


            foreach (var key in list)
            {
                var item = dm.GetItemData(data[key].everyday_item);
                Console.Write($"[{data[key].everyday_date}일]{item.item_name}");
                Console.Write($"({data[key].everyday_item_amount})");
                Console.Write("   ");
                // 줄바꿈
                if (data[key].everyday_date % 7 == 0) { Console.WriteLine(); }
            }
            Console.WriteLine();

            Console.WriteLine($"[출석:{this.info.dayCount}]/[누적:{this.info.rewardedCount}일] / 오늘날짜:[{TODAY.Month}월{TODAY.Day}일] / 이벤트 남은일자:[{(this.endDay - TODAY).Days}일]");

            Console.WriteLine();

            //일일 보상 ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

            // 전체 일정에서 금일 보상에 따른 아이템 찾기
            var todayRewardItemData = data.FirstOrDefault(v => v.Value.everyday_date == this.info.dayCount).Value;

            // 금일 지급할 아이템 키
            int todayRewardItemKey = todayRewardItemData.everyday_item;

            // 금일 지급할 아이템 지급 수량
            int todayRewardItemAmount = todayRewardItemData.everyday_item_amount;

            // 찾은 키로 아이템 가져오기
            ItemData todayRewardItem = dm.GetItemData(todayRewardItemKey);
            todayRewardItem.amount = todayRewardItemAmount;

            this.ItemGet(todayRewardItem, todayRewardItemAmount);

            //연속 보상 ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
            var awChack = this.info.chainDayList.Contains(this.info.rewardedCount);
            if (awChack)
            {
                switch (this.info.rewardedCount)
                {
                    case 5:
                        this.info.chainDayList.Remove(this.info.rewardedCount);
                        this.ChainDayPrint(5, dm.GetItemData(1008), 1);
                        break;
                    case 10:
                        this.info.chainDayList.Remove(this.info.rewardedCount);
                        this.ChainDayPrint(10, dm.GetItemData(1004), 200);
                        break;
                    case 20:
                        this.info.chainDayList.Remove(this.info.rewardedCount);
                        this.ChainDayPrint(20, dm.GetItemData(1004), 500);
                        break;
                    default:
                        break;
                }
            }
        }

        public void ItemGet(ItemData rewardedItem, int amount)
        {
            // 일일 보상 획득
            this.GetItemPrint(rewardedItem);
            bool reuslt = this.info.RewardedItem(this.info.userId, rewardedItem);
        }

        public void Login()
        {
            this.info.LoadUserInfoData();
        }
    }

 

4. UserInfo.cs

더보기
    class UserInfo
    {
        public string userId;
        public string rewardedDate;

        public int dayCount;
        public int rewardedCount;

        public List<int> chainDayList;

        public Dictionary<int, ItemData> dicRewardedItems;

        public UserInfo()
        {
            this.dicRewardedItems = new Dictionary<int, ItemData>();
            
        }

        public UserInfo(string userId, string rewardedDate, Dictionary<int, ItemData> dicRewardedItems)
        {
            this.userId = userId;
            this.rewardedDate = rewardedDate;
            this.dicRewardedItems = dicRewardedItems;
        }

        public bool RewardedItem(string userid, ItemData rewardedItem)
        {
            this.userId = userid;
            this.rewardedDate = App.TODAY.ToString("yyyy-MM-dd HH:mm:s"); ;
            // 같은 아이템의경우 수량만 추가
            if (!this.dicRewardedItems.ContainsKey(rewardedItem.id))
            {
                this.dicRewardedItems.Add(rewardedItem.id, rewardedItem);
            }
            else
            {
                this.dicRewardedItems[rewardedItem.id].amount += rewardedItem.amount;
                Console.WriteLine("{0}(소지수량:{1}) + {2}획득",
                    this.dicRewardedItems[rewardedItem.id].item_name,
                    this.dicRewardedItems[rewardedItem.id].amount,
                    rewardedItem.amount
                    );
                Console.WriteLine();
            }
            return this.SaveUserInfoData();
        }

        public bool SaveUserInfoData()
        {
            bool result = false;
            var json = JsonConvert.SerializeObject(this);

            try
            {
                File.WriteAllText("./info/userInfo.json", json);

                result = true;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
                throw;
            }
            return result;
        }

        public void LoadUserInfoData()
        {
            DirectoryInfo folder = new DirectoryInfo("./info");
            if (!folder.Exists)
            {
                folder.Create();
            }

            var path = "./info/userInfo.json";
            try
            {
                if (File.Exists(path))
                {
                    var json = File.ReadAllText(path);
                    UserInfo readInfo = new UserInfo();
                    readInfo = JsonConvert.DeserializeObject<UserInfo>(json);
                    this.rewardedDate = readInfo.rewardedDate;
                    this.userId = readInfo.userId;
                    this.dicRewardedItems = readInfo.dicRewardedItems;
                    this.dayCount = readInfo.dayCount;
                    this.rewardedCount = readInfo.rewardedCount;
                    this.chainDayList = readInfo.chainDayList;
                }
                else
                {
                    Console.WriteLine("-신규유저입니다.");
                    Console.WriteLine("-ID는 lion 입니다.");
                    this.userId = "lion";
                    this.chainDayList = new List<int> { 5, 10, 15 };
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
                throw;
            }

            this.dayCount++;

            if (!this.RewardedCountCheck())
            {
                this.rewardedCount = 0;
            }
            this.rewardedCount++;
        }

        public bool RewardedCountCheck()
        {
            DateTime loadDate = Convert.ToDateTime(this.rewardedDate);
            if (this.rewardedDate != null)
            {
                if (App.TODAY.AddDays(-1).Day == loadDate.Day)
                {
                    return true;
                }
            }
            this.rewardedDate = App.TODAY.ToString("yyyy-MM-dd HH:mm:s");
            return false;
        }
    }

 

 

매일매일 페키지는 매일 자정 구매제한 초기화 개념

 


> App.cs

더보기
using Microsoft.SqlServer.Server;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace _20200428_1
{
    class App
    {
        Info info;
        public App()
        {
            DataManager dm = DataManager.GetInstance();

            this.Init();


            //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
            // test용 데이터 주입

            //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

            this.Load();
            this.info.myDia = 2000;
            this.info.myGold = 10000000;
            this.info.myLevel = 60;

            this.info.PrintInfo();
            this.PackageList();

            // 패키지 구매 테스트
            this.BuyPackage(10000);
            this.BuyPackage(10000);
            this.BuyPackage(10001);
            this.BuyPackage(10002);
            /*  
              this.BuyPackage(10000);
              this.BuyPackage(10001);
              this.BuyPackage(10002);
              this.BuyPackage(10003);
              this.BuyPackage(10004);
              this.BuyPackage(10005);
            */

            // this.everyDayPackageCount();
            this.info.Save();
        }

        public void Init()
        {
            DataManager dm = DataManager.GetInstance();

            info = new Info();

            Console.WriteLine();
            dm.LoadDatas();
        }

        // 판매 종료일 계산
        public void convertDate(string[] getDate)
        {
            DataManager dm = DataManager.GetInstance();

            System.DateTime endDate = new System.DateTime(int.Parse(getDate[0]), int.Parse(getDate[1]), int.Parse(getDate[2]));
            TimeSpan ddayDate = endDate - DateTime.Now;

            Console.Write($"-판매종료까지: ");
            if (ddayDate.Days > 0) { Console.Write($"{ddayDate.Days}일 "); };
            Console.WriteLine($"{ ddayDate.Hours }시간 { ddayDate.Minutes }분 { ddayDate.Seconds }초 남음");

        }

        //매일매일 초기화
        public void everyDayPackageCount()
        {
            Timer timaer = null;
            int FixHours = 12;
            var now = DateTime.Now;
            var scheduledTime = new DateTime(now.Year, now.Month, now.Day, FixHours, 0, 0);
            if (scheduledTime < now)
                scheduledTime = scheduledTime.AddDays(1);

            var timeout = scheduledTime - now;

            var timer = new Timer(timeout.TotalMilliseconds);
            timer.Enabled = true;
            timer.Elapsed += OnTimeEvent;

            Console.Write($"-판매종료까지: ");
            Console.WriteLine($"{ timeout.Hours }시 { timeout.Minutes }분 { timeout.Seconds }초 남음");

        }

        public void OnTimeEvent(Object source, System.Timers.ElapsedEventArgs e)
        {
            // 해당 이벤트 발생한다면 매일 자정 이후 매일매일 패키지 구매 카운트 초기화
            Console.WriteLine(e.SignalTime);
            this.info.dicBuyedPackageData[10005] = 0;
        }

        public void BuyPackage(int buyNum)
        {
            DataManager dm = DataManager.GetInstance();
            var data = dm.GetItemDatas(buyNum);

            Console.WriteLine();
            Console.WriteLine("ㅡㅡㅡㅡㅡㅡ 구매 ㅡㅡㅡㅡㅡㅡ");
            Console.WriteLine(data.item_name);
            this.info.BuyPackage(buyNum);
        }

        public void PackageList()
        {
            DataManager dm = DataManager.GetInstance();
            Dictionary<int, ItemData> data = dm.GetAllItemDatas();
            List<int> list = new List<int>(data.Keys);

            foreach (var key in list)
            {
                var cType = dm.GetCurrencyDataById(data[key].item_type);
                var desc = string.Format(data[key].level_limit_desc, data[key].level_limit);
                string money = String.Format("{0:#,###}", data[key].price);
                string mileage = String.Format("{0:#,###}", data[key].mileage);
                string[] testdate = new string[3];

                Console.WriteLine("ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ");
                Console.WriteLine(" *" + data[key].item_name);


                if (data[key].mileage > 0)
                {
                    Console.WriteLine($"-마일리지: {mileage}");
                }

                if (data[key].level_limit > 0) { Console.WriteLine("-" + desc); }
                Console.Write($"[{cType.name}]");
                Console.WriteLine($"-가격: {money}");
                if (data[key].everyday_package) { Console.WriteLine("★매일매일 패키지★"); }


                if (data[key].buy_end_date != "null")
                {
                    testdate = data[key].buy_end_date.Split('.');
                    this.convertDate(testdate);
                }

                if (key == 10005)
                {
                    this.everyDayPackageCount();
                }

                if (data[key].buy_limit > 0)
                {
                    Console.Write("-구매가능수량: (");
                    if (this.info.dicBuyedPackageData.ContainsKey(key))
                    {
                        this.info.count = this.info.dicBuyedPackageData[key];
                    }
                    Console.Write(this.info.count);
                    Console.WriteLine($"/{data[key].buy_limit})");
                }

            }//forEach end
        }

        public void MyinfoPrint()
        {
            Info myInfo = this.info.GetInfoData();
            Console.WriteLine("ㅡㅡㅡㅡㅡㅡㅡㅡㅡ 내 정보 ㅡㅡㅡㅡㅡㅡㅡㅡ");
            Console.WriteLine("[다이아:{0}][골드:{1}][마일리지:{2}][레벨:{3}]",
                myInfo.myDia, myInfo.myGold, myInfo.myLevel);
        }

        public void Load()
        {
            var path = "./info/info.json";
            if (File.Exists(path))
            {
                //파일 읽기 
                var json = File.ReadAllText("./info/info.json");

                //역직렬화 
                //이때 배열이 아니라는점 주의 
                this.info = JsonConvert.DeserializeObject<Info>(json);
                Console.WriteLine(this.info.myLevel);
            }
        }
    }
}

 

> DataManager.cs

더보기
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.InteropServices;
using Newtonsoft.Json;

namespace _20200428_1
{
    class DataManager
    {
        private static DataManager singleTone;

        private Dictionary<int, CurrencyData> dicCurrencyData;
        private Dictionary<int, ItemData> dicItemData;

        private DataManager()
        {
            this.dicCurrencyData = new Dictionary<int, CurrencyData>();
            this.dicItemData = new Dictionary<int, ItemData>();
        }

        public static DataManager GetInstance()
        {
            if (DataManager.singleTone == null)
            {
                DataManager.singleTone = new DataManager();
                return DataManager.singleTone;
            }
            else
            {
                return DataManager.singleTone;
            }
        }

        public void LoadDatas()
        {
            string json = "";
            string path = "";

            try
            {
                // 아이템 
                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/currency_data.json";
                if (File.Exists(path))
                {
                    json = File.ReadAllText(path);
                    this.dicCurrencyData = Newtonsoft.Json.JsonConvert.DeserializeObject<CurrencyData[]>(json).ToDictionary(x => x.id, x => x);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("* catch");
                Console.WriteLine(e.Message);
                throw;
            }

        } //Loaddata() end

        public CurrencyData GetCurrencyDataById(int id)
        {
            return dicCurrencyData[id];
        }

        public ItemData GetItemDatas(int id)
        {
            return this.dicItemData[id];
        }

        public Dictionary<int, ItemData> GetAllItemDatas()
        {
            return this.dicItemData;
        }

    }// class end
}

 

> Info.cs

더보기
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20200428_1
{
    class Info
    {
        public int myDia; // 소지 다이아 갯수
        public int myGold; // 소지 골드 갯수
        public int myLevel; // 현재 레벨
        public int myMileage; // 현재 누적 마일리지
        public int count;

        public Dictionary<int, int> dicBuyedPackageData; // 구매한 페키지 id, 수량 추가


        public Info()
        {
            this.dicBuyedPackageData = new Dictionary<int, int>();
        }

        public Info(int myDia, int myGold, int myLevel, int myMileage, Dictionary<int, int> dicBuyedPackageData)
        {
            this.myDia = myDia;
            this.myGold = myGold;
            this.myLevel = myLevel;
            this.myMileage = myMileage;
            this.dicBuyedPackageData = dicBuyedPackageData;
        }

        public void BuyPackage(int buyNum)
        {
            DataManager dm = DataManager.GetInstance();

            ItemData data = dm.GetItemDatas(buyNum);

            // 보유 재화 확인
            if (data.item_type == 100)
            {
                if (this.myDia >= data.price)
                {
                    // 구매가능 수량 확인
                    this.PackageBuyLimitCheck(data);
                }
                else
                {
                    Console.WriteLine("구매 다이아 부족");
                }
            }

            if (data.item_type == 101)
            {

                if (this.myGold >= data.price)
                {
                    // 구매가능 수량 확인
                    this.PackageBuyLimitCheck(data);
                }
                else
                {
                    Console.WriteLine("구매 골드 부족");
                }
            }

            this.PrintInfo();
        }

        // 수매수량, 레벨 체크
        public void PackageBuyLimitCheck(ItemData data)
        {
            if (this.dicBuyedPackageData.ContainsKey(data.id))
            {
                this.count = this.dicBuyedPackageData[data.id];
            }

            // 수량 체크
            if (data.buy_limit != 0 && data.buy_limit <= this.count) { Console.WriteLine("더이상 구매불가"); return; }

            // 레벨 체크
            if (data.level_limit != 0 && data.level_limit > this.myLevel) { Console.WriteLine("레벨부족으로 구매불가"); return; }

            if (data.item_type == 100)
            {
                Console.WriteLine("-다이아");
                this.count++;
                this.myDia -= data.price;
                this.myMileage += data.mileage;
                this.dicBuyedPackageData[data.id] = this.count;
            }

            if (data.item_type == 101)
            {
                Console.WriteLine("-골드");
                this.count++;
                this.myGold -= data.price;
                this.myMileage += data.mileage;
                this.dicBuyedPackageData[data.id] = this.count;
            }
        }

        public void PrintInfo()
        {
            DataManager dm = DataManager.GetInstance();

            Console.WriteLine($"-다이아:{this.myDia} -골드:{this.myGold} -레벨:{this.myLevel} -마일리지:{this.myMileage}");

            Console.WriteLine("ㅡㅡㅡㅡㅡ 구매 이력 ㅡㅡㅡㅡ");

            if (this.dicBuyedPackageData.Count > 0)
            {
                foreach (var item in this.dicBuyedPackageData)
                {
                    Console.WriteLine($"{item.Key } {item.Value}");
                }
            }
        }

        public void Save()
        {
            try
            {
                var json = JsonConvert.SerializeObject(this);
                File.WriteAllText("./info/info.json", json);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                throw;
            }
            Console.WriteLine("데이터 저장");
        }

        public Info GetInfoData()
        {
            return this;
        }
    }
}

 

> data파일들

더보기
namespace _20200428_1
{
    class ItemData
    {
        public int id;
        public int item_type;
        public string item_name;
        public int mileage;
        public int price;
        public int level_limit;
        public string level_limit_desc;
        public int buy_limit;
        public string buy_start_date;
        public string buy_end_date;
        public bool everyday_package;
    }
}
namespace _20200428_1
{
    class CurrencyData
    {
        public int id;
        public string name;
        public int currency_type;
        public string icon_currency;
    }
}

 

'c# 강의 > 과제' 카테고리의 다른 글

20200505 - winForm + 2048 게임 만들기  (0) 2020.05.04
20200429 - 일일보상 + 연속보상 + Date연산  (0) 2020.05.01
20200427 - 싱글톤  (0) 2020.04.28
20200421 - File 읽기 (JSON)  (0) 2020.04.22
20200420 - List 과제  (0) 2020.04.20

1. Year 활용

 System.DateTime endDate = new System.DateTime(2020, 4, 30);
 //endDate 원하는 년,월,일 생성
 	TimeSpan ddayDate = endDate - DateTime.Now;
 // 현재데이터와 연산하여 TimeSpan에 남은 day를 알 수 있다.
 
 /*
   ddayDate.Days 일
   ddayDate.Hours 시간 
   ddayDate.Minutes 분  
   ddayDate.Seconds 초 남음
 */

2. 문자열 -> DateTime

-  년,월,일 구분값은 [스페이스값],[/],[-] 으로만 구분가능하다. 

public void ToDateTimeTest1()
{
    DateTime dti01 = Convert.ToDateTime("2015 11 13");      //변환 가능 (2015년 11월 13일 오후 12:00:00)
    DateTime dti02 = Convert.ToDateTime("2015-11-13");      //변환 가능 (2015년 11월 13일 오후 12:00:00)
    DateTime dti03 = Convert.ToDateTime("2015/11/13");      //변환 가능 (2015년 11월 13일 오후 12:00:00)
    DateTime dti04 = Convert.ToDateTime("2015-11/13");      //변환 가능 (2015년 11월 13일 오후 12:00:00)
    DateTime dti05 = Convert.ToDateTime("2015/11 13");      //변환 가능 (2015년 11월 13일 오후 12:00:00)
    DateTime dti06 = Convert.ToDateTime("20151113");        //에러 (구분값 없음)
    DateTime dti07 = Convert.ToDateTime("2015_11_13");      //에러 (구분값 에러)
    DateTime dti08 = Convert.ToDateTime("2015:11:13");      //에러 (구분값 에러 :는 시간에서 사용가능)
}

3. 데이터 보기 좋게 가공

        public void test()
        {
            var result = DateTime.Now.ToString("yyyy-MM-dd HH:mm:s");
            Console.WriteLine(result);
        }


 

2. Timer 는 테스트 후 다시 기록하기로 한다.

 

 

1. 라이브러리로 생각되긴하는데, C#에서의 솔루션용 Nuget 패키지 의미를 잘모르겠다.

 

using Newtonsoft.Json;

 


2. File 클래스를 사용하려면 추가

using System.IO;

> 읽기 활용

1. 바로 해당 인스턴스 Dictionary로 전환

 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);
                }
                //Newtonsoft.Json 축약가능 using Newtonsoft.Json; 하면

 

2. 배열타입 인스턴스에서 다시 Dictionary로 전환

  var json = File.ReadAllText("./achievement_data.json");
            var arrAchievementDatas = JsonConvert.DeserializeObject<AchievementData[]>(json);
            foreach (var data in arrAchievementDatas) {
                this.dicAchievementDatas.Add(data.id, data);
            }

 


> 쓰기

        public void Save()
        {
            try
            {
                var json = JsonConvert.SerializeObject(this);
                File.WriteAllText("./info/info.json", json);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                throw;
            }
        }

 


> 폴더 생성

            DirectoryInfo folder = new DirectoryInfo("./info");
            if (!folder.Exists)
            {
                folder.Create();
            }

'c# 강의 > 수업내용(문법 관련)' 카테고리의 다른 글

20200505 - 2차원 배열 (캐릭터 이동)  (0) 2020.05.06
DateTime / Timer 활용  (0) 2020.04.29
20200428 - 문자열 콤마 찍기  (0) 2020.04.28
20200427 - 싱글톤  (0) 2020.04.28
20200423 - Achievement  (0) 2020.04.23
 string money = String.Format("{0:#,###}", data[key].price);


- 맴버로 private static 자신 타입 변수 준비(인스턴스) 

 class DataManager
    {
        private static DataManager singleTone;
        
        private Dictionary<int, HeroData> dicHeroData;
        private Dictionary<int, CurrencyData> dicCurrencyData;
        private Dictionary<int, ItemData> dicItemData;


- 생성자 private 으로 선언 및  컬렉션 초기화

 private DataManager()
        {
            this.dicCurrencyData = new Dictionary<int, CurrencyData>();
            this.dicItemData =  new Dictionary<int, ItemData>();
            this.dicHeroData = new Dictionary<int, HeroData>();
        }

 

- GetInstance 메소드 준비

        public static DataManager GetInstance()
        {
            if (DataManager.singleTone == null)
            {
                DataManager.singleTone = new DataManager();
                return DataManager.singleTone;
            }
            else
            {
                return DataManager.singleTone;
            }
        }

+ Recent posts