贪吃蛇
网上下的源码,可是看不懂,大家能否帮我注释下呢?  不懂的地方已经标出来了Dim s() As Integer
Dim dz(1) As Integer   
Dim fx As Byte   'fx是什么?
Const sb = 0
Const xb = 1
Const zb = 2
Const yb = 3Const z = 10  
Const d = 10
Const k = 10
Const g = 10
Const hg = 20 
Const sg = 20  Private Sub Form_Load()
ReDim s(1, 0) 
hgz   
s(0, 0) = 1
s(1, 0) = 1
fx = xb
bean    
End SubPrivate Sub hgz()
Dim l As Integer
Dim l1 As IntegerFor l = 0 To hg
  For l1 = 0 To sg
    Line (l * k + z, l1 * g + d)-((l + 1) * k + z, (l1 + 1) * g + d), 0, B  
Next
Next
End SubPrivate Sub bean()    
Randomize
dz(0) = Int((hg + 1) * Rnd)
dz(1) = Int((sg + 1) * Rnd)
Line (dz(0) * k + z, dz(1) * g + d)-((dz(0) + 1) * k + z, (dz(1) + 1) * g + d), 65280, BF 
End SubPrivate Sub Timer1_Timer()
Dim n As Integer
Cls  
hgz  
Line (dz(0) * k + z, dz(1) * g + d)-((dz(0) + 1) * k + z, (dz(1) + 1) * g + d), 65280, BF 
For n = UBound(s, 2) To 1 Step -1    '这个for 循环是什么作用?下标已经越界了,有什么意义? 
s(0, n) = s(0, n - 1)
s(1, n) = s(1, n - 1)
NextSelect Case fx   '这里又是怎么判别的? 
Case sb
  s(1, 0) = s(1, 0) - 1
  If s(1, 0) < 0 Then over  
Case xb
  s(1, 0) = s(1, 0) + 1
  If s(1, 0) > sg Then over
Case zb
  s(0, 0) = s(0, 0) - 1
  If s(0, 0) < 0 Then over
Case yb
  s(0, 0) = s(0, 0) + 1
  If s(0, 0) > hg Then over
End SelectIf s(0, 0) = dz(0) And s(1, 0) = dz(1) Then   
ReDim Preserve s(1, UBound(s, 2) + 1)
Select Case fx
  Case sb
   s(1, UBound(s, 2)) = s(1, 0) + 1
   s(0, UBound(s, 2)) = s(0, 0)
  Case xb
   s(1, UBound(s, 2)) = s(1, 0) - 1
   s(0, UBound(s, 2)) = s(0, 0)
  Case zb
   s(0, UBound(s, 2)) = s(0, 0) + 1
   s(1, UBound(s, 2)) = s(1, 0)
  Case yb
   s(0, UBound(s, 2)) = s(0, 0) - 1
   s(1, UBound(s, 2)) = s(1, 0)
End Select
bean
End IfLine (s(0, 0) * k + 2 + z, s(1, 0) * g + 2 + d)-((s(0, 0) + 1) * k - 2 + z, (s(1, 0) + 1) * g - 2 + d), 255, BF
For n = 1 To UBound(s, 2)
Line (s(0, n) * k + 2 + z, s(1, n) * g + 2 + d)-((s(0, n) + 1) * k - 2 + z, (s(1, n) + 1) * g - 2 + d), 255, BF
If s(0, 0) = s(0, n) And s(1, 0) = s(1, n) Then over
Next
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
Case 38       ' 38为键盘的上箭头KeyCode值
  If fx <> xb Then   '这是什么意思?有什么作用?
   fx = sb 
End If

Case 40      '40为键盘的下箭头KeyCode值
  If fx <> sb Then
   fx = xb
  End If
Case 37    '37为键盘的左箭头KeyCode值
  If fx <> yb Then
   fx = zb
  End If
Case 39    '39为键盘的右箭头KeyCode值
  If fx <> zb Then
   fx = yb
  End If
End Select
End SubPrivate Sub over()
Timer1.Enabled = False
MsgBox "哈哈~~~~,你完了"
End Sub

