• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

[VB6] Sử dụng mảng Control

Các bài viết hướng dẫn, giúp các bạn hiểu và tiếp cận với Visual Basic nhanh hơn
QuangHoa
Guru
Guru
Bài viết: 542
Ngày tham gia: T.Năm 27/03/2008 9:02 am
Đến từ: Quê hương Đại tướng Võ Nguyên Giáp
Been thanked: 5 time
Liên hệ:

[VB6] Sử dụng mảng Control

Gửi bàigửi bởi QuangHoa » T.Tư 11/06/2008 8:14 pm

Tên bài viết: Hướng dẫn lập trình bằng sử dụng một mảng các Control trong VB6
Tác giả: Võ Quang Hòa
Cấp độ bài viết: Căn bản
Tóm tắt: Hướng dẫn lập trình bằng sử dụng một mảng các Control trong VB6 thông qua một trò chơi đơn giản


Lập trình chắc bạn đã làm quen với một mảng các con số, mảng các chuổi, trong VB6 còn cho phép bạn một tạo một mảng (Array) các Control. Không khó lắm để sử dụng nhưng nếu bạn sử dụng được thì trong nhiều trường hợp rất tiện lợi so với cách thông thường.

Tôi sẻ hướng dẫn các bạn sử dụng mảng các Control thông qua việc làm một trò chơi đơn giản, đó là trò xếp chử. Rất dễ mà.
Hình ảnh
Đầu tiên bạn cũng tạo ra một giao diện. Menu Game gồm có New Game, Exit, Menu Level có menu mnuLevel (caption là Level 1) với index =1, mục đính là sau đó ta sẻ tạo tiếp các Menu level 2, Level 3…., và bạn đánh dấu V vào nút check.
Hình ảnh
Tiếp đó bạn vẽ Label ghi số, khác với bình thưởng bạn không phải vẽ ra một loạt các Label mà bạn chỉ cần tạo ra một Label thôi, đặt tên cho nó là nut, chỉnh kích thước vừa phải, như tôi làm là Height=495 Width=735, bạn cho thuộc tính Top=Left=240, chỉnh lại một số thuộc tính khác như Back Color, Fore Color, Alignment tùy thích, và quan trọng nhất bạn cho Index của nó là 1. Bạn cũng điều chỉnh một số thuộc tính khác của Form nhưng cũng không nhất thiết. Xong phần thiết kế bạn sẻ có được một cái khung như thế này.
Hình ảnh
Ta bắt đầu viết Code cho nó.
Phần khai báo một số hàm, hằng số cần thiết

Mã: Chọn hết

  1. Const KhoangCach = 10
  2. Dim level As Byte
  3. Dim i As Byte
  4. Dim ViTriTrong As Byte

Bây giờ ta tạo giao diện đầy đủ.
Bạn thêm các menu Level, chẳng hạn ta có các Menu từ 1 đến 9 thì sẻ cần có một thủ tục như thế này. Menu mnuLevel với Index là 1 đã có, cần thêm các mnuLevel có Index từ 2 đến 9. Dùng lệnh Load để tạo Menu, sửa lại thuộc tính Visible = true để cho nó hiện lên. Do MnuLevel có Index là 1 được chọn nên các Menu sau cũng giống nó là cũng được chọn, do đó mà ta cần bỏ chọn đi.

Mã: Chọn hết

  1. Sub Vemenu()
  2. For i = 2 To 9
  3.     Load mnulevel(i)
  4.     mnulevel(i).Caption = " Level " & i
  5.     mnulevel(i).Visible = True
  6.     mnulevel(i).Checked = False
  7. Next
  8. End Sub

