I am making a 2d soccer game, all players move in 8 directions, so I need to convert AI steering behavior(like arrive and pursuit) into 8 directions.
Here are three example situations:
Player(now is at point A) set target To point B, we could not directly move in direction(B - A), player need to first move to point C in horizontal or vertical, then move in 45 degree to reach target point.
Consider in my game there is no steering behavior accumulation, which means, at any time , only have one function to affect player movement(arrive or pursuit), so I first make convert code in arrive function, because pursuit actually call arrive either.
Here is pseudo-code:
void RSAIController::Init()
{
...
m_vDirectionArray[0] = CCPoint(1.f, 0.f);
m_vDirectionArray[1] = CCPoint(0.7071f, 0.7071f);
m_vDirectionArray[2] = CCPoint(0.f, 1.f);
m_vDirectionArray[3] = CCPoint(-0.7071f, 0.7071f);
m_vDirectionArray[4] = CCPoint(-1.f, 0.f);
m_vDirectionArray[5] = CCPoint(-0.7071f, -0.7071f);
m_vDirectionArray[6] = CCPoint(0.f, -1.f);
m_vDirectionArray[7] = CCPoint(0.7071f, -0.7071f);
}
//called in arrive method, then use m_vMoveDirection as speed direction
void RSAIController::ConvertTo8Directional()
{
int idx = -1;
float maxValue = -MaxFloat;
CCPoint direction = m_vTarget - m_pPlayer->Pos();
//do this because in cocos2d normalize zero vector will return (1, 0)
//which is not the expected result,so I avoid it manually
if(!VIsZero(direction))
direction = direction.normalize();
for(int i = 0; i < 8; ++i)
{
float dotValue = m_vDirectionArray[i].dot(direction);
if(dotValue > maxValue)
{
maxValue = dotValue;
idx = i;
}
}
m_vMoveDirection = m_vDirectionArray[idx];
}
Then I am thinking 8-directional AI movement is pretty common in old nes game, like "Nintendo World Cup". Does anyone used to meet this problem or have any articles related to this?
UPDATE: I have update the code in @Json advice, but still got the errors I met before.
1.Actually player will change direction in 22.5 degree not 45 degree. I need player move on the diagonals when the degree is just reach 45.
2.When player move on the diagonals, the player will keep shaking. For example, in situation 1, when player start to move from C to B in first frame, player decide to move in perfect 45 degree, but player can not reach precise point C because "distance from A to C" has small error to "player speed(constant) * move time from A to C" , this will cause next frame player probably run in horizontal direction, again and again..
Do I need to check when the last frame that arrive at C, then just make player at the precise point C manually to avoid this error, or there has any other trick to fix this?