bool AStarPathFind::CanDiagonalWalk(const ASTAR_NODE* pNode1, const ASTAR_NODE* pNode2) { ASTAR_NODE* pNodeNear1 = GetNode(pNode1->nX, pNode2->nY); ASTAR_NODE* pNodeNear2 = GetNode(pNode2->nX, pNode1->nY); if (CanWalk(pNodeNear1->nX, pNodeNear1->nY) && CanWalk(pNodeNear2->nX, pNodeNear2->nY)) { return true; } return false; }
bool Game_Player::GetOffVehicle() { if (InAirship()) { if (!AirshipLandOk(x, y)) return false; } else { int front_x = Game_Map::XwithDirection(x, direction); int front_y = Game_Map::YwithDirection(y, direction); if (!CanWalk(front_x, front_y)) return false; } Game_Map::GetVehicle((Game_Vehicle::Type) vehicle_type)->GetOff(); if (InAirship()) direction = RPG::EventPage::Direction_down; else { // TODO // ForceMoveForward(); opacity = 255; } vehicle_getting_off = true; move_speed = 4; through = false; Game_System::BgmPlay(walking_bgm); return true; }
bool Game_Player::GetOffVehicle() { if (!InAirship()) { int front_x = Game_Map::XwithDirection(GetX(), GetDirection()); int front_y = Game_Map::YwithDirection(GetY(), GetDirection()); if (!CanWalk(front_x, front_y)) return false; } GetVehicle()->GetOff(); if (!InAirship()) { location.unboarding = true; Unboard(); through = true; MoveForward(); through = false; } return true; }
bool AStarPathFind::FloydCrossAble(const ASTAR_POINT& oPos1, const ASTAR_POINT& oPos2) { int nPosX1 = oPos1.nX; int nPosY1 = oPos1.nY; int nPosX2 = oPos2.nX; int nPosY2 = oPos2.nY; if (nPosX1 == nPosX2 && nPosY1 == nPosY2) { return false; } float fPosCenterX1 = nPosX1 + 0.5f; float fPosCenterY1 = nPosY1 + 0.5f; float fPosCenterX2 = nPosX2 + 0.5f; float fPosCenterY2 = nPosY2 + 0.5f; int nLoopDir = 1; if (abs((int)(nPosX2 - nPosX1)) <= abs((int)(nPosY2 - nPosY1))) { nLoopDir = 2; } float fDistX = fPosCenterX1 - fPosCenterX2; fDistX = fDistX == 0 ? 1 : fDistX; float fA = (fPosCenterY1 - fPosCenterY2) / fDistX; float fB = fPosCenterY1 - fA * fPosCenterX1; if (nLoopDir == 1) { ASTAR_NODE* tNodeList[4]; float fLoopStart = (float)XMath::Min(nPosX1, nPosX2); float fLoopStartCenter = fLoopStart + 0.5f; float fLoopEnd = (float)XMath::Max(nPosX1, nPosX2); for (float i = fLoopStart; i <= fLoopEnd; i++) { if (i == fLoopStart) { i += 0.5f; } float fPosY = 0; if (fPosCenterX1 == fPosCenterX2) { assert(false); return false; } else if (fPosCenterY1 == fPosCenterY2) { fPosY = fPosCenterY1; } else { fPosY = fA * i + fB; } int nCount = GetNodesUnderPoint(i, fPosY, tNodeList); for (int n = nCount - 1; n >= 0; n--) { if (!CanWalk(tNodeList[n]->nX, tNodeList[n]->nY)) { return false; } } if (i == fLoopStartCenter) { i -= 0.5f; } } } else { ASTAR_NODE* tNodeList[4]; float fLoopStart = (float)XMath::Min(nPosY1, nPosY2); float fLoopStartCenter = fLoopStart + 0.5f; float fLoopEnd = (float)XMath::Max(nPosY1, nPosY2); for (float i = fLoopStart; i <= fLoopEnd; i++) { if (i == fLoopStart) { i += 0.5f; } float fPosX = 0; if (fPosCenterX1 == fPosCenterX2) { fPosX = fPosCenterX1; } else if (fPosCenterY1 == fPosCenterY2) { assert(false); return false; } else { fPosX = (i - fB) / fA; } int nCount = GetNodesUnderPoint(fPosX, i, tNodeList); for (int n = nCount - 1; n >= 0; n--) { if (!CanWalk(tNodeList[n]->nX, tNodeList[n]->nY)) { return false; } } if (i == fLoopStartCenter) { i -= 0.5f; } } } return true; }
int AStarPathFind::PathFind(int nStartX, int nStartY, int nEndX, int nEndY, std::list<Point>& oListPath) { if (m_poMapConf == NULL) { return -1; } nStartX = XMath::Max(0, XMath::Min(nStartX, (int)m_poMapConf->nPixelWidth - 1)); nStartY = XMath::Max(0, XMath::Min(nStartY, (int)m_poMapConf->nPixelHeight - 1)); nEndX = XMath::Max(0, XMath::Min(nEndX, (int)m_poMapConf->nPixelWidth - 1)); nEndY = XMath::Max(0, XMath::Min(nEndY , (int)m_poMapConf->nPixelHeight - 1)); int nSX = nStartX / gnUnitWidth; int nSY = nStartY / gnUnitHeight; int nEX = nEndX / gnUnitWidth; int nEY = nEndY / gnUnitHeight; if (nSX == nEX && nSY == nEY) { return -2; } if (!CanWalk(nSX, nSY) || !CanWalk(nEX, nEY)) { return -3; } m_uSearchVersion++; ASTAR_NODE* pNode = GetNode(nSX, nSY); ASTAR_NODE* pEnd = GetNode(nEX, nEY); if (pNode == NULL || pEnd == NULL) { return -4; } m_OpenedList.Clear(); pNode->bOpened = true; m_OpenedList.Push(pNode); static int tDir[8][2] = { { -1, 1 }, { -1, 0 }, { -1, -1 }, { 0, 1 }, { 0, -1 }, { 1, 1 }, { 1, 0 }, { 1, -1 } }; while (!pEnd->bClosed && m_OpenedList.Size() > 0) { pNode = m_OpenedList.Min(); m_OpenedList.Remove(pNode); pNode->bOpened = false; pNode->bClosed = true; ASTAR_NODE* pTmpNode = NULL; for (int i = 0; i < 8; i++) { int nX = pNode->nX + tDir[i][0]; int nY = pNode->nY + tDir[i][1]; pTmpNode = GetNode(nX, nY); if (pTmpNode == NULL || !CanWalk(nX, nY)) { continue; } if (!CanDiagonalWalk(pNode, pTmpNode)) { continue; } int nG = pNode->nG + GetG(pNode->nX, pNode->nY, pTmpNode->nX, pTmpNode->nY); int nH = GetH(pTmpNode->nX, pTmpNode->nY, pEnd->nX, pEnd->nY); int nF = nG + nH; if (pTmpNode->bOpened || pTmpNode->bClosed) { if (pTmpNode->nKey > nF) { pTmpNode->nG = nG; pTmpNode->nH = nH; pTmpNode->nKey = nF; pTmpNode->pParent = pNode; if (pTmpNode->bOpened) { m_OpenedList.Update(pTmpNode); } } } else { pTmpNode->nG = nG; pTmpNode->nH = nH; pTmpNode->nKey = nF; pTmpNode->pParent = pNode; m_OpenedList.Push(pTmpNode); pTmpNode->bOpened = true; } } } if (!pEnd->bClosed) { return -5; } m_oTmpListPath.clear(); ASTAR_NODE* pTarNode = pNode; //XLog(LEVEL_DEBUG,"Robot path0:"); while (pTarNode != NULL) { ASTAR_POINT oASPos; oASPos.nX = pTarNode->nX; oASPos.nY = pTarNode->nY; //XLog(LEVEL_DEBUG, "[%d,%d] ", oASPos.nX, 35 - oASPos.nY); m_oTmpListPath.push_front(oASPos); pTarNode = pTarNode->pParent; } //XLog(LEVEL_DEBUG,"\n"); if (m_oTmpListPath.size() > 2) { Floyd(m_oTmpListPath); } ASLITER iter = m_oTmpListPath.begin(); ASLITER iter_end = m_oTmpListPath.end(); //XLog(LEVEL_DEBUG,"Robot path1:"); for (; iter != iter_end; iter++) { ASTAR_POINT& oPos = *iter; int nPosX = (int)((oPos.nX + 0.5f) * gnUnitWidth); int nPosY = (int)((oPos.nY + 0.5f) * gnUnitHeight); oListPath.push_back(Point(nPosX, nPosY)); //XLog(LEVEL_DEBUG,"[%d,%d](%d,%d) ", nPosX, nPosY, oPos.nX, 35-oPos.nY); } //XLog(LEVEL_DEBUG,"\n"); return 0; }