日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简单寻路算法实现

發布時間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单寻路算法实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一直想把塔防游戲的小兵改成不固定路線,這就涉及到尋路,用lua簡單實現了一遍。

一、 構建地圖

local map = { {11,12,13,14,15,16,17,18,19,},{21,22,23,24,25,26,27,28,29,},{31,32,33,34,35,36,37,38,39,},{41,42,43,44,45,46,47,48,49,},{51,52,53,54,55,56,57,58,59,},{61,62,63,64,65,66,67,68,69,},{71,72,73,74,75,76,77,78,79,},{81,82,83,84,85,86,87,88,89,},{91,92,93,94,95,96,97,98,99,},}

就這一個簡單粗暴的表吧,假設是一個 9 * 9 的地圖。上面的值表示地圖中的一個點。

二、 構建節點對象

local function createPoint(x, y, nextPoint, lastPoint)return {x = x, --該節點在地圖中的x坐標y = y, --該節點在地圖中的y坐標value = map[x][y], --該節點在地圖中的值np = nextPoint, --該節點的下一個節點(子節點)lp = lastPoint, --該節點的上一個節點(父節點)} end

因為在計算中我們要紀錄從哪個節點到哪個節點,所以最好以對象為計算單位,找到目標節點之后順著父節點往上查找就可以得到完整路線。

三、 定義變量

尋路的要素: 地圖、障礙、開始節點、目標節點

local endPoint = {4,4} local startPoint = {1,2} local zhangAis = {} local hadGoPoints = {}

endPoint 和 startPoint 就不說了,這里解釋一下zhangAis 和 hadGoPoints (命名比較隨意,輕噴)。

zhangAis : 障礙集合, 保存地圖中無法行走的點。比如 假設地圖上33這個點是障礙,則

zhangAis[33] = true

hadGoPoints : 已經走過的點的集合 如已經走過了 33、34節點則

hadGoPoints[33] = true hadGoPoints[34] = true

為什么要hadGoPoints?參考A*算法,走過的路就不要走第二次了。

四、 尋找下一步可以走的節點

local function checkCanGoNext(x, y)local canGos = {}if x - 1 > 0 and not zhangAis[map[x-1][y]] then table.insert(canGos, {x - 1, y})endif x + 1 < 10 and not zhangAis[map[x + 1][y]] then table.insert(canGos, {x + 1, y})endif y - 1 > 0 and not zhangAis[map[x][y - 1]] then table.insert(canGos, {x , y - 1})endif y + 1 < 10 and not zhangAis[map[x][y + 1]] then table.insert(canGos, {x, y + 1})endlocal function compareDistance(point_1, point_2)local distance_1_x = math.abs(point_1[1] - endPoint[1])local distance_1_y = math.abs(point_1[2] - endPoint[2])local distance_1 = math.sqrt(distance_1_x ^ 2 + distance_1_y ^ 2)local distance_2_x = math.abs(point_2[1] - endPoint[1])local distance_2_y = math.abs(point_2[2] - endPoint[2])local distance_2 = math.sqrt(distance_2_x ^ 2 + distance_2_y ^ 2)return distance_1 < distance_2endtable.sort(canGos, compareDistance)return canGos end

原理簡單,就是根據當前節點的x y 坐標計算出上下左右的四個點。這里加了一個排序,根據計算出的節點和目標節點距離進行排序,距離越近越排在前面。更近說明走這一步更容易找到目標節點,簡單粗暴的預測。

五、 判斷是否找到目標節點

local function checkEnd(point)if point.x == endPoint[1] and point.y == endPoint[2] then return trueend end

很簡單,比較 x 和 y。 endPoint是全局變量。

六、 找到目標節點后的處理

local function handleEnd(point)local nowPoint = pointlocal rd = {}while nowPoint.lp doprint(nowPoint.value)table.insert(rd, 1, nowPoint.value)nowPoint = nowPoint.lpendreturn rd end

找到目標節點后 根據父節點輸出完整路線并返回。此時的point就是目標節點。

七、尋路

local function getNextPoint(point)hadGoPoints[point.value] = truelocal nexts = checkCanGoNext(point.x, point.y)for _, v in ipairs(nexts) do local np = createPoint(v[1], v[2], _, point)if not hadGoPoints[np.value] thenpoint.np = npif true == checkEnd(point.np) then return handleEnd(point.np)elselocal rd = getNextPoint(point.np) if rd thenreturn rdend endendend end

重頭戲,短短十幾行代碼,整個尋路的靈魂。先不解釋吧,看一下結果。

七、測試

隨便定義一些障礙和調用尋路

zhangAis[32] = true zhangAis[23] = true zhangAis[24] = true zhangAis[25] = true zhangAis[26] = true zhangAis[27] = true zhangAis[28] = true zhangAis[29] = true zhangAis[45] = true zhangAis[34] = true zhangAis[42] = true zhangAis[52] = true zhangAis[62] = true zhangAis[72] = true zhangAis[82] = true zhangAis[54] = true zhangAis[73] = true zhangAis[75] = true zhangAis[84] = true zhangAis[66] = true zhangAis[58] = true --開始尋路 local start = createPoint(startPoint[1],startPoint[2]) local rd = getNextPoint(start) printTable(rd)

為了方便觀察 我們把上面的障礙 用**表示:

{11,12,13,14,15,16,17,18,19,}, {21,22,**,**,**,**,**,**,**,}, {31,**,33,**,35,36,37,38,39,}, {41,**,43,44,**,46,47,48,49,}, {51,**,53,**,55,56,57,**,59,}, {61,**,63,64,65,**,67,68,69,}, {71,**,**,74,**,76,77,78,79,}, {81,**,83,**,85,86,87,88,89,}, {91,92,93,94,95,96,97,98,99,},

好了目標就是從節點12繞過障礙找到一條路線到節點44。

printTable得到路線是

{22 21 31 41 51 61 71 81 91 92 93 94 95 85 86 76 77 67 57 56 55 65 64 63 53 43 44}

開始是點節12, 第一步節點22,最后節點44,看起來沒有錯!

看下在游戲中的效果如何:

xc2

依托障礙和建塔構建路線,最后一步堵住去路,小兵尋找到新路線!

八、優點

這個算法的優點是:不用判斷是否遍歷完,如果程序完成時rd沒有值,那就是無路可走。
感興趣的同學可以自己修改障礙測試一下。

九、缺點

有時候找到了一條路徑,但未必是最優路徑。因為一旦找到目標節點就返回成功了。可以進行優化直到找到最優路徑。另外當地圖很大時就比較困難了。

十、解析

關于getNextPoint函數,其實是不斷地遞歸查找。但是并不是亂找,按距離的優先級進行遞歸,所以一般能夠很快找到目標節點。大家復制代碼自行測試吧!

感謝瀏覽!

如果你有興趣請支持一波我們的游戲:

塔防海岸線 下載路線1

總結

以上是生活随笔為你收集整理的简单寻路算法实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。