티스토리 뷰

이제 C#을 드디어 다 나갔다! 다음주부터 유니티를 배운다고 한다 너무 기대된다 ㅎㅎ

수업시간에 벽돌 부수기 게임에서 벽돌빼고 구현을 했는데 과제는 벽돌을 구현하는 거였다 생각보다 빠르게 구현해서 만족스러웠다!


💻 C#

Delegate

delegate void MessageHandler(string message);

static void DisplayMessage(string message) // 델리게이트에 연결할 메서드
{
    Console.WriteLine(message);
}

var messageHandler = new MessageHandler(DisplayMessage); // 델리게이트 인스턴스 생성
messageHandler("Hello, World!"); // 델리게이트 호출

델리게이트는 메서드를 가리키는 포인터 역할을 하는 참조타입. 즉 메서드를 변수처럼 다룰 수 있도록 해주는 기능이다

메서드 체인 (멀티태스크 델리게이트)

delegate void MessageHandler(string message);

static void DisplayMessage(string message)
{
    Console.WriteLine(message);
}

static void DisplayUpperMessage(string message) 
{
    Console.WriteLine(message.ToUpper());
}

Console.WriteLine("=== 간단한 델리게이트와 이벤트 예제 ===");

Console.WriteLine("1. 델리게이트");
var messageHandler = new MessageHandler(DisplayMessage);
messageHandler("Hello, World!");
Console.WriteLine();

Console.WriteLine("2. 메서드 체인(멀티캐스트 델리게이트)");
messageHandler += DisplayUpperMessage;
messageHandler("Hello, World!");

Event

class Character
{
    public string Name { get; private set; }
    public int Health { get; private set; }

    public event EventHandler OnDamaged; // 이벤트 선언

    public Character(string name, int health)
    {
        Name = name;
        Health = health;
    }

    public void TakeDamage(int damage)
    {
        Health -= damage;
        Console.WriteLine($"{Name}이(가) {damage} 데미지를 입었습니다.");
        OnDamaged?.Invoke(this, EventArgs.Empty);
    }
}

var hero = new Character("용사", 100);
hero.OnDamaged += HeroOnDamaged; // 이벤트 구독 
hero.TakeDamage(30); // TakeDamage 내에서 OnDamaged 이벤트가 발생함
Console.WriteLine();

hero.OnDamaged -= HeroOnDamaged; // 이벤트 구독 취소
hero.TakeDamage(30);

// 이벤트핸들러 메서드
// sender : 이벤트를 발생시킨 객체 (여기서는 Character)
// e : 이벤트와 관련된 추가 데이터
static void HeroOnDamaged(object sender, EventArgs e)
{
    var character = sender as Character;
    Console.WriteLine($"Event Alert! {character.Name}이(가) 데미지를 입었습니다! " +
        $"(현재 체력 {character.Health})");
}

특정 이벤트가 발생했을 때 실행되는 동작으로 Delegate 기반으로 구현한다

Action

class Character
{
    public string Name { get; private set; }
    public int Health { get; private set; }

    public Action<Character, int> OnDamaged; // 이벤트 역할

    public Character(string name, int health)
    {
        Name = name;
        Health = health;
    }

    public void TakeDamage(int damage)
    {
        Health -= damage;
        Console.WriteLine($"{Name}이(가) {damage} 데미지를 입었습니다.");
        OnDamaged?.Invoke(this, Health);
    }
}

var hero = new Character("용사", 100);
hero.OnDamaged += HandleDamage;
hero.TakeDamage(30);
Console.WriteLine();

hero.OnDamaged -= HandleDamage;
hero.TakeDamage(30);
Console.WriteLine();

static void HandleDamage(Character character, int health)
{
    Console.WriteLine($"Event Alert! {character.Name}이(가) 데미지를 입었습니다! " +
$"(현재 체력 {character.Health})");
}

🕹️ 콘솔 게임 만들기

벽돌 부수기 게임

public void Progress()
{
    if (MyBallData.IsReady == false)
    {
        switch (MyBallData.Direct)
        {
            case Direction.Up:
                if (!Collide(MyBallData.X, MyBallData.Y - 1))
                {
                    MyBallData.Y--;
                }
                break;
            case Direction.UpRight:
                if (!Collide(MyBallData.X + 1, MyBallData.Y - 1))
                {
                    MyBallData.X++;
                    MyBallData.Y--;
                }
                break;
            case Direction.DownRight:
                if (!Collide(MyBallData.X + 1, MyBallData.Y + 1))
                {
                    MyBallData.X++;
                    MyBallData.Y++;
                }
                break;
            case Direction.Down:
                if (!Collide(MyBallData.X, MyBallData.Y + 1))
                {
                    MyBallData.Y++;
                }
                break;
            case Direction.DownLeft:
                if (!Collide(MyBallData.X - 1, MyBallData.Y + 1)) 
                {
                    MyBallData.X--;
                    MyBallData.Y++;
                }
                break;
            case Direction.UpLeft:
                if (!Collide(MyBallData.X - 1, MyBallData.Y - 1))
                {
                    MyBallData.X--;
                    MyBallData.Y--;
                }
                break;
            default:
                break;
        }
    }
}

public bool Collide(int x, int y)
{
    if (y == 0)
    {
        MyBallData.Direct = (Direction)WallCollision[0, (int)MyBallData.Direct];
        return true;
    }

    if (x == 1)
    {
        MyBallData.Direct = (Direction)WallCollision[1, (int)MyBallData.Direct];
        return true;
    }

    if (x == 77)
    {
        MyBallData.Direct = (Direction)WallCollision[2, (int)MyBallData.Direct];
        return true;
    }

    if (y == 23)
    {
        MyBallData.Direct = (Direction)WallCollision[3, (int)MyBallData.Direct];
        return true;
    }

    return false;
}

 

방향 방향 0(위) 방향 1(오른쪽 위) 방향 2(오른쪽 아래) 방향 3(아래) 방향 4(왼쪽 아래) 방향 5(왼쪽 위)
위쪽 벽(0) 3 (아래로 변경) 2 (오른쪽 아래로 변경) -1 (변화 없음) -1 (변화 없음) -1 (변화 없음) 4 (왼쪽 아래로 변경)
오른쪽 벽(1) -1 (변화 없음) -1 (변화 없음) -1 (변화 없음) -1 (변화 없음) 2 (오른쪽 아래로 변경) 1 (오른쪽 위로 변경)
아래쪽 벽(2) -1 (변화 없음) 5 (왼쪽 위로 변경) 4 (왼쪽 아래로 변경) -1 (변화 없음) -1 (변화 없음) -1 (변화 없음)
왼쪽 벽(3) -1 (변화 없음) -1 (변화 없음) 1 (오른쪽 위로 변경) 0 (위로 변경) 5 (왼쪽 위로 변경) -1 (변화 없음)

📝 과제

벽돌게임 완성하기

https://github.com/yh97yhyh/likelion-csharp-study/tree/main/BrickGame

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함