• 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

Tạo game Snake đơn giản

Các bài viết hướng dẫn về Visual Basic .NET và C#

Điều hành viên: tungcan5diop, QUANITGROBEST

Hình đại diện của người dùng
vo_minhdat2007
Quản trị
Quản trị
Bài viết: 2227
Ngày tham gia: CN 17/07/2005 1:40 am
Has thanked: 13 time
Been thanked: 87 time
Liên hệ:

Tạo game Snake đơn giản

Gửi bàigửi bởi vo_minhdat2007 » T.Năm 24/09/2009 11:01 am

Tên bài viết: Tạo game Snake đơn giản
Tác giả: Võ Minh Đạt
Cấp độ bài viết: Trung bình
Tóm tắt: Tạo game Snake đơn giản, sử dụng mảng 2 chiều và một số biến quản lí



Nhìn code có lẽ bạn cho là dài, nhưng hãy thử xoá hết chú thích, xem còn lại bao nhiêu hàng :))

Project mẫu (VS 2008) :
Snake.rar
(58.6 KiB) Đã tải 2903 lần


I. Giao diện :
Chỉ đơn giản một PictureBox (tên là imgField) có:
  • Location : Tuỳ ý
  • Size : Phải là hình vuông (Width = Height) và phải chia hết cho số ô của bản đồ
    Trong ví dụ này, size của imgField là 400x400 (chia đều 20 ô, mỗi ô 20x20)

Thuộc tính KeyPreview của Form : True

Ngoài ra còn một Button Bắt đầu (butStart)

II. Code :

Các khi báo :

Mã: Chọn hết

  1.    Enum Objects As Integer
  2.         NoObject = 0
  3.         Wall = 1
  4.         Snake = 2
  5.         Food = 3
  6.     End Enum
  7.  
  8.     'Biến quản lí giao diện
  9.     Dim FieldGUI(19, 19) As PictureBox
  10.  
  11.     'Biến để quản lí bản đồ
  12.     Dim Field(19, 19) As Objects
  13.  
  14.     'Biến quản lí đầu rắn
  15.     Dim Head As New Point(0, 0)
  16.  
  17.     'Biến quản lí rắn (kể cả đầu)
  18.     Dim Snake As New List(Of Point)
  19.  
  20.     'Timer quản lí chuyển động của rắn
  21.     'Interval tuỳ bạn đặt nhanh hay chậm
  22.     Dim WithEvents tmrMove As New Timer With {.Interval = 75, .Enabled = False}
  23.  
  24.     'Biến lưu hướng di chuyển hiện tại
  25.     'Gọi 0 là lên, 1 là trái, 2 là xuống, 3 là phải
  26.     'Biến HasChanged đề phòng bug khi người chơi
  27.     'nhấn liên tục 2 phím gây lỗi
  28.     Dim CurrentDirection As Integer, HasChanged As Boolean


Xử lí giao diện "giả" khi bắt đầu chương trình và nạp các PictureBox con :

Mã: Chọn hết

  1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  2.         'Load giao diện (là các ô)
  3.         imgField.Controls.Clear()
  4.         For i As Integer = 0 To 19
  5.             For j As Integer = 0 To 19
  6.                 Dim imgGUI As New PictureBox
  7.                 'Đặt tên không bị trùng
  8.                 imgGUI.Name = "Field" & i & "_" & j
  9.                 'Kích thước chia đều cho 20 ô
  10.                 imgGUI.Size = New Size(imgField.Width / 20, imgField.Height / 20)
  11.                 'Các thông số khác
  12.                 imgGUI.Location = New Point(j * imgGUI.Width, i * imgGUI.Height)
  13.                 imgGUI.Visible = True
  14.                 'Thêm vào giao diện
  15.                 imgField.Controls.Add(imgGUI)
  16.                 'Thêm vào danh sách quản lí
  17.                 FieldGUI(j, i) = imgGUI
  18.                 'Nếu là ô ở biên thì sẽ là tường
  19.                 If j = 0 Or i = 0 Or j = 19 Or i = 19 Then Field(j, i) = Objects.Wall
  20.             Next
  21.         Next
  22.         'Đặt các giá trị đầu để thể hiện khi chưa bắt đầu!
  23.         'Đây chỉ là cho người dùng tưởng rằng ta đã khởi tạo
  24.         'nhưng thực ra vẫn chưa :D
  25.         Field(1, 1) = Objects.Snake
  26.         Field(2, 1) = Objects.Snake
  27.         Field(3, 1) = Objects.Snake
  28.         Field(4, 1) = Objects.Snake
  29.         Head = New Point(5, 1)
  30.         DrawGUI()
  31.     End Sub


