본문 바로가기

Programming/VB 2010 강좌

[D_Pain] Mine Story [Ver 0.1] 과 [Ver 0.2]의 코드설명 (MyBase.KeyDown 이벤트)

안녕하세요 D_Pain입니다^^

오늘은 제가 만든 Mine Story게임의 오래된 버전과 최신버전의 코드의 차이점에 대해 강좌를 쓰려합니다^^





이 포스트는 MyBase.KeyDown 이벤트를 중점적으로 설명할겁니다.

물론 [Ver 0.2]의 케릭터 조작에는 타이머를 사용했기에 타이머에 관해서도 설명할겁니다^^

주석을 써가며 코드 설명 가겠습니다!


[Ver 0.1] 케릭터 이동에 관한 소스 코드


    Public AreChatting As Boolean = False

    Public HP게이지 As Integer = 0
'위의 선언문은 KeyDown이벤트에서 사용합니다.

Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
'이건 게임 폼에 키보드를 누를 때 발동되는 이벤트입니다.

        If AreChatting = False Then
'AreChatting이란 Boolean은 프로그램이 사용자가 채팅중인지 아닌지를 체크하기 위해 존재합니다.

            If e.KeyValue = Keys.T Then
'채팅 텍스트 박스를 직접 클릭하시거나 "T"를 눌러서 채팅을 시작하면 AreChatting은 False(거짓)에서 True(참)으로 바뀌면서 채팅 시작이 될겁니다.

                AreChatting = True

                MsgBox(AreChatting)
'이 메세지 박스는 사용자가 AreChatting이 참인지 거짓인지 알려주기 위해 집어넣었다만 사실 디버깅을 할때 사용한거라 나중엔 제거할 기능입니다.

            End If

            If Pgb_MP.Value > 0 Then
'AreChatting이 거짓일때는 사용자가 케릭터를 조종하고 있다는 소리입니다. 이 때, 케릭터의 마나가 0이상이면 밑의 코드를 수행하게됩니다.

                If e.KeyValue = Keys.D Then
'"D"를 누르면 Speed(현재 20픽셀로 설정됨)만큼 오른쪽으로 움직입니다. 그리고 1만큼 마나가 소모되구요. 이것의 문제점은 뭐냐면, 한번에 20픽셀을 가기때문에 유저는 케릭터가 움직이는 듯한 느낌을 받지 않고 대신 순간이동하는 느낌을 받게됩니다. 이 문제점은 [Ver 0.2]에서 고쳤습니다. 

                    Pnl_Character.Left += Speed

                    Pgb_MP.Value = Pgb_MP.Value - 1

                End If

                If e.KeyValue = Keys.W Then
'이것도 위의 코드와 같습니다.

                    Pnl_Character.Top -= Speed

                    Pgb_MP.Value = Pgb_MP.Value - 1

                End If

                If e.KeyValue = Keys.A Then

                    Pnl_Character.Left -= Speed

                    Pgb_MP.Value = Pgb_MP.Value - 1

                End If

                If e.KeyValue = Keys.S Then
'분명 지면은 있다만 "S"를 누르면 지면 밑으로 내려가면서 월드에서 떨어졌다고 뜹니다. 실수로 그것을 염두하지 않고 코드를 지우지 않았네요.

                    Pnl_Character.Top += Speed

                    Pgb_MP.Value = Pgb_MP.Value - 1

                End If

            End If

        End If


        '경계선 넘으면 경고!
        '말그대로 일정 경계선과 케릭터가 맞닿으면 (맵의 끝) 체력을 잃고 리스폰 장소에서 리스폰합니다.

        If Pnl_Character.Right > 965 Or Pnl_Character.Bottom > 182 Or Pnl_Character.Left < 0 Or Pnl_Character.Top < 0 Then

            MsgBox(Label3.Text & " fell from the World!")

            Pgb_HP.Value = Pgb_HP.Value - 10

            Pnl_Character.Location = New Point(453, 83)

        End If


        'HP 다 달음
        '체력이 다 달면 게임오버라고 뜨게끔합니다.

        If Pgb_HP.Value = 0 Then

            MsgBox("You died! Game Over :(")

            End

        End If

        'MP 다 달음

        If Pgb_MP.Value = 0 Then

            MsgBox("No more Mana Points to move :(")

        End If


        If AreChatting = True Then
'AreChatting이 참일 경우에는 프로그램은 텍스트 박스를 집중시킵니다. Txb_Chat.Select() 이벤트에는 텍스트박스를 작동시키는 코드가 짜여져있습니다.

            Txb_Chat.Select()

        End If

    End Sub

뭐 이 정도로 [Ver 0.1] 소스코드의 설명은 마쳤습니다 :)




[Ver 0.2] 케릭터 이동에 관한 소스 코드


    Public AreChatting As Boolean = False

    Public UsedJumpAlready As Boolean = False
