/// <summary> /// Performs a gun action - the shoot. It Releases the bullet into the space and calls the bullet collision resolving. /// </summary> /// <param name="gameTime">Game time</param> /// <param name="position">The gun position in the shoot moment</param> /// <param name="azimuth">The shoot direction</param> public override void DoAction(GameTime gameTime, PositionInTown position, float azimuth) { if (gameTime.TotalGameTime - lastTimeShot >= type.ShotTimeout && Usable) { bool somethingWasHit = PerformShoot(gameTime, position, azimuth, true); if (!somethingWasHit && Holder is Player) //affect the secondary drawn quarter { TownQuarter secondaryQuarter = Game.Town.SecondaryDrawnQuarter; Debug.Write("Secondary quarer", secondaryQuarter.Name); Vector2 positionDelta = secondaryQuarter.CurrentDrawingPositionDelta; float azimuthDelta = secondaryQuarter.CurrentDrawingAzimuthDelta; PositionInTown secondaryPosition = new PositionInTown(secondaryQuarter, Vector3.Transform(position.PositionInQuarter.ToVector3(0), Matrix.CreateTranslation(-positionDelta.ToVector3(0)) * Matrix.CreateRotationY(azimuthDelta)).XZToVector2()); float secondaryAzimuth = azimuth - azimuthDelta; PerformShoot(gameTime, secondaryPosition, secondaryAzimuth, false); if (secondaryQuarter != Game.Opponent.Position.Quarter && gameTime.IsRunningSlowly) { secondaryQuarter.Update(gameTime, true); } } Game.SoundPlayer.PlaySound(type.ShootSount, position); lastTimeShot = gameTime.TotalGameTime; bullets--; } }
/// <summary> /// Plays specified sound at specified place. It automaticly sets the volume. /// </summary> /// <param name="sound">The specified sound</param> /// <param name="position">The specified position</param> public void PlaySound(SoundEffect sound, PositionInTown position) { if (game.Player.Position.Quarter == position.Quarter) { float quarterDiagonalLength = (new Vector2(position.Quarter.BitmapSize.Width, position.Quarter.BitmapSize.Height) * TownQuarter.SquareWidth).Length(); sound.Play(1f - (position.MinimalDistanceTo(game.Player.Position) / quarterDiagonalLength), 0f, 0f); } }
/// <summary> /// Recomputes the waypoints according to path graph to get to the task target. /// </summary> /// <param name="from">Start position</param> /// <param name="to">Destination position</param> protected void RecomputeWaypoints(PositionInTown from, PositionInTown to) { wayPoints.Clear(); foreach (PathGraphVertex v in PathGraph.FindShortestPath(from, to, !(holder is Opponent))) { wayPoints.Enqueue(new WayPoint(v.Position)); } wayPoints.Enqueue(new WayPoint(to)); }
/// <summary> /// Respawns the human into a specified quarter. /// </summary> /// <param name="targetQuarter">The destination quarter</param> public void RespawnInto(TownQuarter targetQuarter) { Position.Quarter.BeLeftBy(this); Position = new PositionInTown(targetQuarter, targetQuarter.GetRandomSquare(fillType => fillType == MapFillType.Road, point => point != targetQuarter.FlagPoint).ToVector2() * TownQuarter.SquareWidth); Position.Quarter.BeEnteredBy(this); health = 100; tasks.Clear(); }
/// <summary> /// Creates a new instance of human /// </summary> /// <param name="game">The game</param> /// <param name="model">Model</param> /// <param name="position">Position</param> /// <param name="azimuth">Azimuth</param> /// <param name="worldTransform">World transform matrix</param> public Human(ActionGame game, Model model, PositionInTown position, double azimuth, Matrix worldTransform) : base(model, position, azimuth, worldTransform) { this.game = game; health = 100; tools.AddRange( from gunType in game.HumanDefaultGuns select new Gun(gunType, gunType.DefaultBulletCount, this, game) ); selectedToolIndex = 0; lastPosition = position.PositionInQuarter; lastSeenEnemy = null; lastTimeSawEnemy = TimeSpan.Zero; }
protected void Load(Model model, PositionInTown position, float verticalPosition, double azimuth, Matrix worldTransform) { this.model = model; this.verticalPosition = verticalPosition; Vector3 size = Vector3.Zero; if (model != null) { size = model.GetSize(worldTransform); verticalSize = size.Y; } base.Load(position, azimuth, size.XZToVector2()); }
/// <summary> /// Loads and sets the player's specific content and settings. /// </summary> /// <param name="model">Model</param> /// <param name="position">Position</param> /// <param name="azimuth">Azimuth</param> /// <param name="worldTransform">The world transform matrix</param> public new void Load(Model model, PositionInTown position, double azimuth, Matrix worldTransform) { base.Load(model, position, azimuth, worldTransform); Content = new TownQuarterOwnerContent { AllyHumanModel = Game.Content.Load <Model>("Objects/Humans/botBlue"), FlagModel = Game.Content.Load <Model>("Objects/Decorations/flagBlue2"), RoadSignTexture = Game.Content.Load <Texture2D>("Textures/roadSignBlue"), ColorTexture = Game.Content.Load <Texture2D>("Textures/blue"), DrawingColor = System.Drawing.Color.Blue }; }
/// <summary> /// Loads and sets the opponent specific content and settings /// </summary> /// <param name="model">Model</param> /// <param name="position">Postion</param> /// <param name="azimuth">Azimuth</param> /// <param name="worldTransform">World transform matrix</param> public void Load(Model model, PositionInTown position, double azimuth, Matrix worldTransform) { base.Load(model, position, 0, azimuth, worldTransform); Content = new TownQuarterOwnerContent { AllyHumanModel = Game.Content.Load <Model>("Objects/Humans/botYellow"), FlagModel = Game.Content.Load <Model>("Objects/Decorations/flagYellow2"), RoadSignTexture = Game.Content.Load <Texture2D>("Textures/roadSignYellow"), ColorTexture = Game.Content.Load <Texture2D>("Textures/yellow"), DrawingColor = System.Drawing.Color.Yellow }; Running = true; }
/// <summary> /// Rotates the human toward the specified destination. /// </summary> /// <param name="destination">The destination</param> /// <param name="seconds">Moving duration</param> public void TurnThisWay(PositionInTown destination, float seconds) { if (destination.Quarter == Position.Quarter) { double actualRotateAngle = RotateAngle * seconds; float direction = (destination.PositionInQuarter - Position.PositionInQuarter).GetAngle() + 1 * MathHelper.PiOver2; direction = direction % MathHelper.TwoPi; if (IsAzimuthTooFarFrom(direction, actualRotateAngle)) { bool toLeft = (azimuth > direction && direction >= 0 && azimuth - direction < MathHelper.Pi) || (direction > azimuth && direction - azimuth > MathHelper.Pi); Rotate(toLeft, seconds); } else { azimuth = direction; } } }
/// <summary> /// Creates a new flat object. /// </summary> /// <param name="position">Position of the object</param> /// <param name="azimuth">Azimuth</param> /// <param name="size">Size (width, lenght)</param> /// <param name="texture">Used texture</param> public FlatObject(PositionInTown position, double azimuth, Vector2 size, Texture2D texture) : base(position, azimuth, size) { this.texture = texture; vertices = new VertexPositionNormalTexture[4]; indexes = new short[6]; Vector2 textureUpperLeft = new Vector2(0.0f, 0.0f); Vector2 textureUpperRight = new Vector2(1.0f, 0.0f); Vector2 textureLowerLeft = new Vector2(0.0f, 1.0f); Vector2 textureLowerRight = new Vector2(1.0f, 1.0f); for (int i = 0; i < vertices.Length; i++) { vertices[i].Normal = Vector3.Up; } vertices[0].Position = LowerLeftCorner.ToVector3(verticalPosition); vertices[0].TextureCoordinate = textureLowerLeft; vertices[1].Position = UpperLeftCorner.ToVector3(verticalPosition); vertices[1].TextureCoordinate = textureUpperLeft; vertices[2].Position = LowerRightCorner.ToVector3(verticalPosition); vertices[2].TextureCoordinate = textureLowerRight; vertices[3].Position = UpperRightCorner.ToVector3(verticalPosition); vertices[3].TextureCoordinate = textureUpperRight; indexes[0] = 0; indexes[1] = 1; indexes[2] = 2; indexes[3] = 2; indexes[4] = 1; indexes[5] = 3; quadEffect = new BasicEffect(texture.GraphicsDevice); quadEffect.EnableDefaultLighting(); quadEffect.TextureEnabled = true; quadEffect.Texture = texture; }
/// <summary> /// Creates a new guard for this human. /// </summary> /// <param name="targetQuarter">Quarted that has to be guarded</param> /// <returns>The guard</returns> public Human CreateAllyGuard(TownQuarter targetQuarter) { PositionInTown pos = new PositionInTown(targetQuarter, targetQuarter.GetRandomSquare(x => x == MapFillType.Road).ToVector2() * TownQuarter.SquareWidth); Human guard = new Human(game, Content.AllyHumanModel, pos, 0, game.Drawer.WorldTransformMatrix); foreach (Human enemy in enemies) { guard.AddEnemy(enemy); } foreach (Human friend in friends) { guard.AddFriend(friend); } foreach (Human has in hasMeAsEnemy) { has.AddEnemy(guard); } guard.AddTask(new InfinityWalkingTask(guard, targetQuarter.GetRandomWalkingWaypoints())); foreach (GunType gt in game.GuardDefaultGuns) { guard.AddTool(new Gun(gt, gt.DefaultBulletCount, guard, game)); } return(guard); }
protected void Load(PositionInTown position, double azimuth, Vector2 size) { this.position = position; this.azimuth = azimuth; this.size = size; }
/// <summary> /// Creates a new spatial object. /// </summary> /// <param name="model">Model</param> /// <param name="position">Posistion</param> /// <param name="azimuth">Azimuth</param> /// <param name="worldTransform">World transform matrix</param> public SpatialObject(Model model, PositionInTown position, double azimuth, Matrix worldTransform) : base(position, azimuth, (model == null ? Vector2.Zero : model.GetSize(worldTransform).XZToVector2())) { Load(model, position, 0, azimuth, worldTransform); }
/// <summary> /// Creates a new flag action object /// </summary> /// <param name="game">The game</param> /// <param name="model">Model</param> /// <param name="position">Position</param> /// <param name="azimuth">Azimuth</param> /// <param name="worldTransform">World transform matrix</param> public Flag(ActionGame game, Model model, PositionInTown position, double azimuth, Matrix worldTransform) : base(game, ActionDistance, model, position, azimuth, worldTransform) { }
/// <summary> /// Creates a new Box /// </summary> /// <param name="game">The game</param> /// <param name="takeSound">Sound that will be played if the box is taken</param> /// <param name="model"></param> /// <param name="position"></param> /// <param name="world"></param> public Box(ActionGame game, SoundEffect takeSound, Model model, PositionInTown position, Matrix world) : base(model, position, 0, world) { this.takeSound = takeSound; this.game = game; }
/// <summary> /// Chages the objects position and azimuth. /// </summary> /// <param name="newPosition">The new position</param> /// <param name="azimuth">The new azimuth</param> public void MoveTo(PositionInTown newPosition, double azimuth) { position = newPosition; this.azimuth = azimuth; }
/// <summary> /// Performs the specific tool action if it is overriden. /// </summary> /// <param name="gameTime">Game time</param> /// <param name="position">The position of the tool at the action moment</param> /// <param name="azimuth">The action direction</param> public abstract void DoAction(GameTime gameTime, PositionInTown position, float azimuth);
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { if (running) { using (Loading loadingForm = new Loading()) { GameTime gameTime = new GameTime(TimeSpan.Zero, TimeSpan.Zero); loadingForm.Show(); loadingForm.SetLabel("Loading graphics device tools..."); spriteBatch = new SpriteBatch(GraphicsDevice); loadingForm.SetLabel("Loading content..."); contentRepository.LoadContent(); loadingForm.SetLabel("Loading gun types..."); LoadGunTypes(); player = new Player(this); opponent = new Opponent(this); town = new Town(this, loadingForm); loadingForm.SetLabel("Loading player..."); loadingForm.SetValue(0); Point playerPoint = town.CurrentQuarter.GetRandomSquare(s => s == MapFillType.Sidewalk); PositionInTown playerPosition = new PositionInTown(town.CurrentQuarter, playerPoint.ToVector2() * TownQuarter.SquareWidth + Vector2.One * 0.5f * TownQuarter.SquareWidth); player.Load(contentRepository.Player, playerPosition, MathHelper.PiOver2, drawer.WorldTransformMatrix); town.CurrentQuarter.SpaceGrid.AddObject(player); town.CurrentQuarter.SetOwner(player, gameTime); player.AddEnemy(opponent); loadingForm.SetLabel("Loading opponent..."); loadingForm.SetValue(0); TownQuarter oppQuarter = (from q in town.Quarters where q != town.CurrentQuarter orderby random.Next() select q).First(); Point oppPoint = oppQuarter.GetRandomSquare(s => s == MapFillType.Sidewalk); PositionInTown oppPosition = new PositionInTown(oppQuarter, oppPoint.ToVector2() * TownQuarter.SquareWidth); opponent.Load(contentRepository.Opponent, oppPosition, 0, drawer.WorldTransformMatrix); oppQuarter.BeEnteredBy(opponent); oppQuarter.SetOwner(opponent, gameTime); opponent.AddEnemy(player); Components.Add(town); BulletVisualisation.Texture = Content.Load <Texture2D>("Textures/white"); backgroundSound = Content.Load <SoundEffect>("Sounds/background").CreateInstance(); loadingForm.SetLabel("Cleaning memory..."); loadingForm.SetValue(0); GC.Collect(); loadingForm.SetValue(100); loadingForm.SetLabel("Content loaded. Get ready to play!"); loadingForm.SetValue(100); loadingForm.Close(); backgroundSound.IsLooped = true; backgroundSound.Play(); drawer.ShowMessage(new GameTime(), String.Format("Wellcome in the game. You're in {0}.", player.Position.Quarter.Name)); } if (settings.Fullscreen) { graphics.ToggleFullScreen(); } } }
public WayPoint(PositionInTown point) { this.point = point; }
/// <summary> /// Creates new action object. /// </summary> /// <param name="game">The game</param> /// <param name="actionDistance">Distance from which the action can be performed</param> /// <param name="model">Model of the action object</param> /// <param name="position">Position</param> /// <param name="azimuth">Azimuth</param> /// <param name="worldTransform">World transform matrix</param> public ActionObject(ActionGame game, float actionDistance, Model model, PositionInTown position, double azimuth, Matrix worldTransform) : base(model, position, azimuth, worldTransform) { this.actionDistance = actionDistance; this.game = game; }
void ComputeWayPointsFrom(PositionInTown from) { RecomputeWaypoints(from, destination); }
/// <summary> /// Performs move to the spcifed target. /// </summary> /// <param name="destination">Wished destination</param> /// <param name="seconds">Duration</param> public void GoThisWay(PositionInTown destination, float seconds) { if (destination.Quarter == Position.Quarter) { double actualRotateAngle = RotateAngle * seconds; float direction = (destination.PositionInQuarter - Position.PositionInQuarter).GetAngle() + 1 * MathHelper.PiOver2; direction = direction % MathHelper.TwoPi; if (IsAzimuthTooFarFrom(direction, actualRotateAngle)) { bool toLeft = (azimuth > direction && direction >= 0 && azimuth - direction < MathHelper.Pi) || (direction > azimuth && direction - azimuth > MathHelper.Pi); Rotate(toLeft, seconds); if (Math.Abs(azimuth - direction) < MathHelper.PiOver2 && Position.MinimalDistanceTo(destination) > TownQuarter.SquareWidth) { Go(seconds); } } else { azimuth = direction; Go(seconds); } } else { TownQuarterInterface rightIface = null; foreach (TownQuarterInterface iface in Position.Quarter.Interfaces) { if (iface.OppositeInterface.Quarter == destination.Quarter) { rightIface = iface; } } if (rightIface != null) { if (Position.MinimalDistanceTo(rightIface.LeftPathGraphVertex.Position) <= Human.EpsilonDistance || Position.MinimalDistanceTo(rightIface.RightPathGraphVertex.Position) <= Human.EpsilonDistance) { //Changes home quarter TownQuarter newQuarter = rightIface.OppositeInterface.Quarter; Position.Quarter.BeLeftBy(this); Game.Drawer.StopDrawingObject(this); Vector2 posDelta = Town.ResolveQuarterPositionDelta(rightIface); float azDelta = Town.ResolveQuarterAzimuthDelta(rightIface.SidePosition, rightIface.OppositeInterface.SidePosition); MoveTo( new PositionInTown(newQuarter, Vector3.Transform(PositionInQuarter, Matrix.CreateTranslation(-posDelta.ToVector3(0)) * Matrix.CreateRotationY(azDelta)).XZToVector2()), Azimuth - azDelta ); newQuarter.BeEnteredBy(this); if (newQuarter.CurrentlyDrawed) { Game.Drawer.StartDrawingObject(this, newQuarter.CurrentDrawingAzimuthDelta, newQuarter.CurrentDrawingPositionDelta); } } else { GoThisWay(rightIface.LeftPathGraphVertex.Position, seconds); } } } }
/// <summary> /// Loads the human specific content. This can be used if the content wasn't specified in the construct. /// </summary> /// <param name="model">Model</param> /// <param name="position">Position</param> /// <param name="azimuth">Azimuth</param> /// <param name="worldTransform">World transform matrix</param> public void Load(Model model, PositionInTown position, double azimuth, Matrix worldTransform) { base.Load(model, position, 0, azimuth, worldTransform); lastPosition = position.PositionInQuarter; }
/// <summary> /// Creates a new game object /// </summary> /// <param name="position">Position</param> /// <param name="azimuth">Azimuth</param> /// <param name="size">Size (width, length)</param> public GameObject(PositionInTown position, double azimuth, Vector2 size) { Load(position, azimuth, size); }
/// <summary> /// Creates a new heal box. /// </summary> /// <param name="healPercentage">Percentage that will be added to the human's health status if he takes it.</param> /// <param name="game">The game</param> /// <param name="takeSound">The take sound effect</param> /// <param name="model">Model of the box</param> /// <param name="position">Position</param> /// <param name="world">World transformation matrix</param> public HealBox(int healPercentage, ActionGame game, SoundEffect takeSound, Model model, PositionInTown position, Matrix world) : base(game, takeSound, model, position, world) { this.healPercentage = healPercentage; }
/// <summary> /// Creates a new toolbox /// </summary> /// <param name="toolInside">The tool instance inside</param> /// <param name="game">The game</param> /// <param name="takeSound">The taking sound</param> /// <param name="model">Model of the box</param> /// <param name="position">Position of the box</param> /// <param name="world">World transformation matrix</param> public ToolBox(Tool toolInside, ActionGame game, SoundEffect takeSound, Model model, PositionInTown position, Matrix world) : base(game, takeSound, model, position, world) { tool = toolInside; }
/// <summary> /// Creates a new move task. /// </summary> /// <param name="holder">The holder of the task.</param> /// <param name="destination">The destination that has to be reached</param> public MoveTask(Human holder, PositionInTown destination) : base(holder) { this.destination = destination; }
/// <summary> /// Performes the bullet releasing in the shoot process /// </summary> /// <param name="gameTime">Game time</param> /// <param name="position">Start position</param> /// <param name="azimuth">Flight direction</param> /// <param name="visualiseBullet">Whether the bullet should be visualised indicator</param> /// <returns>True if the bullet hit something</returns> bool PerformShoot(GameTime gameTime, PositionInTown position, float azimuth, bool visualiseBullet) { const float bulletWidth = 0.02f; //const float startHeight = 0.5f; const float bulletWidthHalf = bulletWidth / 2; bool solveHeight = (Holder is Player); double lookAngle = Holder.LookAngle; //Vector2 quarterPosition = position.PositionInQuarter; float startHeight = Holder.FirstHeadPosition.Y - bulletWidth; Vector2 quarterPosition = position.PositionInQuarter; Vector2 left = quarterPosition.Go(bulletWidthHalf, azimuth - MathHelper.PiOver2); Vector2 right = quarterPosition.Go(bulletWidthHalf, azimuth + MathHelper.PiOver2); Quadrangle bullet = new Quadrangle(right, left, right.Go(type.Range, azimuth), left.Go(type.Range, azimuth)); TownQuarter quarter = position.Quarter; List <Quadrangle> colliders = new List <Quadrangle>(quarter.SpaceGrid.GetAllCollisions(bullet)); colliders.RemoveAll(x => x == Holder); //Half-interval search Stack <RangeF> testedParts = new Stack <RangeF>(); Dictionary <float, float> heights = new Dictionary <float, float>(); testedParts.Push(new RangeF(0, type.Range)); if (solveHeight) { heights.Add(0, startHeight); heights.Add(type.Range, startHeight + type.Range * (float)Math.Tan(lookAngle)); } Quadrangle nearest = null; float distance = type.Range; while (testedParts.Count != 0) { RangeF bulletRangePart = testedParts.Pop(); float h1 = 0f; float h2 = 0f; if (solveHeight) { h1 = heights[bulletRangePart.Begin]; h2 = heights[bulletRangePart.End]; } Quadrangle bulletPart = new Quadrangle( left.Go(bulletRangePart.Begin, azimuth), right.Go(bulletRangePart.Begin, azimuth), left.Go(bulletRangePart.End, azimuth), right.Go(bulletRangePart.End, azimuth)); List <Quadrangle> newColliders = new List <Quadrangle>( colliders.Where( x => (solveHeight && x is SpatialObject && (((SpatialObject)x).Size.Y >= h2 || ((SpatialObject)x).Size.Y >= h2) && (0 <= h1 || 0 <= h2) && x.IsInCollisionWith(bulletPart)) || (!solveHeight && x.IsInCollisionWith(bulletPart)) ) ); if (newColliders.Count != 0) { if (newColliders.Count == 1 || bulletRangePart.Length <= bulletWidthHalf) { nearest = newColliders[0]; distance = bulletRangePart.End; break; } colliders = newColliders; float halfLength = bulletRangePart.Length * 0.5f; float middle = bulletRangePart.Begin + halfLength; testedParts.Push(new RangeF(middle, bulletRangePart.End)); testedParts.Push(new RangeF(bulletRangePart.Begin, middle)); if (solveHeight && halfLength != 0f) { heights.Add(middle, startHeight + middle * (float)Math.Tan(lookAngle)); } } } if (visualiseBullet) { quarter.AddBullet(gameTime, new BulletVisualisation(quarter, quarterPosition, azimuth, distance, startHeight, startHeight + distance * (float)Math.Tan(lookAngle))); } if (nearest != null) { Debug.Write("Shot", nearest.ToString()); nearest.BecomeShoot(gameTime, type.Damage, Holder); return(true); } return(false); }