Các code còn lại :

Mã: Chọn hết

  1.    Sub DrawGUI() 'Tô màu các ô
  2.         'Không có gì là màu trắng
  3.         'Tường là màu đen
  4.         'Rắn là màu vàng
  5.         'Đầu rắn là màu đỏ
  6.         'Thức ăn là màu xanh
  7.         For i As Integer = 0 To 19
  8.             For j As Integer = 0 To 19
  9.                 Select Case Field(i, j)
  10.                     Case Objects.NoObject
  11.                         FieldGUI(i, j).BackColor = Color.White
  12.                     Case Objects.Wall
  13.                         FieldGUI(i, j).BackColor = Color.Black
  14.                     Case Objects.Snake
  15.                         FieldGUI(i, j).BackColor = Color.Yellow
  16.                     Case Objects.Food
  17.                         FieldGUI(i, j).BackColor = Color.Blue
  18.                 End Select
  19.             Next
  20.         Next
  21.         FieldGUI(Head.X, Head.Y).BackColor = Color.Red
  22.     End Sub
  23.  
  24.     Private Sub butStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butStart.Click
  25.         'Reset lại (nếu đã chơi rồi) đồng thời đặt tường
  26.         For i As Integer = 0 To 19
  27.             For j As Integer = 0 To 19
  28.                 Field(i, j) = Objects.NoObject
  29.                 If i = 0 Or i = 19 Or j = 0 Or j = 19 Then Field(i, j) = Objects.Wall
  30.             Next
  31.         Next
  32.         CurrentDirection = 3
  33.         'Đặt vị trí của rắn
  34.         Field(1, 1) = Objects.Snake
  35.         Field(2, 1) = Objects.Snake
  36.         Field(3, 1) = Objects.Snake
  37.         Field(4, 1) = Objects.Snake
  38.         Field(5, 1) = Objects.Snake
  39.         Head = New Point(5, 1)
  40.         'Đặt vào biến quản lí rắn
  41.         Snake = New List(Of Point)()
  42.         Snake.Add(New Point(5, 1))
  43.         Snake.Add(New Point(4, 1))
  44.         Snake.Add(New Point(3, 1))
  45.         Snake.Add(New Point(2, 1))
  46.         Snake.Add(New Point(1, 1))
  47.         'Tạo thức ăn
  48.         GenerateFood()
  49.         'Vẽ giao diện
  50.         DrawGUI()
  51.         'Khởi động Timer
  52.         tmrMove.Start()
  53.     End Sub
  54.  
  55.     'Sub để tạo ra thức ăn ở vị trí ngẫu nhiên
  56.     Sub GenerateFood()
  57.         'Biến lưu vị trí
  58.         Dim Location As New Point
  59.         Do
  60.             'Khởi tạo class gọi số ngẫu nhiên
  61.             Dim Rnd As New Random
  62.             'x, y lấy ngẫu nhiên từ 1 đến 18
  63.             'Do 0 và 19 đã là tường
  64.             'nếu bạn không đặt tường ở biên thì thêm vào!
  65.             'Thực chất ta sẽ xét sau, nên dù thế nào
  66.             'bạn đặt từ 0 đến 19 vẫn được!
  67.             Dim x As Integer = Rnd.Next(1, 20)
  68.             Dim y As Integer = Rnd.Next(1, 20)
  69.             'Gán giá trị vào Location
  70.             Location = New Point(x, y)
  71.             'Thoát vòng lặp khi tại điểm đó không có gì cản đường
  72.             'Do x và y được khai báo ở trong vòng lặp nên bạn không dùng được!
  73.         Loop Until Field(Location.X, Location.Y) = Objects.NoObject
  74.         Field(Location.X, Location.Y) = Objects.Food
  75.     End Sub
  76.  
  77.     Private Sub tmrMove_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmrMove.Tick
  78.         '=====Di chuyển rắn====='
  79.         'Đầu rắn
  80.         ''Di chuyển
  81.         Select Case CurrentDirection
  82.             Case 0
  83.                 Head = New Point(Head.X, Head.Y - 1)
  84.             Case 1
  85.                 Head = New Point(Head.X - 1, Head.Y)
  86.             Case 2
  87.                 Head = New Point(Head.X, Head.Y + 1)
  88.             Case 3
  89.                 Head = New Point(Head.X + 1, Head.Y)
  90.         End Select
  91.         ''Kiểm tra xem có đụng tường hay đuôi không
  92.         If Field(Head.X, Head.Y) = Objects.Wall Or Field(Head.X, Head.Y) = Objects.Snake Then
  93.             'Dừng Timer trước
  94.             tmrMove.Stop()
  95.             'Gọi sự kiện thua cuộc
  96.             Lose()
  97.             'Thoát khỏi kiện
  98.             Exit Sub
  99.         End If
  100.         ''Kiểm tra xem có ăn thức ăn không
  101.         If Field(Head.X, Head.Y) = Objects.Food Then
  102.             'Thêm độ dài rắn.
  103.             'Tạm thời bạn chấp nhận, sau khi đọc code sẽ hiểu
  104.             'tại sao add New Point ở 0,0
  105.             'thực ra bạn muốn cho số nào cũng được
  106.             Snake.Add(New Point(0, 0))
  107.             'Xoá thức ăn
  108.             'Không được đặt NoObject
  109.             'để đề phòng thức ăn mới trùng
  110.             Field(Head.X, Head.Y) = Objects.Snake
  111.             'Tạo thức ăn mới
  112.             GenerateFood()
  113.         End If
  114.         'Di chuyển rắn
  115.         For i As Integer = Snake.Count - 1 To 1 Step -1
  116.             Field(Snake(i).X, Snake(i).Y) = Objects.NoObject
  117.             Snake(i) = Snake(i - 1)
  118.         Next
  119.         'Di chuyển đầu rắn
  120.         Snake(0) = Head
  121.         'Làm lại các ô có rắn trên bản đồ
  122.         For i As Integer = 0 To Snake.Count - 1
  123.             Field(Snake(i).X, Snake(i).Y) = Objects.Snake
  124.         Next
  125.         HasChanged = False
  126.         '=====Đặt lại tường ở vị trí 0, 0======'
  127.         Field(0, 0) = Objects.Wall
  128.         '=====Vẽ lại giao diện======'
  129.         DrawGUI()
  130.     End Sub
  131.  
  132.     'Gọi sub này khi thua cuộc (rắn đụng tường/đuôi)
  133.     Sub Lose()
  134.         MsgBox("Bạn đã thua!", MsgBoxStyle.Information, "Snake")
  135.     End Sub
  136.  
  137. Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
  138.         If HasChanged Then Exit Sub
  139.         Select Case e.KeyCode
  140.             Case Keys.NumPad4
  141.                 If CurrentDirection = 1 Or CurrentDirection = 3 Then Exit Sub
  142.                 CurrentDirection = 1
  143.                 e.Handled = True
  144.                 HasChanged = True
  145.             Case Keys.NumPad6
  146.                 If CurrentDirection = 1 Or CurrentDirection = 3 Then Exit Sub
  147.                 CurrentDirection = 3
  148.                 HasChanged = True
  149.             Case Keys.NumPad8
  150.                 If CurrentDirection = 2 Or CurrentDirection = 0 Then Exit Sub
  151.                 CurrentDirection = 0
  152.                 HasChanged = True
  153.             Case Keys.NumPad2
  154.                 If CurrentDirection = 2 Or CurrentDirection = 0 Then Exit Sub
  155.                 CurrentDirection = 2
  156.                 HasChanged = True
  157.         End Select
  158.     End Sub