'이건 새로 추가했습니다. 케릭터가 중력의 영향을 받도록 했기에 또한 버튼을 한번 누르면 점프를 한번만 할 수 있도록 만들었습니다. 나중엔 연속 점프는 못하게끔 만들겁니다^^


    Public 회복게이지 As Integer = 0


    Public WithEvents Tmr_LeftMoveAction As New Timer
'"A"를 누를떄 작동되는 타이머입니다. 이 타이머는 자연스럽게 케릭터가 움직여지게 만듭니다.

    Public WithEvents Tmr_RightMoveAction As New Timer
''"D"를 누를떄 작동되는 타이머입니다. 이 타이머는 자연스럽게 케릭터가 움직여지게 만듭니다.

    Public WithEvents Tmr_JumpAction As New Timer
''"W"를 누를떄 작동되는 타이머입니다. 이 타이머는 자연스럽게 케릭터가 움직여지게 만듭니다.

    Public TmrDuration As Integer = 0
'이건 움직일떄 작동되는 타이머가 얼마동안 작동되어야하는지 설정해주는 타이머입니다. 현재 0으로 설정되있다만 나중에 나올 코드에서 10 * LoopNumber 만큼으로 설정됩니다.

    Public LoopNumber As Integer
'LoopNumber은 몇번 반복할건지 설정합니다. 예를 든다면, JumpAction(1)이라는 코드를 사용하는데 뒤에 (1)은 LoopNumber를 1로 설정하는겁니다. 그렇게된다면 타이머의 지속시간은 10x1이 됩니다. MoveAction(1, Right)으로 만들어진 타이머에서도 역시 10x1만큼의 지속시간을 가집니다. 나중에 트윅을 쉽게하기 위해서 이렇게 코딩한겁니다 ^^

    Public X As Integer = 0
'X는 기타 잡설정을 위해서 그냥 추가 해두었습니다. 한 이벤트에서만 어느 숫자를 저장해야되는 경우, 사용합니다. 따로 선언하기가 귀찮아서 말이죠 ^^;


    '중력 작동시키는 타이머
    '말 그대로 이 타이머는 항상 작동되며 케릭터가 3픽셀씩 내려가지게끔 합니다. 지면에 도착한다면 멈추고요.

    Private Sub Tmr_Gravity_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Tmr_Gravity.Tick

        If Not Pnl_Character.Top = 84 Then

            Pnl_Character.Top += 3

        End If

        If Pnl_Character.Top > 84 Then

            Pnl_Character.Top = 84

        End If


        '디버그전용 기능
        '이건 그냥 제가 에러 체크하느라 추가한겁니다. 나중엔 지울겁니다.

        Label4.Text = AreChatting

    End Sub


    Private Sub Tmr_LeftMoveAction_Tick() Handles Tmr_LeftMoveAction.Tick


'타이머의 Interval은 1입니다. 즉 1 Tick마다 케릭터는 5픽셀 움직이게됩니다.

        Pnl_Character.Left -= 1

        Pnl_Character.Left -= 1

        Pnl_Character.Left -= 1

        Pnl_Character.Left -= 1

        Pnl_Character.Left -= 1

        X = X + 1
'1틱마다 X란 임시 숫자는 0에서 부터 1씩 추가됩니다.

        Lbl_ID.Text = X

        If X = TmrDuration Then
'1씩 올라간 X가 TmrDuration에서 설정된 숫자와 동일해진다면 타이머는 꺼질겁니다.

            Tmr_LeftMoveAction.Dispose()

            X = 0

            Pgb_MP.Value = Pgb_MP.Value - 1

        End If

    End Sub


    Private Sub Tmr_RightMoveAction_Tick() Handles Tmr_RightMoveAction.Tick


        Pnl_Character.Left += 1

        Pnl_Character.Left += 1

        Pnl_Character.Left += 1

        Pnl_Character.Left += 1

        Pnl_Character.Left += 1


        X = X + 1

        Lbl_ID.Text = X

        If X = TmrDuration Then

            Tmr_RightMoveAction.Dispose()

            X = 0

            Pgb_MP.Value = Pgb_MP.Value - 1

        End If

    End Sub


    Private Sub Tmr_JumpAction_Tick() Handles Tmr_JumpAction.Tick


'이건 점프 액션을 위한 타이머입니다. 방금전의 Move Action과 동일합니다.

        Pnl_Character.Top -= 1

        Pnl_Character.Top -= 1

        Pnl_Character.Top -= 1

        Pnl_Character.Top -= 1

        Pnl_Character.Top -= 1


        X = X + 1

        Lbl_ID.Text = X

        If X = TmrDuration Then

            Tmr_JumpAction.Dispose()

            X = 0

            Pgb_MP.Value = Pgb_MP.Value - 1

        End If

    End Sub


    Private Sub MoveAction(ByVal LoopNumber As Integer, ByVal Direction As String)