解决方案 »

  1.   

    1,=========================================================================================
    fx 是Byte 型的变量 
    byte 类型是一个字节的数据,这个类型有以下几个应用场合:
    1、最常用的一个场景,就是处理二进制数据流,比如说从某个文件读取一段,我们在读取的时候并不关心这个文件到底是什么格式,只需要关心我需要从哪里开始的多长的一段。然后我们可以一个字节一个字节去分析这个文件的某部分。或者我们用来获取网络上传递的信息,或者用来承载串行口传过来的数据等等。2、最简单的一个场景,就是处理一个字节的数据。对于VB.NET来说,一个Char的长度不是一个字节,也不是两个字节,而仅仅是用来表示一个字符得很抽象的类——其实是两个字节,我这么说有我的理由的:比如说字符'A',如果我们用AscII方式去理解,或者说转换成用AscII编码储存的二进制数据,那就是一个字节;如果用Unicode方式,那么就是两个字节。也就是说现在不能像VB6那样,用Char来存储一个字节的数据(首先某些二进制值是非法字符,存不进去,其次就算存进去了,也很可能会浪费50%的空间,就算做得很好也不太可能有100%的利用率),你也不要企望一个Char他就一定是代表一个字节的内容。所以现在我们用Byte来处理一个字节大小的数据。3、如果你有很多很多的标志位,就是那种只要表示“是或否”的数据,如果你用Boolean就非常不合算,因为Boolean占用4个字节,而Byte只占用一个。比如你有1百万个这样的标志,那么用Boolean要花费4MB,而用Byte只要1MB。当然,为建议你最好不要用Byte来作为标志使用,原因你自己慢慢体会。现在的内存够大,没必要为了省这么3MB的空间而作出另外一些牺牲。2,====================================================================================
    UBound 函数: 返回一个 Long 型数据,其值为指定的数组维可用的最大下标。 >>语法 UBound(arrayname[, dimension]) >>UBound 函数的语法包含下面部分: arrayname 必需的。数组变量的名称,遵循标准变量命名约定。 
    dimension 可选的;Variant (Long)。指定返回哪一维的上界。1 表示第一维,2 表示第二维,如此等等。如果省略 dimension,就认为是 1。 >>说明 UBound 函数与 LBound 函数一起使用,用来确定一个数组的大小。LBound 用来确定数组某一维的上界。 对具有下述维数的数组而言,UBound 的返回值见下表: Dim A(1 To 100, 0 To 3, -3 To 4) 语句 : 返回值 
    UBound(A, 1) : 100 
    UBound(A, 2) : 3 
    UBound(A, 3) : 4 
      

  2.   

    fx很简单,就是方向。在timer中,如果蛇将一直按fx所表明的意思移动。什么时候改变fx呢?在form keydown的时候,而且如果原来的方向和新的方向不一样的时候才改变方向,这就是说,两次重复的按键只有第一次有用。
      

  3.   

    1、'fx是定义的字节变量;
    2、For n = UBound(s, 2) To 1 Step -1    '这个for循环是数组变量赋值。但这里有问题,按照定义ReDim s(1, 0),第二个下标的最大值为0,这个循环不能被执行。   
            s(0, n) = s(0, n - 1) 
           s(1, n) = s(1, n - 1) 
       Next 
    3、Select Case fx   '这里又是怎么判别的? 
       fx有四个字节:sb,xb,zb,yb
    4、 If fx  <>  xb Then   '这是什么意思?有什么作用? 
           fx = sb  
        End If
        fx不为字节xb,则为sb
         
      

  4.   

    For n = UBound(s, 2) To 1 Step -1    '这个for 循环是什么作用?下标已经越界了,有什么意义?
    怎么会越界呢,楼主请注意STEP -1,说明循环变量是从大到小循环,每次减1Select Case fx   '这里又是怎么判别的?  
    Case sb 
       ... (1
    Case xb 
       ... (2
    Case zb 
       ... (3
    Case yb 
       ... (4
    End Select 
    这是一个多项判断,
    当FX=傻B 的时候就跳转到第(1处执行
    当FX=小B 的时候就跳转到第(2处执行
    当FX=贼B 的时候就跳转到第(3处执行
    当FX=淫B 的时候就跳转到第(4处执行Case 38       ' 38为键盘的上箭头KeyCode值 
      If fx  <>  xb Then   '这是什么意思?有什么作用? 
       fx = sb  
    End If 
    当键盘按下左方向键“<-”的时候,如果FX不等于小B,那么FX赋值为傻B
    在程序开头处有对这几个量的定义。
      

  5.   


    知道了,fx是表示方向问题一:
    Form_Load()事件中已经定义了数组s(1,0)
    ReDim s(1, 0) For n = UBound(s, 2) To 1 Step -1    这个循环的作用是什么呀?
    s(0, n) = s(0, n - 1)
    s(1, n) = s(1, n - 1)
    Next所以n=UBound(s,2)=0
    即 For n = 0 To 1 Step -1   
    s(0, 0) = s(0,  - 1)
    s(1, 0) = s(1, - 1)
    这样不是越界了吗?
    问题二:
    If s(0, 0) = dz(0) And s(1, 0) = dz(1) Then   '吃掉一个食物,又随机产生一个食物
     ReDim Preserve s(1, UBound(s, 2) + 1)  '身体加长
     Select Case fx          '身体移动
      Case sb '上                                                 身体是怎么移的呀?不太明白   s(1, UBound(s, 2)) = s(1, 0) + 1
       s(0, UBound(s, 2)) = s(0, 0)

      Case xb  '下
       s(1, UBound(s, 2)) = s(1, 0) - 1
       s(0, UBound(s, 2)) = s(0, 0)
      Case zb  '左
       s(0, UBound(s, 2)) = s(0, 0) + 1
       s(1, UBound(s, 2)) = s(1, 0)
      Case yb  '右
       s(0, UBound(s, 2)) = s(0, 0) - 1
       s(1, UBound(s, 2)) = s(1, 0)
     End Select
     bean
    End If
      

  6.   

    循环还不简单呐,你想想蛇是怎么运动的,假设一个蛇原来向右运动,现在转头向上了,自然是蛇头先转向上,后面的仍然向右,下一次timer中,第二个节与蛇头的方向一样了,而第三节以后还维持向右的方向不变。依此类推,过了N个timer之后,有N节蛇身转向上,且这些蛇身都是在蛇头转向的位置由向右转为向上。