Tiếp theo bạn tạo một thủ tục để vẽ bản số. Cách làm là ta đã có Nut với Index là 1, ta sẻ vẽ tiếp các Nut có Index là 2,3 Giả sử cần vẽ ô số có số hàng bằng số cột bằng bac được truyền vào, ta cần phải vẽ bac*bac-1 nút (Vì không phải vẽ lại nút đầu tiên), vậy phải dùng một vòng lặp (vòng For) để vẽ. … Do nó có nhiều hàng nhiều cột nên ta vừa phải Load nut vừa phải định lại vị trí cho nó. Để ý một quy tắc đơn giản là nếu nut thứ I mà I chia hết cho bac thì nut đó sẻ là nut ở đầu dòng, có hoành độ trùng với nut đâu tiên, có tung độ bằng tung độ của cái trước cộng thêm một khoảng, khoảng đó chính là chiều cao của cái nut và khoảng cách của hai nut.
Hình ảnh
Còn nếu không phải là đầu dòng thì nó là liền sau một nut ở trước, nên có tung độ bằng tung độ cái trước, hoành độ là hoành độ cái trước cộng với chiều dài nút và khoảng cách 2 nút. Bạn khai báo khoảng cách hai nút này là một hằng số trước nhé. Ví dụ tôi khai báo nó bằng 10.
Hình ảnh
Sau đó ta cho Caption của nó trùng với Index của nó. Riêng nut cuối cùng ta để trống. Và tất nhiên là phải đặt thuộc tính Visible của từng cái là True để nó hiện lên, nếu không nó vẫn tồn tại nhưng ta không thấy được.

Mã: Chọn hết

  1. Sub VeBangSO(bac As Byte)
  2. On Error Resume Next
  3. Nut(1).Caption = 1
  4. For i = 2 To bac * bac
  5.     Load Nut(i)
  6.     If i Mod bac = 1 Then
  7.         Nut(i).Left = Nut(1).Left
  8.         Nut(i).Top = Nut(i - bac).Top + Nut(i - bac).Height + KhoangCach
  9.     Else
  10.         Nut(i).Left = Nut(i - 1).Left + Nut(i - 1).Width + KhoangCach
  11.         Nut(i).Top = Nut(i - 1).Top
  12.     End If
  13.     Nut(i).Caption = i
  14.     Nut(i).Visible = True
  15. Next
  16. Nut(i - 1).Caption = ""
  17. ViTriTrong = i - 1
  18. Me.Width = Nut(i - 1).Left + Nut(i - 1).Width + 300
  19. Me.Height = Nut(i - 1).Top + Nut(i - 1).Height + 900
  20. Me.Top = Screen.Height / 2 - Me.Height / 2
  21. Me.Left = Screen.Width / 2 - Me.Height / 2
  22. End Sub
  23.  

Sau đó ta điều chỉnh lại kích thước của Form cho phù hợp với số lượng các nut. Đơn giản thôi, nguyên tắc là nó không quá lớn, không quá nhỏ mà chỉ đủ để chứa cái nut cuối cùng. Bạn cũng phải chỉnh lại vị trí của Form để nó hiện đúng trên màn hình nửa.
Xong phần khởi tạo giao diện bạn hãy thêm gọi hai hàm vừa rồi trong sự kiện Form Load để kiểm tra thử. Đoạn mã này để kiểm tra thôi.

Mã: Chọn hết

  1. Private Sub Form_Load()
  2.      Vemenu
  3.      VeBangSO 4
  4. End Sub
  5.  

Bấm F5, Úm bala bạn thấy thế nào !
Hình ảnh
Xong việc khởi tạo giao diện, rất dễ phải không ! Và hay nửa chứ.
Tiếp tục ta viết Code cho nó hoạt động. Bạn tạo một thủ tục để đảo lộn thứ tự của các Nut, thật ra thì bạn chỉ đảo Caption của các nut thôi còn bản thân chúng thì đâu vẫn ở đó.
Tôi không thích hàm Rand trong VISUAL BASIC cho lắm nên tôi sẻ tạo một hàm Random thay thế. Nó sẻ lấy một số ngẫu nhiên từ 0 đến max-1

Mã: Chọn hết

  1. Function random(max As Byte) As Byte
  2.     If max = 0 Then random = 0: Exit Function
  3.     random = ((Second(Now) ^ 2 + Minute(Now) ^ 2 + Hour(Now) ^ 2 + Second(Now) * (Minute(Now) + 22) * Day(Now)) Mod max)
  4. End Function
  5.  

Bạn có thể có nhiều thuật giải khác nhau để đảo thứ tự của chúng, còn tôi thì có thuật riêng. Một vòng For duyệt các phần tử, đến phần tử nào nó chọn ngẫu nhiên một phần tử đứng sau nó để tráo đổi Caption với nó.

Mã: Chọn hết

  1. Sub TraoDoiNgauNhien(bac As Byte)
  2. Dim tempstring As String
  3.     For i = 1 To bac * bac - 1
  4.         tempstring = Nut(i).Caption
  5.         Nut(i).Caption = Nut(i + random(bac * bac - i)).Caption
  6.         Nut(i + random(bac * bac - i)).Caption = tempstring
  7.     Next
  8. End Sub
  9.  