'MoveAction은 제가 만든 서브입니다.그리고 서브에 몇가지 설정을 할수 있게 만들었습니다. 바로 Loop Number와 방향을 설정할 수 있게 됬는데요, 예시: MoveAction(4, Left)은 MoveAction서브를 수행하는데 그 서브안의 LoopNumber은 4로 설정하며 Direction은 Left로 설정하는겁니다.

        '왼쪽 움직이기

        If Direction = Left Then

            '오른쪽 움직이고 있으면 중단

            If Tmr_RightMoveAction.Enabled = True Then

                Tmr_RightMoveAction.Enabled = False
'이건 오른쪽으로 움직이는 도중, 왼쪽으로 움직이면 켜있는 오른쪽으로 움직이는 타이머를 중간에 끄고 왼쪽으로 움직이게 해주는 타이머를 키는 코드입니다.

            End If

            '왼쪽 움직이는 타이머 설정

            Tmr_LeftMoveAction.Interval = 1

            Tmr_LeftMoveAction.Enabled = True

            TmrDuration = 10 * LoopNumber

            Tmr_LeftMoveAction.Start()
'이건 방향이 왼쪽일 경우, 왼쪽으로 움직이게하는 타이머를 유저가 입력한거에 맞게 설정을 하고 타이머를 실행하여 움직이게 하는 코드입니다.


            '오른쪽 움직이기

        ElseIf Direction = Right Then

            '왼쪽 움직이고 있으면 중단

            If Tmr_LeftMoveAction.Enabled = True Then

                Tmr_LeftMoveAction.Enabled = False
'이것 역시 반대 방향으로 움직이고 있을 경우, 반대 방향으로 가는 타이머를 끄는 코드입니다.

            End If

            '오른쪽 움직이는 타이머 설정

            Tmr_RightMoveAction.Interval = 1

            Tmr_RightMoveAction.Enabled = True

            TmrDuration = 10 * LoopNumber

            Tmr_RightMoveAction.Start()

        End If

    End Sub


    Private Sub JumpAction(ByVal LoopNumber As Integer)

        '점프 타이머 설정

        Tmr_JumpAction.Interval = 1

        Tmr_JumpAction.Enabled = True

        TmrDuration = 10 * LoopNumber

        Tmr_JumpAction.Start()

    End Sub


    Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown

        If AreChatting = False Then

            If e.KeyValue = Keys.T Then

                AreChatting = True

                MsgBox(AreChatting)

            End If

            If Pgb_MP.Value > 0 Then


                '왼쪽 움직이기

                If e.KeyValue = Keys.A Then

                    MoveAction(1, Left)
'왼쪽으로 움직일 때 필요한 코드가 훨씬 적군요^^ 이건 오른쪽, 점프와도 마찬가지입니다!

                End If


                '오른쪽 움직이기

                If e.KeyValue = Keys.D Then

                    MoveAction(1, Right)

                End If


                '점프하기

                If UsedJumpAlready = False Then
'이미 점프를 하지 않을때만 점프가 작동되게끔 설정했습니다.

                    If e.KeyValue = Keys.W Then

                        JumpAction(1)

                        If Pnl_Character.Top < 0 Then

                            Pnl_Character.Top = 0

                        End If

                        UsedJumpAlready = True
'점프를 한번하면 UsedJumpAlready를 참으로 바꿉니다. 이미 점프했다는 소리입니다.

                        Pgb_MP.Value = Pgb_MP.Value - 1

                    End If

                End If

            End If

        End If


        '경계선 넘으면 경고!

        If Pnl_Character.Right > 965 Or Pnl_Character.Left < 0 Then

            MsgBox(Label3.Text & " fell from the World!")

            Pgb_HP.Value = Pgb_HP.Value - 10

            Pnl_Character.Location = New Point(453, 83)

        End If


        'HP 다 달음

        If Pgb_HP.Value = 0 Then

            MsgBox("You died! Game Over :(")

            End

        End If


        'MP 다 달음

        If Pgb_MP.Value = 0 Then

            MsgBox("No more Mana Points to move :(")

        End If


        '채팅 시작할때

        If AreChatting = True Then

            Txb_Chat.Select()
'Txb_Chat.Select()나 Txb_Chat.Focus()는 뭐 차이점이 거의 없습니다. 그냥 Select를 사용했습니다.

        End If

    End Sub

에휴 피곤해라 ㅜ

아무튼 뭐 [Ver 0.1]코드에 비해서 [Ver 0.2]는 후일 제가 기존 기능을 사용한 부가 기능을 추가 할때 훨씬 수월하게 작업 할수 있도록 코드 정리를 하였습니다. 움직임을 담당하는 서브를 만들었기에 예를 들어 2단 점프를 하고 싶다면 JumpAction(2)만 쓴다면 완성입니다. 물론 2단 점프처럼 보이게 하기 위해선 첫 점프 이후, 한번 튕기는듯한 비주얼 효과는 줘야겠지만 말입니다 ^^;


어느정도 쓴듯하네요:D

그럼 이만 강좌 마치겠습니다 ^^