bool callLuafunc(const char* luatable, const char* funcname, const int& i, const int& j, int luaRefIdx)
{
lua_State* L = LuaEngine::getInstance()->getLuaStack()->getLuaState();
if (NULL == L)
{
return false;
}
lua_settop(L, 1); //清理栈 很重要 否则会堆栈溢出
//lua_getglobal(L, luatable);
//if (!lua_istable(L, -1))
//{
// return false;
//}
//lua_pushstring(L, funcname);
//lua_gettable(L, -2);
//if (!lua_isfunction(L, -1))
//{
// assert(0 && funcname);
//}
lua_getref(L, luaRefIdx);
//printf("stack size:%d,%d\n", lua_gettop(L), lua_type(L, -1));
//lua_getglobal(L, "add");
//参数从左到右压栈
lua_pushinteger(L, i);
lua_pushinteger(L, j);
lua_pcall(L, 2, 1, 0);
bool result = lua_toboolean(L, -1);
return result;
}
VEC_OUT_PATH AStar::FindPath(int bi, int bj, int ei, int ej)
{
VEC_OUT_PATH vecPath;
lua_State* L = LuaEngine::getInstance()->getLuaStack()->getLuaState();
if (NULL == L)
{
return vecPath;
}
lua_settop(L, 0); //清理栈 很重要 否则会堆栈溢出
lua_getglobal(L, "g_isValidGird");
luaRefIdx = lua_ref(L, true);
m_vecAllPath.clear();
//vecPath.clear();
SNavMeshGird sStartNode;
SNavMeshGird sEndNode;
sStartNode.row = bi;
sStartNode.col = bj;
sEndNode.row = ei;
sEndNode.col = ej;
Vec2 v3End(sEndNode.row, sEndNode.col);
m_vecOpen.clear();
m_mapOpen.clear();
m_vecClose.clear();
//计算起点终点格子索引
//PosToGird(v3Start.x, v3Start.z, sStartNode.row, sStartNode.col);
//PosToGird(v3End.x, v3End.z, sEndNode.row, sEndNode.col);
//再lua层就过滤掉 检测到超了范围 和 点到掩码 直接不进入该函数
//if (!IsValidGird(sStartNode.row, sStartNode.col) ||
// !IsValidGird(sEndNode.row, sEndNode.col))
//{
// return vecPath;
//}
//评估起点到终点的h值跟g值
sStartNode.h = CountH(&sStartNode, &sEndNode);
sStartNode.g = sStartNode.h + sStartNode.g;
m_vecOpen.push_back(&sStartNode);
m_mapOpen[MakeKey(sStartNode.row, sStartNode.col)] = &sStartNode;
SNavMeshGird* pNode = NULL;
bool bFind = false;
while (m_vecOpen.size() > 0)
{
pNode = m_vecOpen[0];
//找到
if (pNode->row == sEndNode.row && pNode->col == sEndNode.col)
{
bFind = true;
break;
}
//8方向
CheckMove(pNode->row + 1, pNode->col, pNode, &sEndNode, GIRD_HEIGHT);//上
CheckMove(pNode->row, pNode->col - 1, pNode, &sEndNode, GIRD_WIDTH);//左
CheckMove(pNode->row - 1, pNode->col, pNode, &sEndNode, GIRD_HEIGHT);//下
CheckMove(pNode->row, pNode->col + 1, pNode, &sEndNode, GIRD_WIDTH);//右
CheckMove(pNode->row + 1, pNode->col - 1, pNode, &sEndNode, GIRD_DIAGONAL); //左上
CheckMove(pNode->row - 1, pNode->col + 1, pNode, &sEndNode, GIRD_DIAGONAL); //右下
CheckMove(pNode->row - 1, pNode->col - 1, pNode, &sEndNode, GIRD_DIAGONAL); //左下
CheckMove(pNode->row + 1, pNode->col + 1, pNode, &sEndNode, GIRD_DIAGONAL); //右上
//添加到关闭列表 并 从开启列表删除
m_vecClose[MakeKey(pNode->row, pNode->col)] = pNode;
m_vecOpen.erase(m_vecOpen.begin());
//剩下的的点按f值排序
std::sort(m_vecOpen.begin(), m_vecOpen.end(), CompareGird);
}
if (bFind)
{
//生成路径
std::deque deqGIRD;
for (SNavMeshGird* pCur = pNode; pCur != NULL; pCur = pCur->pre)
{
deqGIRD.push_front(pCur);
}
for (int i = 0; i < deqGIRD.size(); ++i)
{
int x, y;
////由格子反推格子中心点坐标
x = deqGIRD[i]->row;
y = deqGIRD[i]->col;
Vec2 v3Pos(deqGIRD[i]->row, deqGIRD[i]->col);
m_vecAllPath.push_back(Vec2(x, y));
if (vecPath.size() >= 2)
{
int preIndex = vecPath.size() - 1;
int prepreIndex = vecPath.size() - 2;
//合并相同方向的路径
float fPreOffsetX = vecPath[preIndex].x - vecPath[prepreIndex].x;
float fPreOffsetY = vecPath[preIndex].y - vecPath[prepreIndex].y;
float fCurOffsetX = v3Pos.x - vecPath[preIndex].x;
float fCurOffsetY = v3Pos.y - vecPath[preIndex].y;
if (fPreOffsetX == fCurOffsetX && fPreOffsetY == fCurOffsetY)
{
vecPath[preIndex].x = v3Pos.x;
vecPath[preIndex].y = v3Pos.y;
continue;
}
}
vecPath.push_back(Vec2(x, y));
//最后一个直接添加目的地点
if (i == deqGIRD.size() - 1)
{
//vecPath.push_back(v3End);
break;
}
}
//第一个点是起点 移除
if (deqGIRD.front()->row == sStartNode.row &&
deqGIRD.front()->col == sStartNode.col)
{
vecPath.erase(vecPath.begin());
m_vecAllPath.erase(m_vecAllPath.begin());
}
}
//寻路完毕 释放内存
for (auto& it : m_vecOpen)
{
if (it->col == sStartNode.col &&
it->row == sStartNode.row)
{
continue;
}
delete it;
}
for (auto& it : m_vecClose)
{
if (it.second->col == sStartNode.col &&
it.second->row == sStartNode.row)
{
continue;
}
delete it.second;
}
m_vecOpen.clear();
m_vecClose.clear();
return vecPath;
}