Xong, ta viết Code cho Menu New Game. Nó sẻ vẽ bảng số sau đó tráo đổi.

Mã: Chọn hết

  1. Private Sub mnunewgame_Click()
  2.     VeBangSO (level + 2)
  3.     TraoDoiNgauNhien (level + 2)
  4. End Sub

Biến level ở đây là biến lưu level sẻ chơi. Level 1 thì có 3 hàng 3 cột, Level 2 thì có 4 hàng 4 cột… Nó sẻ được tạo giá trị mặc định là 1 trong sự kiện Form Load.
Đoạn mã Form Load trên chỉ là để cho bạn kiểm tra thôi, còn mã thực tế của nó trong chương trình sẻ là

Mã: Chọn hết

  1. Private Sub Form_Load()
  2.     Vemenu
  3.     level = 1
  4.     mnunewgame_Click
  5. End Sub
  6.  

Tiếp theo ta sẻ viết Code để cho các nut hoạt động được. Nhớ là lúc vẽ ra các Nút ta đã cho nut cuối cùng có caption là rổng, Nhưng trong quá trình chơi, ta đã di chuyển nó, vì vậy ta cần khai báo biến ViTriTrong để biết được nút nào đang là nut trống rổng. Biết được nó ta sẻ xử lý sự kiện Nut_click.
Vì Nut là một mảng các control nên khi Click vào nó ta sẻ có thêm tham số Index chính là chỉ số Index của nut được bấm chuột để xử lý .
Hình ảnh
Còn bình thường ta không có cái tham số này
Hình ảnh
Biết được vị trí trống, biết được nút nào đang được bấm xuống, ta sẻ xử lý nếu nút được bấm xuống sát ngay nút có Caption là rổng thì hai nut sẻ hoán đổi caption cho nhau, nut rổng sẻ lấy caption của nút được bấm còn nút được bấm giờ có caption sẻ là rổng. Biến ViTriTrong cập nhật lại vị trí của nút caption rổng.
Kiểm tra có đúng là sát nhau hay không, dễ thôi, nó sát nhau nếu là một trong hai trường hợp sau đây,
1: Cùng hàng, cột liên tiếp. Thế thì chắc chắn hiệu của ViTriTrong và Index phải là 1. Ngoài ra phải cùng một hàng, để ý rằng xác định nut thứ I là thuộc hàng nào, ta chỉ việc lấy I -1 mà chia lấy phần nguyên cho số bậc.
2: Cùng cột, hàng liên tiếp, thế thì hiệu của chúng phải là bac.
Những điều trên đây nếu bạn không tin hoặc không hiểu thì cứ lấy giấy bút ra vẽ kiểm tra thử là sẻ rỏ.
Sau khi kiểm tra nếu đúng thì tiếp tục kiểm tra xem bảng số đã đúng hay chưa. Từ đó Code của sự kiện nut click sẻ là.

Mã: Chọn hết

  1. Private Sub Nut_Click(Index As Integer)
  2.     If (Abs(Index - ViTriTrong) = level + 2) Or (Abs(Index - ViTriTrong) = 1 And (((Index - 1) \ (level + 2)) = ((ViTriTrong - 1) \ (level + 2)))) Then
  3.             Nut(ViTriTrong).Caption = Nut(Index).Caption
  4.             Nut(Index).Caption = ""
  5.             ViTriTrong = Index
  6.             KiemTra
  7.     End If
  8. End Sub

Và sau đây là hàm kiểm tra xem bảng số đã đúng hay chưa.

Mã: Chọn hết

  1. Sub KiemTra()
  2. On Error Resume Next
  3.     For i = 1 To (level + 2) * (level + 2) - 1
  4.         If CLng(Nut(i).Caption) <> Nut(i).Index Then Exit Sub
  5.     Next
  6. MsgBox " You win!", vbInformation, "Win !"
  7. If level < 9 Then level = level + 1
  8.     mnunewgame_Click
  9. End Sub

