serezo Yönetici
Ruh Hali : Mesaj Sayısı : 952 Rep Puanı : 13489 Teşekkür Aldı : 0 Kayıt tarihi : 29/10/09 Nerden : Kocaeli/Gebze İş/Hobiler : MEsaj atmak :D Lakap : Sezo
| Konu: Visual Basic'te Yap-Boz Oyunu Yapımı Çarş. Ara. 09, 2009 6:13 pm | |
| Yap-Boz Oyunu -------------------------------------------------------------------------------- GDIPlus grafik apisi kullanılarak yapılmış, sade, anlaşılır ve tarafımdan yazılmış bir oyun. GenelUygulamada; 1- mdlMain (module): Genel değişkenlerin bulunduğu modül 2- mdlGDIPlus (module): GDIPlus fonksiyon, enum ve type lerinin bulunduğu modül 3- CCell (class): Oyundaki resim hücrelerini yöneten class 4- CTable (class): Oyunun genel resim bilgisini yöneten class 5- frmMain (form): Oyunun çizildiği genel form ...bölümleri kullanılmıştır.mdlMain-------------------------------------------------------------------------------- Bu modülde genel tanımlamalar ve user32 library nin DrawEdge fonksiyonu kullanılmıştır.
Kullanılan Sabitler; Public Const COLUMNS As Long = 4 ' Oyundaki toplam kolon sayisi Public Const ROWS As Long = 3 ' Oyundaki toplam satır sayisi Public Const ORGX As Long = 4 ' Oyun tablosunun baslangiç koordinatlari (x) Public Const ORGY As Long = 4 ' Oyun tablosunun baslangiç koordinatlari (y) Public Const CELLW As Long = 110 ' Oyundaki tek bir hücrenin genisligi Public Const CELLH As Long = 110 ' Oyundaki tek bir hücrenin yüksekligi
Kullanılan Tipler; Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type
Kullanılan Api Fonksiyonu; Public Declare Function DrawEdge Lib "user32" _ (ByVal hdc As Long, _ qrc As RECT, _ ByVal edge As Long, _ ByVal grfFlags As Long) As Long
DrawEdge fonksiyonu belirtilen koordinatlara, belirtilen tipte çerçeve çizer. mdlMain modülünün kodları:Option Explicit
'Constant for game Public Const COLUMNS As Long = 4 ' Oyundaki toplam kolon sayisi Public Const ROWS As Long = 3 ' Oyundaki toplam satır sayisi Public Const ORGX As Long = 4 ' Oyun tablosunun baslangiç koordinatlari (x) Public Const ORGY As Long = 4 ' Oyun tablosunun baslangiç koordinatlari (y) Public Const CELLW As Long = 110 ' Oyundaki tek bir hücrenin genisligi Public Const CELLH As Long = 110 ' Oyundaki tek bir hücrenin yüksekligi
Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type
Public Declare Function DrawEdge Lib "user32" _ (ByVal hdc As Long, _ qrc As RECT, _ ByVal edge As Long, _ ByVal grfFlags As Long) As LongmdlGDIPlus-------------------------------------------------------------------------------- Bu uygulamada kullanılan GDIPlus foksiyonları tanımlanmıştır. GDIPlus fonksiyonlarının tamamı için GDI Analog Saat Örneği dökümanımı inceleyebiliriniz.mdlGDIPlus modülünün kodları:Option Explicit
Public Enum GpUnit ' aka Unit UnitWorld ' 0 -- World coordinate (non-physical unit) UnitDisplay ' 1 -- Variable -- for PageTransform only UnitPixel ' 2 -- Each unit is one device pixel. UnitPoint ' 3 -- Each unit is a printer's point, or 1/72 inch. UnitInch ' 4 -- Each unit is 1 inch. UnitDocument ' 5 -- Each unit is 1/300 inch. UnitMillimeter ' 6 -- Each unit is 1 millimeter. End Enum
' NOTE: Enums evaluate to a Long Public Enum GpStatus ' aka Status Ok = 0 GenericError = 1 InvalidParameter = 2 OutOfMemory = 3 ObjectBusy = 4 InsufficientBuffer = 5 NotImplemented = 6 Win32Error = 7 WrongState = 8 Aborted = 9 FileNotFound = 10 ValueOverflow = 11 AccessDenied = 12 UnknownImageFormat = 13 FontFamilyNotFound = 14 FontStyleNotFound = 15 NotTrueTypeFont = 16 UnsupportedGdiplusVersion = 17 GdiplusNotInitialized = 18 PropertyNotFound = 19 PropertyNotSupported = 20 End Enum
Public Type GdiplusStartupInput GdiplusVersion As Long ' Must be 1 for GDI+ v1.0, the current version as of this writing. DebugEventCallback As Long ' Ignored on free builds SuppressBackgroundThread As Long ' FALSE unless you're prepared to call ' the hook/unhook functions properly SuppressExternalCodecs As Long ' FALSE unless you want GDI+ only to use ' its internal image codecs. End Type
Public Declare Function GdiplusStartup Lib "gdiplus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As GpStatus Public Declare Sub GdiplusShutdown Lib "gdiplus" (ByVal token As Long)
Public Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hdc As Long, graphics As Long) As GpStatus Public Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal graphics As Long) As GpStatus
Public Declare Function GdipDrawImageRect Lib "gdiplus" (ByVal graphics As Long, ByVal image As Long, ByVal x As Single, ByVal y As Single, ByVal Width As Single, ByVal Height As Single) As GpStatus Public Declare Function GdipLoadImageFromFile Lib "gdiplus" (ByVal filename As String, image As Long) As GpStatus Public Declare Function GdipDisposeImage Lib "gdiplus" (ByVal image As Long) As GpStatus Public Declare Function GdipGetImageWidth Lib "gdiplus" (ByVal image As Long, Width As Long) As GpStatus Public Declare Function GdipGetImageHeight Lib "gdiplus" (ByVal image As Long, Height As Long) As GpStatus Public Declare Function GdipGetImagePixelFormat Lib "gdiplus" (ByVal image As Long, PixelFormat As Long) As GpStatus Public Declare Function GdipCloneBitmapAreaI Lib "gdiplus" (ByVal x As Long, ByVal y As Long, ByVal Width As Long, ByVal Height As Long, ByVal PixelFormat As Long, ByVal srcBitmap As Long, dstBitmap As Long) As GpStatusCCell-------------------------------------------------------------------------------- Bu class, oyundaki tek bir hücre bilgisini barındırır. (Bu hücreye ait resim bilgisi, sütun ve satır numarası vb...)
Bu class ta kullanılan değişken, fonksiyon, sub ve property; *Değişkenler; Dim m_nNewRow As Long ' Oyunda karıştırılmış olan hücrelerde bu hücrenin yeni satır numarası Dim m_nNewColumn As Long ' Oyunda karıştırılmış olan hücrelerde bu hücrenin yeni sütun numarası Dim m_nRow As Long ' Hücredeki remin orjinal satır numarası Dim m_nColumn As Long ' Hücredeki remin orjinal sütun numarası Dim m_nImage As Long ' Hücredeki m_nRow ve m_nColumn a denk düşen resim parçası*Foksiyon, Sub ve Property ler;1- Public Sub SetImage(ByVal nImage As Long, ByVal nColumn As Long, ByVal nRow As Long) nImage: GDIPlus ile olusturulmus Image objesi nColumn: Bu hücrenin hangi kolonda bulunduğu bilgisi nRow: Bu hücrenin hangi satırda bulunduğu bilgisi
Fonksiyon, nImage olarak belirtilen genel resimdeki nColumn ve nRow koordinatlarına denk gelen resim parçasını class genelinde tanımlı olan m_nImage değişkenine kopyalar.
2- Public Function DrawImage(ByVal hDestDC As Long, ByVal nColumn As Long, ByVal nRow As Long, ByVal nX As Long, ByVal nY As Long) As Long hDestDC: Çizilecek olan resmin çiziminin yapılacağı hDC alanı nColumn: Çizilecek olan resmin belirtilen yeni sütun numarası nRow: Çizilecek olan resmin belirtilen yeni satır numarası nX: Çizimin yapılacağı alanın X koordinat başlangıç değeri nY: Çizimin yapılacağı alanın Y koordinat başlangıç değeri
3- Public Sub SetPosition(ByVal nNewColumn As Long, ByVal nNewRow As Long) nNewColumn: Çizim sırasında kullanılacak olan yeni sütun numarası nNewRow: Çizim sırasında kullanılacak olan yeni satır numarası
4- Public Property Get NewRow() As Long Çizilecek resmin yeni satır numarası
5- Public Property Get NewColumn() As Long Çizilecek resmin yeni sütun numarası
6- Public Property Get Row() As Long Çizilecek resmin orjinal satır numarası
7- Public Property Get Column() As Long Çizilecek resmin orjinal sütun numarası
8- Private Sub Class_Terminate() Bu sub ta SetImage() fonksiyonu ile olusturulmus olan ve class genelinde tanımlı m_nImage objesi kaldırılır. CCell classının kodları:Option Explicit
Dim m_nNewRow As Long Dim m_nNewColumn As Long Dim m_nRow As Long Dim m_nColumn As Long Dim m_nImage As Long
Public Sub SetImage(ByVal nImage As Long, ByVal nColumn As Long, ByVal nRow As Long) If nImage = 0 Then Exit Sub Dim nPixFormat As Long Dim nSrcWidth As Long Dim nSrcHeight As Long Dim nX As Long, nY As Long, nWidth As Long, nHeight As Long If m_nImage Then Call GdipDisposeImage(m_nImage) m_nImage = 0 End If Call GdipGetImageWidth(nImage, nSrcWidth) Call GdipGetImageHeight(nImage, nSrcHeight) nWidth = (nSrcWidth - (nSrcWidth Mod COLUMNS)) / COLUMNS nHeight = (nSrcHeight - (nSrcHeight Mod ROWS)) / ROWS nX = nColumn * nWidth nY = nRow * nHeight m_nColumn = nColumn m_nRow = nRow m_nNewColumn = nColumn m_nNewRow = nRow Call GdipGetImagePixelFormat(nImage, nPixFormat) Call GdipCloneBitmapAreaI(nX, nY, nWidth, nHeight, nPixFormat, nImage, m_nImage) End Sub
Public Function DrawImage(ByVal hDestDC As Long, ByVal nColumn As Long, ByVal nRow As Long, ByVal nX As Long, ByVal nY As Long) As Long If m_nImage = 0 Then Exit Function Dim graphic As Long Dim rc As RECT nX = nColumn * CELLW + nX nY = nRow * CELLH + nY If GdipCreateFromHDC(hDestDC, graphic) <> Ok Then GoTo son: If GdipDrawImageRect(graphic, m_nImage, nX, nY, CELLW, CELLH) <> Ok Then GoTo son: rc.Left = nX rc.Right = rc.Left + CELLW rc.Top = nY rc.Bottom = rc.Top + CELLH DrawImage = DrawEdge(hDestDC, rc, 5, 15) son: Call GdipDeleteGraphics(graphic) End Function
Public Property Get NewRow() As Long NewRow = m_nNewRow End Property
Public Property Get NewColumn() As Long NewColumn = m_nNewColumn End Property
Public Property Get Row() As Long Row = m_nRow End Property
Public Property Get Column() As Long Column = m_nColumn End Property
Public Sub SetPosition(ByVal nNewColumn As Long, ByVal nNewRow As Long) m_nNewColumn = nNewColumn m_nNewRow = nNewRow End Sub
Private Sub Class_Terminate() If m_nImage Then Call GdipDisposeImage(m_nImage) m_nImage = 0 End If End SubCTable-------------------------------------------------------------------------------- Bu class oyunun genel tablo yapısını barındırır. Hücre kontrolleri bu klas üstünden yapılmaktadır.
Bu class ta kullanılan değişken, fonksiyon, sub ve property;*Değişkenler; Dim m_mxTable(COLUMNS - 1, ROWS - 1) As New CCell m_mxTable matrisi belirtilen COLUMNS ve ROWS sabitleri kadar CCell class ları bilgilerini saklar. COLUMNS ve ROWS değerlerini değiştirerek oyunu zorlaştırabilirsiniz. Bunu parametrik yapmadım. İsterseniz menüye bu özelliği ekleyebilirsiniz. *Foksiyon, Sub ve Property ler;1- Public Function LoadPicture(ByVal sFileName As String) As Boolean sFileName: Belirtilen resim dosyasini yükler. Bu fonksiyonda resim, GDIPlus kullanılarak yüklenmiştir.
2- Private Sub RefreshTable(ByVal nImage As Long) nImage: LoadPicture fonksiyonunda yüklenen resim Image (GDIPlus) olarak bu fonksiyona gönderilir. Bu fonksiyon vasıtası ile resim parçalara ayrılır ve CCell hücrelerine set edilir.
3- Public Sub DrawTable(ByVal hDestDC As Long, ByVal nX As Long, ByVal nY As Long) hDestDC: Oyunun çizileceği genel resim alanının hDC değeri. nX: Oyunun çizileceği alanın başlangıç X koordinatı. nY: Oyunun çizileceği alanın başlangıç Y koordinatı. Bu fonksiyon, karıştırılmış olan resim parçalarını karıştırıldığı şekli ile hDestDC alanına çizer.
4- Public Sub DrawPreview(ByVal hDestDC As Long, ByVal nX As Long, ByVal nY As Long) hDestDC: Oyunun çizileceği genel resim alanının hDC değeri. nX: Oyunun çizileceği alanın başlangıç X koordinatı. nY: Oyunun çizileceği alanın başlangıç Y koordinatı. Bu fonksiyon, karıştırılmış olan resim parçalarını orjinal şekli ile hDestDC alanına çizer. Fonksiyonun amacı, oyun sırasında kullanıcının genel resmi görmesi için kullanılır.
5- Public Sub NewGame() Yeni oyun için mevcut olan hücreleri random olarak karıştırır. Karıştırma işleminde karıştırılan hücrelerden tekrar orjinal resme ulaşılabilmesi için bu fonksiyon içindeki karıştırma tekniği kullanılmıştır.
6- Public Function HitTest(ByVal nX As Long, ByVal nY As Long) As CCell Belirtilen nX ve nY koordinatlarındaki hücreyi döndürür. Mouse ile forma tıklandığında, hangi hücrenin seçildiği, bu fonksiyon yardımı ile belirlenir.
7- Public Property Get EndOfGame() As Boolean Bu fonsiyon, orjinal satır ve sütun numaraları ile oyun boyunca kullanıcı tarafından değiştirilen yeni satır ve sütun numaralarını karşılaştırır. Tüm satır ve sütunlar birbirine eşit ise oyunun tamamlandığına dair True değerini döndürür.
8- Public Sub Click(ByVal nX As Long, ByVal nY As Long) Mouse ile form üstünde tıklanan noktanın X ve Y koordinatları bu fonksiyona gönderilir. Bu fonksiyon belirtilen noktadaki hücrenin sağ, sol, yukarı ve aşağı hareket edebilme kabiliyetini kontrol ederek hücrenin satır ve sütun numarasını değiştirerek yeni yerine tayin eder.
9- Private Sub ChangeItem(item1 As CCell, item2 As CCell) Belirtilen iki hücrenin Row ve Column değerlerini yer değiştirir. "Click" fonksiyonu tarafından kullnılır. CTable classının kodları:Option Explicit
Dim m_mxTable(COLUMNS - 1, ROWS - 1) As New CCell
Public Function LoadPicture(ByVal sFileName As String) As Boolean Dim nImage As Long
If GdipLoadImageFromFile(StrConv(sFileName, vbUnicode), nImage) <> Ok Then Exit Function End If
Call RefreshTable(nImage) Call GdipDisposeImage(nImage) LoadPicture = True End Function
Private Sub RefreshTable(ByVal nImage As Long) 'ilk degerler set edilir. Dim i As Long, j As Long For j = 0 To ROWS - 1 For i = 0 To COLUMNS - 1 With m_mxTable(i, j) Call .SetImage(nImage, i, j) End With Next i Next j End Sub
Public Sub DrawTable(ByVal hDestDC As Long, ByVal nX As Long, ByVal nY As Long) Dim i As Long, j As Long 'karistirilmis olan hücreler 'ekrana çizdirilir. For j = 0 To ROWS - 1 For i = 0 To COLUMNS - 1 With m_mxTable(i, j) If .Column > 0 Or .Row > 0 Then Call .DrawImage(hDestDC, .NewColumn, .NewRow, nX, nY) End If End With Next i Next j End Sub
Public Sub DrawPreview(ByVal hDestDC As Long, ByVal nX As Long, ByVal nY As Long) Dim i As Long, j As Long 'Normal resmin tamami gösterilir. For j = 0 To ROWS - 1 For i = 0 To COLUMNS - 1 With m_mxTable(i, j) Call .DrawImage(hDestDC, i, j, nX, nY) End With Next i Next j End Sub
Public Sub NewGame() 'Bu bölümde hücreleri karistirarak 'yeni bir oyun olusturuyoruz 'karistirma islemi neticesinde 'mutlaka, çözülebilir bir oyun olusturulur. Dim n1 As Long Dim i As Long, j As Long Dim nCol As Long, nRow As Long Dim spaceItem As CCell Dim item1 As CCell Set spaceItem = m_mxTable(0, 0) For n1 = 0 To 100 nCol = 2 * Rnd(999) - 1 + spaceItem.NewColumn nRow = 2 * Rnd(999) - 1 + spaceItem.NewRow If nCol < 0 Then nCol = spaceItem.NewColumn + 1 If nRow < 0 Then nRow = spaceItem.NewRow + 1 If nCol >= COLUMNS Then nCol = spaceItem.NewColumn - 1 If nRow >= ROWS Then nRow = spaceItem.NewRow - 1 Set item1 = HitTest(nCol * CELLW + ORGX, nRow * CELLH + ORGY) Debug.Assert Not item1 Is Nothing Call ChangeItem(item1, spaceItem) Next n1 End Sub
Public Function HitTest(ByVal nX As Long, ByVal nY As Long) As CCell Dim i As Long, j As Long Dim item1 As CCell Dim nColumn As Long, nRow As Long nX = nX - ORGX nY = nY - ORGY If nX < 0 Or nX > (CELLW * COLUMNS) Then Exit Function If nY < 0 Or nY > (CELLH * ROWS) Then Exit Function nColumn = (nX - (nX Mod CELLW)) / CELLW nRow = (nY - (nY Mod CELLH)) / CELLH For j = 0 To ROWS - 1 For i = 0 To COLUMNS - 1 Set item1 = m_mxTable(i, j) If item1.NewColumn = nColumn And item1.NewRow = nRow Then Set HitTest = item1 Set item1 = Nothing Exit Function End If Set item1 = Nothing Next i Next j End Function
Public Property Get EndOfGame() As Boolean Dim item1 As CCell Dim i As Long, j As Long For j = 0 To ROWS - 1 For i = 0 To COLUMNS - 1 Set item1 = m_mxTable(i, j) If item1.NewColumn <> i Or item1.NewRow <> j Then Set item1 = Nothing Exit Property End If Set item1 = Nothing Next i Next j EndOfGame = True End Property
Public Sub Click(ByVal nX As Long, ByVal nY As Long) Dim selCell As CCell Dim spaceCell As CCell Dim n1 As Long, n2 As Long Set selCell = HitTest(nX, nY) If selCell Is Nothing Then Exit Sub Set spaceCell = m_mxTable(0, 0) n1 = Abs(selCell.NewColumn - spaceCell.NewColumn) n2 = Abs(selCell.NewRow - spaceCell.NewRow) If (n1 = 0 And n2 = 1) Or (n1 = 1 And n2 = 0) Then Call ChangeItem(selCell, spaceCell) End If End Sub
Private Sub ChangeItem(item1 As CCell, item2 As CCell) Dim nCol As Long, nRow As Long nCol = item1.NewColumn nRow = item1.NewRow Call item1.SetPosition(item2.NewColumn, item2.NewRow) Call item2.SetPosition(nCol, nRow) End Sub frmMain-------------------------------------------------------------------------------- Bu form oyunun çizildiği genel alandır. Bu form da kullanılan değişken, fonksiyon, sub ve property;*Değişkenler; Dim m_objTable As New CTable ' Genel oyun tablo objesi Dim m_bDisabled As Boolean ' Oyununda mouse faaliyetlerini kontrol eder (kullanılır veya kullanılamaz) Dim m_nToken As Long ' GDIPlus dll dosyasının yüklenme bilgisini barındırır.*Foksiyon, Sub ve Property ler; 1- Private Sub Form_Load() Form yüklenirken, formun scalemode bölümü ayarlanır ve GDIPlus apisi yüklenir.
2- Private Sub Form_Unload(Cancel As Integer) Kullanılan m_objTable objesi kaldırılır. GDIPlus apisi kaldırılır.
3- Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single) Mouse koordinatlarına göre tablodaki resmin pozisyonu değiştirilir. Oyunun kazanılıp-kazanılmadığı bu fonksiyonda kontrol edilir.
4- Private Sub DrawPreview() Orjinal resmin tamamı çizilir.
5- Private Sub DrawTable() Oyunun kendisi çizilir.
6- Private Sub Timer1_Timer() Preview ekranı belirtilen süre boyunca kullanıcıya gösterilir. Timer süresi değiştirilerek bu süre artırılıp azaltılabilir.
7- Private Sub miOpen_Click() Oyunda kullanılacak resim yüklenir.
8- Private Sub miNewGame_Click() Yeni oyun hazırlanır. Bu menü her seçildiğinde, random olarak yeni bir oyun ekranı hazırlanır.
9- Private Sub miPreview_Click() Oyunun yüklenmiş olan genel resmini kullanıcıya hatırlatmak için bu menü kullanılır.
10- Private Sub miExit_Click() Uygulama kapatılır. frmMain formunun kodları:Option Explicit
Dim m_objTable As New CTable Dim m_bDisabled As Boolean Dim m_nToken As Long
Private Sub Form_Load() Dim GpInput As GdiplusStartupInput Me.ScaleMode = vbPixels ' Load the GDI+ Dll GpInput.GdiplusVersion = 1 If GdiplusStartup(m_nToken, GpInput) <> Ok Then MsgBox "Error loading GDI+!", vbCritical Unload Me End If End Sub
Private Sub Form_Unload(Cancel As Integer) Set m_objTable = Nothing ' Unload the GDI+ Dll Call GdiplusShutdown(m_nToken) End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single) If Button = 1 And (Not m_bDisabled) Then Call m_objTable.Click(x, y) Call DrawTable If m_objTable.EndOfGame Then m_bDisabled = True Call DrawPreview If MsgBox("Tebrikler kazandınız?" & vbNewLine & "Yeni bir oyun oynamak ister misiniz?", vbDefaultButton2 + vbYesNo, "Tebrikler") = vbYes Then Call miNewGame_Click End If End If End If End Sub
Private Sub miExit_Click() Unload Me End Sub
Private Sub miNewGame_Click() Call m_objTable.NewGame Call DrawTable End Sub
Private Sub miOpen_Click() openDLG.filename = vbNullString openDLG.Filter = "All Pictures (*.bmp; *.jpeg; *.jpg)|*.bmp; *.jpeg; *.jpg|BMP File (*.bmp)|*.bmp|JPEG File (*.jpg; *.jpeg)|*.jpg; *.jpeg" Call openDLG.ShowOpen If openDLG.filename <> vbNullString Then If m_objTable.LoadPicture(openDLG.filename) Then miNewGame.Enabled = True miPreview.Enabled = True Call miNewGame_Click End If End If End Sub
Private Sub miPreview_Click() If Not m_bDisabled Then m_bDisabled = True Call DrawPreview Timer1.Enabled = True End If End Sub
Private Sub Timer1_Timer() If m_bDisabled Then Timer1.Enabled = False Call DrawTable m_bDisabled = False End If End Sub
Private Sub DrawPreview() Me.Cls m_objTable.DrawPreview Me.hdc, ORGX, ORGY Me.Refresh End Sub
Private Sub DrawTable() Me.Cls m_objTable.DrawTable Me.hdc, ORGX, ORGY Me.Refresh | |
|