Hình đại diện của người dùng
phongbuj
Thành viên năng nổ
Thành viên năng nổ
Bài viết: 59
Ngày tham gia: T.Bảy 11/10/2008 10:22 am

Re: Tạo game Snake đơn giản

Gửi bàigửi bởi phongbuj » CN 27/09/2009 7:37 pm

sao chuyển cái nút key Numpad4,6,8,8 thành các nút Up,dow ,left,right ko đc thế

Hình đại diện của người dùng
vo_minhdat2007
Quản trị
Quản trị
Bài viết: 2227
Ngày tham gia: CN 17/07/2005 1:40 am
Has thanked: 13 time
Been thanked: 87 time
Liên hệ:

Re: Tạo game Snake đơn giản

Gửi bàigửi bởi vo_minhdat2007 » CN 27/09/2009 8:16 pm

À, mình tạm thời làm vậy, do form không bắt sự kiện của các phím mũi tên và Page Up/Page Down. Bạn lên Google search cách bắt phím mũi tên đi, do nó hơi phức tạp hơn chút!

Hình đại diện của người dùng
phongbuj
Thành viên năng nổ
Thành viên năng nổ
Bài viết: 59
Ngày tham gia: T.Bảy 11/10/2008 10:22 am

Re: Tạo game Snake đơn giản