Thủ thuật được áp dụng ở đây là vì Index đã là có thứ tự 1,2,3 nên muốn kiểm tra xem Caption của các nut có theo thứ tự hay không thì chỉ việc so sánh Caption và Index của nó. Nếu gặp một nut nào đó mà chỉ số Index khác với Caption thì ô số chưa đúng, còn không gặp thì đúng rồi. Từ khóa On Error Resume Next để bỏ qua lỗi khi mà khi duyệt tới ô có Caption là rổng, hàm Clng (hàm chuyển chuổi các chử số thành một số nguyên) sẻ bị lỗi ở đây.
Và nếu bảng đúng thì thông báo đúng sau đó giả lập việc menu New Game được bấm để tạo trò chơi mới. Level sẻ được tăng lên 1 cho đến khi hết level 9.
Tiếp theo ta viết Code cho Menu Level. Nó cũng là một mảng các Menu, có Index, trong sự kiện click của nó cũng có thêm tham số index (là Chỉ số Index của Menu được bấm) tương tự như chỉ số Index trong sự kiện Click của Nut.

Mã: Chọn hết

  1. Private Sub mnulevel_Click(Index As Integer)
  2.     If level = Index Then Exit Sub
  3.     Huybangso level + 2
  4.     mnulevel(level).Checked = False
  5.     level = Index
  6.     mnulevel(level).Checked = True
  7.     mnunewgame_Click
  8. End Sub

Nhiệm vụ của các menu này là thay đổi Level, nếu là Level hiện tại thì thôi, bỏ qua còn không thì nó bắt đầu trò chơi với Level mới.
Ở đây chú ý rằng khi một Control đã được Load thì không thể Load lần thứ hai, mà muốn Load nó lại thì ta phải UnLoad nó trước, mặt khác nếu đang chơi các Level cao như 3,4… mà trở về Level thấp hơn 1,2 thì sẻ có một số Nut bị thừa ra, như vậy ta phải làm một hàm để loại bỏ các Control này. Ta cũng dùng một vòng For. Thêm một chú ý là vòng For phải bắt đầu từ 2 chứ không phải là từ 1 bởi vì nut có Index là 1 là có khi thiết kế chương trình chứ không phải lúc Run Time (Lúc hoạt động chương trình) nó không thể bị Unload được. Trong một số trường hợp khác muôn bỏ các Control như thế này thì ta chỉ có thể cho thuộc tính Visible là False.

Mã: Chọn hết

  1. Sub Huybangso(bac As Byte)
  2. On Error Resume Next
  3. For i = 2 To bac ^ 2
  4.    Unload Nut(i)
  5. Next
  6. End Sub

Đến đây là trò chơi về cơ bản đã xong nhưng hãy cố gắng thêm một chút nửa, vì hiện tại ta chưa thể điều khiển trò chơi bằng bàn phím được, ta mới chỉ có thể điều khiển bằng chuột được thôi. Không khó lắm đâu, đơn giản chỉ là nếu bấm phím lên trên thì số ở phía trên đổi Caption cho vị trí trống, nếu bấm phím xuống thì số phía dưới sẻ đổi chổ cho vị trí trống ở phía trên nó. Vấn đề còn lại chỉ là xác định xem lúc nào thì có thể di chuyể được và lúc nào thì không, hơi rắc rối, khó hiểu một tí nôm na ví dụ là nếu bấm phím lên trên mà vị trí trống cũng nằm hàng trên cùng thì thôi, không di chuyển được, ấn phím sang phải thì vị trí trống không thể ở cột 1 được. Ngâm cứu một tí về khoản này nhé, sẻ có nhiều phương án có thể đưa ra, nếu bạn không muốn suy nghĩ hoặc nghĩ không ra thì đây là cách của tôi. Giải thích thì dài dòng nhưng nguyên tắc thì khá đơn giản như đã đề cập ở trên, hi vọng bạn tự đọc hiểu lấy.

