본문 바로가기
개발 일지

비주얼 베이직(vb.net)으로 슈팅게임 만들기 - 4. 오브젝트 추가

by PrintedLove 2020. 10. 12.

저번 글에서 예고했던 대로 아이템과 적을 추가했습니다.

... 사실 적은 틀만 잡아 두었구요. 제대로 구현되진 않았습니다. 하지만 아이템은 제대로 구현되어 있습니다!

 

영상입니다.

 

 

영상에서 보시다시피 화면 크기를 640 -> 960으로 변경했습니다.

나중에 난이도를 설정할 때 화면 크기를 옵션으로 넣는것도 좋아 보이네요 ㅎㅎ

 

추가된 중요한 부분들을 설명해 드리겠습니다.

Public Class ObjectBase
    Implements IDisposable

    Protected disposed As Boolean = False
    Public kill As Boolean = False

    Public rec As Rectangle
    Public spr As SpriteSheet
    Public spr_index As Int16
    Public type As Int16
    Public random As Random

    Sub New()
        random = New Random()
    End Sub

    Sub Draw(ByVal g As Graphics)
        If -spr.width \ 2 < rec.X < S_WIDTH + spr.width \ 2 And -spr.height \ 2 < rec.Y < S_HEIGHT + spr.height \ 2 Then
            DrawSprite(g, spr, spr_index, rec.X, rec.Y)
        End If
    End Sub

    Sub DefaultEvent()
        rec.X += player_hspeed
        rec.Y += player_vspeed

        If GetDistanceTwoPoint(rec.X, rec.Y, S_WIDTH \ 2, S_HEIGHT \ 2) > S_WIDTH * 2 Then
            kill = True
        End If
    End Sub

    Sub Die()
        Finalize()
    End Sub

    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposed Then
            If disposing Then
                rec = Nothing
                spr = Nothing
                random = Nothing
            End If

        End If
        Me.disposed = True
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    Protected Overrides Sub Finalize()
        Dispose(False)
        'Debug.WriteLine("object finalized")
        MyBase.Finalize()
    End Sub
End Class

 

먼저, ObjectBase라는 이름의 클래스 입니다. 이 클래스는 이름에서 알 수 있듯 게임에서 사용되는 모든 오브젝트(아이템, 적, 투사체)들의 틀 역할을 합니다. 모든 오브젝트들은 이 클래스를 상속받아 생성됩니다.

그래서 중요한 함수들이 많이 담겨 있습니다.

VB.Net은 자동 가비지 컬렉션을 지원하지만 그건 어떠한 임계점에 도달했을 시부터 작동하므로 속도가 생명인 슈팅게임에서는 필요없는 리소스를 그때그때 제가할 필요성이 있습니다. 때문에 IDisposable 인터페이스 멤버를 정의해 수동으로 용량이 큰 리소스들을(스프라이트, 좌표 그룹) 그때그때 제거해 주도록 했습니다.

클래스 내부의 Finalize() 함수와 Diposed()함수에 그 내용이 있습니다.

그 이외에도 플레이어 기준으로 좌표값을 변경해주는 기능을 가진 DefaultEvent()함수, 비트맵에 스프라이트를 그려주는 Draw() 함수 등이 정의되어 있습니다.

 

Public Class Item : Inherits ObjectBase     'item type[ 0: exp(small), 1: exp(medium), 2: exp(big), 3: hp ball ]

    Public item_type As Int16
    Public getItem As Boolean = False

    Sub New()
        spr = spr_item
        item_type = random.Next(1, 100)

        If item_type < 4 Then           '3 %
            type = 2
        ElseIf item_type < 16 Then      '12 %
            type = 3
        ElseIf item_type < 31 Then      '15 %
            type = 1
        Else                            '70 %
            type = 0
        End If

        spr_index = type
        rec.Location = GetCoordCircle(S_WIDTH \ 2, S_HEIGHT \ 2, random.Next(0, 360) * 180 / Math.PI, S_WIDTH + random.Next(0, S_WIDTH \ 2))

        Select Case type
            Case 0                              'exp(small)
                rec.Size = New Point(11, 11)
            Case 1                              'exp(medium)
                rec.Size = New Point(17, 17)
            Case 2                              'exp(big)
                rec.Size = New Point(23, 23)
            Case 3                              'hp  ball
                rec.Size = New Point(15, 15)
        End Select
    End Sub

    Sub IndividualEvent()
        DefaultEvent()

        'item collision player 
        If Not getItem And rec.IntersectsWith(player_rec) Then
            kill = True

            Select Case type
                Case 0
                    exp_present += 10 + exp_required \ 100
                Case 1
                    exp_present += 20 + exp_required \ 10
                Case 2
                    exp_present += 50 + exp_required \ 3
                Case 3
                    hp += hp_max \ 10

                    If hp > hp_max Then
                        hp = hp_max
                    End If
            End Select
        End If
    End Sub
End Class

 

코드블럭 진짜... 나중에 VB.Net 지원하는 툴을 찾아봐야겠군요.

위 클래스는 앞서 설명해드린 ObjectBase클래스를 상속받는 Item클래스 입니다. 말 그대로 아이템 객체를 생성하는 클래스입니다.

플레이어를 기준으로 원형 좌표에 랜덤 생성되는 코드와, 정해진 확률에 따라 아이템 타입이 랜덤하게 정해지는 코드가 들어 있습니다.

아이템 종류는 exp획득 구슬 3종, HP 회복 구슬 하나 입니다. 각각 3%, 12%, 15%, 70% 확률로 랜덤하게 필드에 생성됩니다.

 

    Private Sub ObjectControl()
        'object event
        Dim list_index As Int16 = 0

        While list_index < obj_list.Count()
            obj_list.Item(list_index).IndividualEvent()

            If obj_list.Item(list_index).kill Then
                obj_list.Item(list_index).Die()

                Select Case obj_list.Item(list_index).type
                    Case 0 To 3
                        item_num -= 1
                End Select

                obj_list.RemoveAt(list_index)
            Else
                list_index += 1
            End If
        End While

        'item object number control
        If item_num < 16 Then
            CreateObject(2)
        End If
    End Sub

 

객체의 생성과 관리는 Form_play에 정의된 ObjectControl 함수가 처리합니다. 해당 함수는 timer_main스레드에 의해서 매 틱마다 호출됩니다.

Module_main에 정의된 obj_list 리스트에 오브젝트들을 요소로 저장하여 관리합니다. 해당 함수를 통해 각 객체들의 메소드들이 동작하게 됩니다.

객체의 kill 변수가 true일시 리스트에서 제거 및 객체 disposed 처리, 아이템 객체의 생성과 수 관리를 합니다.

후에 추가될 적 오브젝트도 여기서 관리될 예정입니다.

 

이외에도 EXP, HP관리등 여러 기능들이 추가되었습니다! 해당 소스는 깃허브 소스코드에서 확인해 주시기 바랍니다.

다음 글에서는 이번에야 말로 Enemy를 구현해 보도록 하겠습니다.

 

소스코드 확인 ->

 

PrintedLove/VisualBasic-Shooting-Game

shooting game project made with Visual Basic. Contribute to PrintedLove/VisualBasic-Shooting-Game development by creating an account on GitHub.

github.com

 

댓글