Gửi bàigửi bởi phongbuj » T.Ba 29/09/2009 5:24 pm

Mã: Chọn hết

  1. Sub DrawGUI() 'Tô màu các ô
  2.         'Không có gì là màu trắng
  3.         'Tường là màu đen
  4.         'Rắn là màu vàng
  5.         'Đầu rắn là màu đỏ
  6.         'Thức ăn là màu xanh
  7.         For i As Integer = 0 To 19
  8.             For j As Integer = 0 To 19
  9.                 Select Case Field(i, j)
  10.                     Case Objects.NoObject
  11.                         FieldGUI(i, j).BackColor = Color.White
  12.                     Case Objects.Wall
  13.                         FieldGUI(i, j).BackColor = Color.Black
  14.                     Case Objects.Snake
  15.                         FieldGUI(i, j).BackColor = Color.Yellow
  16.                     Case Objects.Food
  17.                         FieldGUI(i, j).BackColor = Color.Blue
  18.                 End Select
  19.             Next
  20.         Next
  21.         FieldGUI(Head.X, Head.Y).BackColor = Color.Red
  22.     End Sub
  23.  

Bạn có thể chỉ mình cách thay đổi màu thành hình không ?sao mình thay đổi các thông tin màu này thành hình không đc zậy bạn? :((

Hình đại diện của người dùng
vo_minhdat2007
Quản trị
Quản trị
Bài viết: 2227
Ngày tham gia: CN 17/07/2005 1:40 am
Has thanked: 13 time
Been thanked: 87 time
Liên hệ:

Re: Tạo game Snake đơn giản

Gửi bàigửi bởi vo_minhdat2007 » T.Ba 29/09/2009 8:29 pm

Thay vì dùng BackColor bạn thay thành Image!

Hình đại diện của người dùng
phongbuj
Thành viên năng nổ
Thành viên năng nổ
Bài viết: 59
Ngày tham gia: T.Bảy 11/10/2008 10:22 am

Re: Tạo game Snake đơn giản

Gửi bàigửi bởi phongbuj » T.Bảy 03/10/2009 11:27 am

Thay vào thì đc nhưng ..
Ví dụ cái thức ăn mình thay bằng hình quả táo thì khi rắn ăn xong nó không xóa quả táo đã ăn mà vẫn còn và hình con rắn cũng zậy

Hình đại diện của người dùng
vo_minhdat2007
Quản trị
Quản trị
Bài viết: 2227
Ngày tham gia: CN 17/07/2005 1:40 am
Has thanked: 13 time
Been thanked: 87 time
Liên hệ:

Re: Tạo game Snake đơn giản

Gửi bàigửi bởi vo_minhdat2007 » T.Bảy 03/10/2009 5:16 pm

Nếu là NoObject thì đặt thuộc tính Image lại thành Nothing!

Hình đại diện của người dùng
phongbuj
Thành viên năng nổ
Thành viên năng nổ
Bài viết: 59
Ngày tham gia: T.Bảy 11/10/2008 10:22 am

Re: Tạo game Snake đơn giản

Gửi bàigửi bởi phongbuj » T.Bảy 03/10/2009 10:03 pm

làm phiền bạn hoài mình cũng ngại quá , nhưng không làm đc mình không biết hỏi ai bạn có thể nói rõ hơn tý không

phongpk
Bài viết: 1
Ngày tham gia: T.Hai 18/10/2010 9:40 am

Re: Tạo game Snake đơn giản

Gửi bàigửi bởi phongpk » T.Hai 18/10/2010 9:43 am

anh ơi link die roi,cho e xin lai cai link nha,e cần gấp lắm.!


Quay về “[.NET] 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.5 khách