public override void Handle(float t, float dt) { var npcTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(entityId); var npcBody = (CBody)Game1.Inst.Scene.GetComponentFromEntity <CBody>(entityId); var aiComponent = (CAI)Game1.Inst.Scene.GetComponentFromEntity <CAI>(entityId); var flock = (CFlock)Game1.Inst.Scene.GetComponentFromEntity <CFlock>(aiComponent.Flock); var rotationSpeed = Math.Min(1.8f * dt, 1); var movementSpeed = dt * flock.PreferredMovementSpeed * 5; var closestEnemyDistance = float.MaxValue; var closestEnemyId = -1; CTransform closestEnemyTransform = null; foreach (var player in Game1.Inst.Scene.GetComponents <CInput>()) { if (!Game1.Inst.Scene.EntityHasComponent <CBody>(player.Key)) { continue; } var playerTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(player.Key); var positionDiff = playerTransform.Position - npcTransform.Position; float distance = (float)Math.Sqrt(Math.Pow(positionDiff.X, 2) + 0 + Math.Pow(positionDiff.Z, 2)); if (closestEnemyDistance > distance) { closestEnemyDistance = distance; closestEnemyId = player.Key; closestEnemyTransform = playerTransform; } } if (closestEnemyId == -1) { return; } Vector3 dest = Vector3.Normalize(closestEnemyTransform.Position - npcTransform.Position); var source = Vector3.Backward; var goalQuat = PositionalUtil.GetRotation(source, dest, Vector3.Up); var startQuat = npcTransform.Rotation.Rotation; var dQuat = Quaternion.Lerp(startQuat, goalQuat, rotationSpeed); dQuat.X = 0; dQuat.Z = 0; npcTransform.Rotation = Matrix.CreateFromQuaternion(dQuat); // move forward in set direction npcBody.Velocity.X = (movementSpeed * npcTransform.Rotation.Forward).X; npcBody.Velocity.Z = (movementSpeed * npcTransform.Rotation.Forward).Z; }
public override void Handle(float t, float dt) { var aiComponent = (CAI)Game1.Inst.Scene.GetComponentFromEntity <CAI>(entityId); var npcTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(entityId); var npcBody = (CBody)Game1.Inst.Scene.GetComponentFromEntity <CBody>(entityId); var flock = (CFlock)Game1.Inst.Scene.GetComponentFromEntity <CFlock>(aiComponent.Flock); var flockTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(aiComponent.Flock); var rotationSpeed = 1.0f * dt; var movementSpeed = dt * flock.PreferredMovementSpeed; var separation = Separation(npcTransform.Position, flock); var alignment = flock.AvgVelocity / flock.Members.Count; var cohesion = flock.Centroid - npcTransform.Position; // try to make flock stay at the same position cohesion = flockTransform.Position - npcTransform.Position; cohesion.Y = 0; // factors to enchance certain aspects of flocking behavior separation *= flock.SeparationFactor; alignment *= flock.AlignmentFactor; cohesion *= flock.CohesionFactor; // add all directions and then normalize to get a goal direction var rot = separation + cohesion + alignment; rot.Normalize(); var source = Vector3.Forward; var goalQuat = PositionalUtil.GetRotation(source, rot, Vector3.Up); // add a little randomness to goal direction var randomDirection = (float)rnd.NextDouble() * 0.25f; goalQuat.Y += randomDirection; var startQuat = npcTransform.Rotation.Rotation; var dQuat = Quaternion.Lerp(startQuat, goalQuat, rotationSpeed); dQuat.Normalize(); dQuat.X = 0; dQuat.Z = 0; // set rotation to interpolated direction npcTransform.Rotation = Matrix.CreateFromQuaternion(dQuat); // move forward in set direction npcBody.Velocity.X = (movementSpeed * npcTransform.Rotation.Forward).X; npcBody.Velocity.Z = (movementSpeed * npcTransform.Rotation.Forward).Z; }
public override void Handle(float t, float dt) { var rotationSpeed = Math.Min(0.65f * dt, 1); var stopSpeed = 1 - dt; var npcTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(entityId); var npcBody = (CBody)Game1.Inst.Scene.GetComponentFromEntity <CBody>(entityId); var closestEnemyDistance = float.MaxValue; var closestEnemyId = -1; foreach (var player in Game1.Inst.Scene.GetComponents <CInput>()) { if (!Game1.Inst.Scene.EntityHasComponent <CBody>(player.Key)) { continue; } var playerTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(player.Key); var positionDiff = playerTransform.Position - npcTransform.Position; float distance = (float)Math.Sqrt(Math.Pow(positionDiff.X, 2) + 0 + Math.Pow(positionDiff.Z, 2)); if (closestEnemyDistance > distance) { closestEnemyDistance = distance; closestEnemyId = player.Key; } } var enemyTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(closestEnemyId); Vector3 dest = Vector3.Normalize(enemyTransform.Position - npcTransform.Position); var source = Vector3.Forward; var goalQuat = PositionalUtil.GetRotation(source, dest, Vector3.Up); var startQuat = npcTransform.Rotation.Rotation; var dQuat = Quaternion.Lerp(startQuat, goalQuat, rotationSpeed); dQuat.X = 0; dQuat.Z = 0; npcTransform.Rotation = Matrix.CreateFromQuaternion(dQuat); npcBody.Velocity *= stopSpeed; }