/// <summary> /// Atack steering behavior /// </summary> /// <param name="caller">Game object which calles atack SB</param> /// <param name="target">Target of the attack</param> /// <returns>Force acting on caller</returns> public static Vector3 Attack(Fighter caller, AlienCraft target, List<Fighter> friends) { float minimalDistanceToTargetSquared = 5.0f * 5.0f; float shootingDistanceSquared = 15.0f * 15.0f; float maximalDistaneToTargetSquared = 30.0f * 30.0f; // if you're not escaping if (!caller.IsEscaping) { Vector3 seekingForce = SeekWithSeparation(caller, target.Position, friends); Vector3 separationForce = Vector3.Zero; // if you're to close start escaping if (Vector3.DistanceSquared(caller.Position, target.Position) < minimalDistanceToTargetSquared) { caller.IsEscaping = true; } // if you're in the shooting range slow down to minimum if (Vector3.DistanceSquared(caller.Position, target.Position) < shootingDistanceSquared) { caller.Velocity = Vector3.Zero; } return seekingForce + separationForce; } // if you're escaping else { // if you're far enough start shooting once again if (Vector3.DistanceSquared(caller.Position, target.Position) > maximalDistaneToTargetSquared) { caller.IsEscaping = false; } return Flee(caller, target.Position); } }
public MainScene(WarGame game) : base(game) { // creating post render target with 24-bit depth PresentationParameters pp = game.Graphics.GraphicsDevice.PresentationParameters; postTarget = new RenderTarget2D(game.Graphics.GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, false, game.Graphics.GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24); // creating objects used by environment shader alienBaseEnvironmentRenTarget = new RenderTargetCube(game.Graphics.GraphicsDevice, 256, false, game.Graphics.GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24); alienBaseEnvironmentTextureCube = new TextureCube(game.Graphics.GraphicsDevice, 256, false, game.Graphics.GraphicsDevice.DisplayMode.Format); // creating selection rectangle and adding it to the Scene SelectionRectangle = new SelectionRectangle(game, this); SceneComponents.Add(SelectionRectangle); // the game is initially not in the debug mode IsInDebugMode = false; // adding ground element to the Scene groundElement = new GroundElement(game, new Vector3(0, groundYAxisPosition, 0), this); SceneComponents.Add(groundElement); sceneObjects.Add(groundElement); // setting the position of the alien base alienBasePosition = new Vector3(170, groundYAxisPosition, 170); //adding alien's base to the Scene AlienBase = new AlienBuilding(game, alienBasePosition, this); SceneComponents.Add(AlienBase); sceneObjects.Add(AlienBase); // adding alien crafts to the Scene for (int i = 0; i < numberOfAliens; i++) { AlienCraft a; // placing new craft in the first random and free place do { Vector3 randomPosition = new Vector3(AlienBase.Position.X + (float)WarGame.RandomGenerator.NextDouble() * 50.0f - 25.0f, GroundYAxisPosition + 1.0f, AlienBase.Position.Z + (float)WarGame.RandomGenerator.NextDouble() * 50.0f - 25.0f); a = new AlienCraft(game, this, randomPosition); } while (a.CheckForCollisions() != null); SceneComponents.Add(a); sceneObjects.Add(a); alienCrafts.Add(a); } // adding skybox to the Scene SceneComponents.Add(new Skybox(game)); }
/// <summary> /// Wander steering behavior /// </summary> /// <param name="caller">Game object which calls the wander SB</param> /// <returns>Force acting at the caller</returns> public static Vector3 Wander(AlienCraft caller, List<AlienCraft> friends) { float wanderR = 2.0f; float wanderD = 4.0f; caller.WanderChange += (float)WarGame.RandomGenerator.NextDouble() - 0.5f; Vector3 circleloc = caller.Velocity; if (circleloc.LengthSquared() > 0) circleloc.Normalize(); circleloc *= wanderD; circleloc += caller.Position; Vector2 circleOffSet = new Vector2(wanderR * (float)Math.Cos(caller.WanderChange), wanderR * (float)Math.Sin(caller.WanderChange)); Vector3 target = new Vector3(circleloc.X + circleOffSet.X, circleloc.Y, circleloc.Z + circleOffSet.Y); caller.Target = target; Vector3 seekForce = Seek(caller, caller.Target); return seekForce + 2 * Separation(caller, friends); }
/// <summary> /// Wander ready to attack steering behaviour /// </summary> /// <param name="caller">GameObject which calls the ready to attack SB</param> /// <param name="objects">List of fighters to attack</param> /// <returns>Force acting on the game object</returns> public static Vector3 WanderReadyToAttack(AlienCraft caller, List<AlienCraft> friends, List<Fighter> targets) { int FOV = 50; Fighter fighterToSeek = null; float minDistance = float.MaxValue; foreach (Fighter f in targets) { float d = (caller.Position - f.Position).Length(); if (d < FOV) if (d < minDistance) { minDistance = d; fighterToSeek = f; } } if (fighterToSeek == null) return Wander(caller, friends); else return SeekWithSeparation(caller, fighterToSeek.Position, friends); }
/// <summary> /// Seek steering behavior combined with the separation /// </summary> /// <param name="caller">Game object which calls this SB</param> /// <param name="target">Target seeked by the caller</param> /// <param name="objects">List of fighters to separate from</param> /// <returns>Force acting at the caller</returns> public static Vector3 SeekWithSeparation(AlienCraft caller, Vector3 target, List<AlienCraft> objects) { if ((caller.Position - target).Length() > 5) return Seek(caller, target) + 2 * Separation(caller, objects); else if (Separation(caller, objects).Length() < 0.1f) return Vector3.Zero; else return Seek(caller, target) + 6 * Separation(caller, objects); }