我的寻路中使用luaL_ref lua_rawgeti

2018-12-08  本文已影响0人  人气小哥

    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<SNavMeshGird*> 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;
    }
上一篇下一篇

猜你喜欢

热点阅读