所以我试图让角色在瓷砖地图上走动,使用下面的代码。 tilePath
返回其目标路径中的tile矢量,然后它们的代码使它们前进到矢量中的下一个tile。问题是,当他们到达一个角落时,他们会试图过早地移动它并最终卡在墙上。
白色方块是可步行的方块,灰色是墙,红色是字符。如果角色到达角落可行走的瓷砖,它会过早地绕墙移动,从而被它阻挡。它们通常会最终制作它,但非常明显的是它们已经卡在墙上了一段时间。
std::vector<Tile*> TileMap::tilePath(Tile *p_start, Tile *p_end)
{
std::vector<Tile*> path;
std::vector<Tile*> open;
std::map<uint64_t, Tile*> closed;
p_start->previousTile = p_start;
p_start->g = 0;
p_start->h = 0;
p_start->f = 0;
float g, h, f, cost;
Tile* current = p_start;
Tile* previous = nullptr;
while(current != p_end) {
current->m_sprite.setColor(sf::Color(255,255,255,255));
for(auto neighbor : getNeighbors(current))
{
if(neighbor == current) continue;
if(!(neighbor->m_walkable)) continue;
previous = current;
if(tileTrace(current->previousTile, neighbor)) {
cost = manhattan(current->previousTile, neighbor);
g = current->previousTile->g + cost;
h = manhattan(neighbor, p_end);
f = g + h;
previous = current->previousTile;
} else {
cost = ((current->m_coordinates.x != neighbor->m_coordinates.x) && (current->m_coordinates.y != neighbor->m_coordinates.y)) ? 1.4 : 1;
g = current->g + cost;
h = manhattan(neighbor, p_end);
f = g + h;
}
if(std::find(open.begin(), open.end(), neighbor) != open.end() ||
closed.find(neighbor->key()) != closed.end()) {
if(neighbor->f > f) {
neighbor->f = f;
neighbor->g = g;
neighbor->h = h;
neighbor->previousTile = previous;
}
} else {
neighbor->f = f;
neighbor->g = g;
neighbor->h = h;
neighbor->previousTile = previous;
for(auto i = open.begin(); i != open.end(); i++)
{
if(neighbor->f < (*i)->f) {
open.insert(i, neighbor);
break;
}
}
open.push_back(neighbor);
}
}
closed[current->key()] = current;
if(open.size() == 0) {
return std::vector<Tile*>();
}
current = open.front();
open.erase(open.begin());
}
current = p_end;
path.insert(path.begin(), current);
while(current->previousTile != p_start)
{
current->m_sprite.setColor(sf::Color(255,0,0,255));
path.insert(path.begin(), current->previousTile);
current = current->previousTile;
}
return path;
}
bool TileMap::tileTrace(Tile* p_start, Tile* p_end)
{
int sx = p_start->m_coordinates.x;
int sy = p_start->m_coordinates.y;
int ex = p_end->m_coordinates.x;
int ey = p_end->m_coordinates.y;
int dx = fabsf(ex - sx);
int dy = fabsf(ey - sy);
int _x = sx, _y = sy;
int x_inc = (ex > sx) ? 1 : -1;
int y_inc = (ey > sy) ? 1 : -1;
int error = dx - dy;
for(int n = dx + dy; n > 0; n--) {
Tile& t = m_tiles[_y * m_width + _x];
if(!(t.m_walkable)) return false;
if(error < 0) {
_y += y_inc;
error += dx;
} else {
_x += x_inc;
error -= dy;
}
}
return true;
}
我能做些什么才能让它变得更顺畅?我宁愿这些角色也不会从墙上反弹。
更新
我已经添加了这个内容,以查看角色是朝着还是远离它的#34;&#34;在#34;上。认为它在角落周围获得角色更有效,但它有时会产生一些奇怪的动作。
sf::Vector2f d = start->m_position - p_object->m_position;
float dot = p_object->m_velocity.x * d.x + p_object->m_velocity.y * d.y;
if(dot > 0) {
path.insert(path.begin(), start);
}