Mã: Chọn hết

  1. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  2. On Error Resume Next
  3. Select Case KeyCode
  4.     Case 37 ‘Phím sang phải
  5.         If (ViTriTrong) Mod (level + 2) <> 0 Then
  6.          Nut(ViTriTrong).Caption = Nut(ViTriTrong + 1).Caption
  7.          Nut(ViTriTrong + 1).Caption = ""
  8.          ViTriTrong = ViTriTrong + 1
  9.          KiemTra
  10.        End If
  11.     Case 38 ‘Phím lên trên
  12.         If (ViTriTrong <= (level + 2) * (level + 2) - level - 2) Then
  13.          Nut(ViTriTrong).Caption = Nut(ViTriTrong + level + 2).Caption
  14.          Nut(ViTriTrong + level + 2).Caption = ""
  15.          ViTriTrong = ViTriTrong + level + 2
  16.          KiemTra
  17.         End If
  18.     Case 40 ‘Phím xuống dưới
  19.         If (ViTriTrong > level + 2) Then
  20.          Nut(ViTriTrong).Caption = Nut(ViTriTrong - level - 2).Caption
  21.          Nut(ViTriTrong - level - 2).Caption = ""
  22.          ViTriTrong = ViTriTrong - level - 2
  23.          KiemTra
  24.         End If
  25.     Case 39 ‘Phím sang trái
  26.         If (ViTriTrong) Mod (level + 2) <> 1 Then
  27.          Nut(ViTriTrong).Caption = Nut(ViTriTrong - 1).Caption
  28.          Nut(ViTriTrong - 1).Caption = ""
  29.          ViTriTrong = ViTriTrong - 1
  30.          KiemTra
  31.         End If
  32.     End Select
  33. End Sub

Bạn hãy chỉnh lại hàm kiểm tra một tí chơi sẻ vui tai hơn. Chỉ là thêm cái Beep thôi.

Mã: Chọn hết

  1. Sub KiemTra()
  2. Beep
  3. On Error Resume Next
  4.     For i = 1 To (level + 2) * (level + 2) - 1
  5.         If CLng(Nut(i).Caption) <> Nut(i).Index Then Exit Sub
  6.     Next
  7. MsgBox " You win!", vbInformation, "Win !"
  8. If level < 9 Then level = level + 1
  9.     mnunewgame_Click
  10. End Sub

Và bạn hãy thêm code cho Menu Exit, thêm các menu như help, About Athor, How to Play, Hight Score. Thêm vài phím tắt khác trên bàn phím, phát triển thêm tí ví dụ như chấm điểm theo số lượt đi, chấm điểm theo thời gian hoàn thành một Level. Đổi cái Icon của file, xuất ra file .exe để đem chơi, chúc dzui dẽ.
Tóm lại một số điều như sau:
Dùng mãng (Array ) các Control có những ưu điểm
• Code ngắn gọn hơn nên dễ chỉnh sửa.
• Không mất nhiều thời gian thiết kế form.
• Có thể tạo ra rất nhiều đối tượng giống hệt nhau một cách đơn giản, muốn thay đổi chúng cũng chỉ cần thay đổi một vài thông số.
Lưu ý:
• Tạo mãng đối tượng khi thiết kết bằng cách đặt thuộc tính Index của nó.
• Load đối tượng bằng cách dùng Load <tên mãng đối tượng> (<Chỉ số>)
• Khi Load một đối tượng muốn nó hiển thị thì phải cho thuộc tính Visible là True.
• Tất cả các đối tượng khi được Load đều có các chỉ số tương tự như chỉ số của đối tượng trong quá trình thiết kế. Nếu khi thiết kế ta đã lấy nhiều đối tượng thì các đối tượng được Load sẻ có thuộc tính giống như đối tượng có Index nhỏ nhất. mặc định là 0
• Không được Load một đối tượng khi nó đã tồn tại.
• Không được Unload một đối tượng có trong quá trình thiết kế.
• Tất cả các đối tượng trong mãng đều có những sự kiện chung, khi cần phân biệt các đối tượng với nhau ta dùng tham số Index trong sự kiện.
• Muốn biết mảng có bao nhiêu đối tượng đã được Load ta dùng <tên mảng>.Count
Huong dan lap trinh su dung Array Control trong visual basic.rar
bài viết hướng dẫn
(65.56 KiB) Đã tải 2977 lần

HD PUZZ.rar
Đây là mã nguồn cho bạn tham khảo
(2.5 KiB) Đã tải 1781 lần


朋友
这些年一个人风也过雨也走,有过泪有过错还记得坚持什么。
真爱过才会懂会记没会回手,终有梦中有你在心中。
朋友一生一起走那些日子不再有,一句话一辈子一生情一杯九。
朋友不曾孤单过一声朋友你会懂,还有伤还有痛还要走还有我。

Quay về “[VB] Bài viết hướng dẫn”

Đang trực tuyến

Đang xem chuyên mục này: Không có thành viên nào trực tuyến.1 khách