briefly, this is the overall look and feel of my game:
I have a player and I have an enemy in my map. i tried to learn collision from SaladRaider Youtube channel. collision using chasing method works fine but because of adding Chase and Wander behaviour i implement MSDN Sample on my project instead of the previous simple chasing method. everything works correctly except collision detection for my enemy. when the enemy collides with wall, it just stop at there. this is the code for my collision:
the Collision function :
public bool Collision(Vector2 pos, Obj obj)
{
Rectangle newArea = new Rectangle(area.X, area.Y, area.Width, area.Height);
newArea.X += (int)pos.X;
newArea.Y += (int)pos.Y;
foreach (Obj o in Items.objList)
{
if (o.GetType() == obj.GetType() && o.solid)
if (o.area.Intersects(newArea))
return true;
}
return false;
}
and my Checking collision function for wander behaviour:
public void WanderPushTo(float pix, float dir) //pix is speed, dir is direction
{
float newX = (float)Math.Cos(dir);
float newY = (float)Math.Sin(dir);
newX *= pix;
newY *= pix;
if (!Collision(new Vector2(newX, newY), new Wall(Vector2.Zero)))
{
float MYnewX = (float)Math.Cos(dir);
float MYnewY = (float)Math.Sin(dir);
enemyPosition.X += pix * (float)MYnewX;
enemyPosition.Y += pix * (float)MYnewY;
}
else if (enemyState == enemyAiState.Wander)
{
float MYnewX = (float)Math.Cos(-dir);
float MYnewY = (float)Math.Sin(-dir);
enemyPosition.X += pix * (float)MYnewX;
enemyPosition.Y += pix * (float)MYnewY;
}
}
as you see, i just tried to make the direction as negative when it has a collision with wall ( and the reason is when my enemy was collides with wall, it just stop at that place and doesn't move. i added that "else if" to solve the issue. now it just trace the wall instead of stopping at that position). but unfortunately it just solve my issue when i collide with wall from up and down. it doesn't work when i collide with wall from left and right. to solve this issue, i think i have to turn the pix as negative instead of dir when my enemy collides with wall from left or right. but i don't know how i can check whether my enemy collides from left or right. (fyi, on chasing method, it works without any issue, because the direction is always on the player. but in wander, the direction is random. that's why it doesn't work) do you have any suggestion how to check whether the enemy collides from left or right of the wall ? this is my Chase and Wander Update function:
public void UpdateEnemy(Vector2 playerPosition)
{
// First we have to use the current state to decide what the thresholds are
// for changing state, as described in the doc.
float enemyChaseThreshold = enemyChaseDistance;
float enemyCaughtThreshold = enemyCaughtDistance;
if (enemyState == enemyAiState.Wander)
{
enemyChaseThreshold -= enemyHysteresis / 2;
}
else if (enemyState == enemyAiState.Chasing)
{
enemyChaseThreshold += enemyHysteresis / 2;
enemyCaughtThreshold -= enemyHysteresis / 2;
}
else if (enemyState == enemyAiState.Caught)
{
enemyCaughtThreshold += enemyHysteresis / 2;
}
float distanceFromPlayer = Vector2.Distance(enemyPosition, playerPosition);
if (distanceFromPlayer > enemyChaseThreshold)
{
enemyState = enemyAiState.Wander;
}
else if (distanceFromPlayer > enemyCaughtThreshold)
{
enemyState = enemyAiState.Chasing;
}
else
{
enemyState = enemyAiState.Caught;
}
// Third, once we know what state we're in, act on that state.
float currentEnemySpeed;
if (enemyState == enemyAiState.Chasing)
{
ViewDirection = enemyOrientation = TurnToFace(enemyPosition, playerPosition, enemyOrientation,
enemyTurnSpeed);
currentEnemySpeed = MaxEnemySpeed;
}
else if (enemyState == enemyAiState.Wander)
{
Wander(enemyPosition, ref tankWanderDirection, ref enemyOrientation,
enemyTurnSpeed);
currentEnemySpeed = .25f * MaxEnemySpeed;
}
else
{
currentEnemySpeed = 0.0f;
}
WanderPushTo(currentEnemySpeed, enemyOrientation);
}
and my Wander function :
private void Wander(Vector2 position, ref Vector2 wanderDirection,
ref float orientation, float turnSpeed)
{
wanderDirection.X +=
MathHelper.Lerp(-.25f, .25f, (float)random.NextDouble());
wanderDirection.Y +=
MathHelper.Lerp(-.25f, .25f, (float)random.NextDouble());
if (wanderDirection != Vector2.Zero)
{
wanderDirection.Normalize();
}
orientation = TurnToFace(position, position + wanderDirection, orientation,
.15f * turnSpeed);
float distanceFromScreenCenter = Vector2.Distance(Game1.screenCenter, position);
float MaxDistanceFromScreenCenter =
Math.Min(Game1.screenCenter.Y, Game1.screenCenter.X);
float normalizedDistance =
distanceFromScreenCenter / MaxDistanceFromScreenCenter;
float turnToCenterSpeed = .7f * normalizedDistance * normalizedDistance *
turnSpeed;
orientation = TurnToFace(position, Game1.screenCenter, orientation,
turnToCenterSpeed);
ViewDirection = orientation;
}