自动寻路.BAS
上传用户:pcw2004
上传日期:2022-02-02
资源大小:743k
文件大小:9k
源码类别:

DirextX编程

开发平台:

Visual Basic

  1. Attribute VB_Name = "自动寻路"
  2. '**********************************************************************************
  3. '***---------------------------------- A** 自动寻路模块--------------------------**
  4. '***你可以任意使用,复制和传播该模块,但请不要更改下面的内容,                    **
  5. '***-------------------------工作原理--------------------------------------------**
  6. '**  首先生成8个方向的节点,tmp(tmpe)用于记录生成的节点对应的节点号              **
  7. '**   新生成的节点的指针(d1 -表示离开起始点的 距离)指向生成他的父节点           **
  8. '**,  按该点到目的地的大小nude(i).d2 排序后加入opened列表,                      **
  9. '** (opened 总是指向离 目的地最近的点)然后再从opened表中取出一个节点,生成新的节点**
  10. '** 按8个方向生成新的节点,如果要生成的节点 已经存在(在tmp(tmpe) 中)就比较以下  **
  11. '** 改节点的 d1值 重新修改 父节点指针                                            **
  12. '**  如果达到目的地就返回 节点的序号值,如果目的地不能到达就选出                 **
  13. '**一个距离目的地最近的点做为目的地,如果起始点8个方向都不能动,就返回一个false 值**
  14. '***                                                版权所有: zfc                **
  15. '**                                                     姓名  张林               **
  16. '**                                                     邮箱  zfczl@163.tom.com  **
  17. '**                                                       QQ  21338963           **
  18. '**                                                      来自 河北省石家庄       **
  19. '**                                                                2004.5.10     **
  20. '**********************************************************************************
  21. ' 解释:在8个方向的地图上
  22. '   在地图上两点(x1,y1),(x2,y2) 的距离的最短值是 是 abs(x1-x2) 与 abs(y1-y2)
  23. '  中的较大的一个,而不是 SQR((x1-x2)^2 +(y1-y2)^2) 如下图
  24. '           *  a(1,1)
  25. '           **
  26. '           *** b(3,3)             a 到 b 的距离 是 3-1 =2 而不是 SQR((3-1)^2+(3-1)^2)= SQR(8)
  27. '
  28. '更新内容 改了寻路程序走斜线和对角能穿过的问题    *b     '2004.8.17
  29. ' Download by http://www.codefans.net                                                a*
  30. Option Explicit
  31. Private Type nude_type
  32.     X As Long
  33.     Y As Long
  34.     Father As Long
  35.     D1 As Long
  36.     'D2 As long
  37.     '**********
  38.     d2 As Single
  39.     '**********
  40.     
  41.     Next As Long
  42.     Id As Long
  43. End Type
  44. Public Type P_xy
  45.     X As Long
  46.     Y As Long
  47. End Type
  48. Type Closed_map
  49.     NuDenum As Long
  50.     Mapval As Long
  51. End Type
  52. Private Opened As Long
  53. Public Function FindPath(X As Long, Y As Long, Dx As Long, Dy As Long, ByRef M As Long, ByRef TT() As P_xy, ByRef Desc_Passed_Enable As Boolean) As Boolean
  54.     Dim Nude(6000) As nude_type
  55.     Dim Tmpe(-1 To 500, -1 To 500) As Closed_map
  56.     Dim ISt As Long
  57.     Dim X1 As Long, Y1 As Long
  58.     Dim QQ As Long
  59.     Dim i As Long, j As Long
  60.     
  61.     
  62.     '***************
  63.     '目的地和出发地重合
  64.     If X = Dx And Y = Dy Then
  65.         M = 0
  66.         TT(0).X = Dx
  67.         TT(0).Y = Dy
  68.         FindPath = True: Exit Function
  69.     End If
  70.     '****************
  71.     
  72.     
  73.     X1 = X: Y1 = Y
  74.     Nude(0).X = X: Nude(0).Y = Y: Nude(0).Father = -1: Nude(0).D1 = 0
  75.         
  76.  
  77. '***************************
  78.  'Dim tmpx As long, tmpy As long
  79.  'tmpx = Abs(x1 - dx): tmpy = Abs(y1 - dy)
  80.  'Nude(0).D2 = IIf(tmpx > tmpy, tmpx, tmpy)
  81.      Nude(0).d2 = Sqr((X1 - Dx) ^ 2 + (Y1 - Dy) ^ 2)
  82. '***********************
  83.     Nude(0).Next = -1
  84.     Nude(0).Id = 0: Opened = 0
  85.     Tmpe(X1, Y1).NuDenum = 0
  86.     Tmpe(X1, Y1).Mapval = 1
  87.     Dim Maxnum As Long: Maxnum = 0 '这个数可不能改
  88.     Dim MaxCounts As Long '限制最大搜索范围,加快搜索速度
  89.     MaxCounts = 0
  90.     '*************
  91.     
  92.     '如果 目标正在被包围中(不能到达)就缩小搜索范围节约速度
  93. '    For i = -1 To 1
  94. '        For j = -1 To 1
  95. '            If i = 0 And j = 0 Then
  96. '            Else
  97. '                If Dx + i >= 0 And Dx + i <= Map_Width And Dy + j >= 0 And Dy + j <= Map_Width Then
  98. '                    If Map5(Dx + i, Dy + j) = 0 Then GoTo Begin
  99. '                End If
  100. '            End If
  101. '        Next
  102. '    Next
  103. '    MaxCounts = (Abs(X - Dx) + Abs(Y - Dy)) * 4
  104.     '*******************
  105. Begin:
  106.     Do
  107.         QQ = Getopenednude(Nude())
  108.         ISt = Sub1(Nude(QQ).X, Nude(QQ).Y, Dx, Dy, Tmpe(), Nude(), Maxnum, Desc_Passed_Enable)
  109.         If ISt > 0 Then GoTo FINDs '找到目标
  110.         If Maxnum >= MaxCounts Then
  111.             Exit Do
  112.         End If
  113.     Loop Until Opened = -1
  114.     
  115.     If Maxnum = 0 Then
  116.     '************
  117.     ' 要找的目标紧挨着自己
  118.         M = 0
  119.         TT(0).X = X
  120.         TT(0).Y = Y
  121.         FindPath = True: Exit Function
  122.     '***************
  123.     End If
  124.        '********目标没有找到就选泽一个距离目标最近的地方作为目标
  125.     Dim AA As Long, Lengh As Single
  126.     Dim nn As Long, MM As Long
  127.     Dim iii As Long
  128.     AA = Maxnum
  129.     Lengh = Nude(1).d2
  130.     iii = 1
  131.     nn = Nude(1).X: MM = Nude(1).Y
  132.        
  133.     For i = 1 To AA
  134.         If Lengh > Nude(i).d2 Then
  135.             Lengh = Nude(i).d2
  136.             nn = Nude(i).X: MM = Nude(i).Y
  137.             iii = i
  138.         End If
  139.     
  140.     Next
  141.     Dx = nn: Dy = MM
  142. FINDs:
  143.     Dim l As Long
  144.     AA = iii
  145.     l = 0
  146.     If ISt > 0 Then AA = ISt
  147.     Do
  148.         TT(l).X = Nude(AA).X
  149.         TT(l).Y = Nude(AA).Y
  150.         AA = Nude(AA).Father
  151.         l = l + 1
  152.     Loop Until AA = -1
  153.     M = l - 2
  154.     FindPath = True
  155. End Function
  156. Private Function Sub1(ByRef X As Long, ByRef Y As Long, _
  157. ByRef Dx As Long, ByRef Dy As Long, ByRef tmp() As Closed_map, _
  158. ByRef Nude() As nude_type, ByRef N As Long, _
  159. ByRef Desc_Passed_Enable As Boolean) As Long
  160.     Dim i As Long, j As Long, Fatnum As Long, Mme As Long, _
  161.     M As Long
  162.     Dim aaa As Long, X1 As Long, Y1 As Long, X2 As Long, Y2 As Long
  163.     Dim t As Long
  164.     t = 0
  165.     For i = -1 To 1
  166.         For j = -1 To 1
  167.      '*********仅用于怪物寻找玩家
  168.             If Desc_Passed_Enable = False Then
  169.                 If i <> 0 Or j <> 0 Then
  170.                     If X + i = Dx And Y + j = Dy Then '找到目标
  171.                         Dx = X:  Dy = Y
  172.                         Sub1 = tmp(X, Y).NuDenum
  173.                         Exit Function
  174.                     End If
  175.                 End If
  176.             End If
  177.       '*************
  178.     
  179.             If (i <> 0 Or j <> 0) And Testmap(X, Y, i, j) Then
  180.                 If tmp(X + i, Y + j).Mapval = 1 Then
  181.                     Mme = tmp(X + i, Y + j).NuDenum
  182.                     aaa = tmp(X, Y).NuDenum
  183.                     Fatnum = Nude(aaa).Father
  184.                     If Fatnum = -1 Then
  185.                     Else
  186.                         If Nude(Fatnum).D1 > Nude(Mme).D1 Then Nude(aaa).Father = Mme
  187.                     End If
  188.                 End If
  189.                 If tmp(X + i, Y + j).Mapval = 0 Then
  190.                     M = tmp(X, Y).NuDenum
  191.                     N = N + 1
  192.                     X1 = X + i: Y1 = Y + j
  193.                     tmp(X1, Y1).Mapval = 1
  194.                     tmp(X1, Y1).NuDenum = N
  195.                     Nude(N).X = X1: Nude(N).Y = Y1
  196.                     Nude(N).Father = M
  197.                     Nude(N).D1 = Nude(M).D1 + 1
  198.                     
  199.         '***************************
  200.         'Dim tmpx As long, tmpy As long
  201.         'tmpx = Abs(x1 - dx): tmpy = Abs(y1 - dy)
  202.         'Nude(0).D2 = IIf(tmpx > tmpy, tmpx, tmpy)
  203.                     Nude(N).d2 = Sqr((X1 - Dx) ^ 2 + (Y1 - Dy) ^ 2)
  204.     '***********************
  205.     
  206.              
  207.                     Nude(N).Id = N
  208.                     If Nude(N).d2 = 0 Then '找到目标
  209.                         Sub1 = N
  210.                         Exit Function
  211.                     End If
  212.                     Call InstOPened(Nude(N), Nude())
  213.                     
  214.                 End If
  215.             End If
  216.         
  217.         Next
  218.     Next
  219.    
  220. End Function
  221. Private Sub InstOPened(Mnud As nude_type, Nude() As nude_type)
  222.     Dim Temp2 As Long
  223.     'Dim f As long
  224.     '************
  225.     Dim f As Single
  226.     '**********
  227.     Dim dd As Long
  228.     If Opened = -1 Then
  229.         Mnud.Next = -1
  230.         Opened = Mnud.Id
  231.         Exit Sub
  232.     End If
  233.     f = Mnud.d2
  234.     Temp2 = Opened
  235.     Do
  236.         If f < Nude(Temp2).d2 Then GoTo K1
  237.         dd = Temp2
  238.         Temp2 = Nude(Temp2).Next
  239.     Loop Until Temp2 = -1
  240.     Mnud.Next = -1
  241.     Nude(dd).Next = Mnud.Id
  242.     Exit Sub
  243. K1:
  244.     
  245.     Mnud.Next = Temp2
  246.     If Opened <> Temp2 Then
  247.         Nude(dd).Next = Mnud.Id
  248.     Else
  249.         Opened = Mnud.Id
  250.     End If
  251. End Sub
  252. Private Function Getopenednude(Nude() As nude_type) As Long
  253.     Dim tmp3 As Long
  254.     If Opened = -1 Then
  255.     ' error
  256.     Else
  257.         tmp3 = Opened
  258.         Opened = Nude(tmp3).Next
  259.         Getopenednude = tmp3
  260.     End If
  261. End Function
  262. Private Function Testmap(ByVal X As Long, ByVal Y As Long, i As Long, j As Long)
  263. '  检测地图能不能走
  264. On Error GoTo Errors '如过超出边界 就不能走
  265. '你可以在这里加如其他的限制 ,比如有走的地图上不能有其他的 蚂蚁
  266.  
  267.     If i * j = 0 Then
  268.         If Map.Map3(X + i, Y + j) = 0 And Map.Map4(X + i, Y + j) = 0 And Map.Map5(X + i, Y + j) = 0 Then Testmap = True: Exit Function
  269.     
  270.         If Map.Map4(X + i, Y + j) > 0 Then
  271. '            If Mon(Map4(X + i, Y + j)).HP_生命值 <= 0 Then Testmap = True: Exit Function
  272.         End If
  273.     End If
  274.     If i * j <> 0 Then
  275.         If Map.Map3(X + i, Y + j) = 0 And Map.Map4(X + i, Y + j) = 0 And Map.Map5(X + i, Y + j) = 0 And Map.Map3(X + i, Y) = 0 And Map.Map4(X + i, Y) = 0 And Map.Map5(X + i, Y) = 0 And Map.Map3(X, Y + j) = 0 And Map.Map4(X, Y + j) = 0 And Map.Map5(X, Y + j) = 0 Then Testmap = True: Exit Function
  276.     End If
  277. Errors:
  278.     Testmap = False
  279. End Function