예제 #1
0
 /// <summary>
 /// Creates a new bullet visualisation.
 /// </summary>
 /// <param name="quarter">Town quarter where the bullet is located</param>
 /// <param name="start">Starting position</param>
 /// <param name="azimuth">The flight direction</param>
 /// <param name="range">The flight range</param>
 /// <param name="startHeight">Starting height</param>
 /// <param name="endHeight">Ending height</param>
 public BulletVisualisation(TownQuarter quarter, Vector2 start, float azimuth, float range, float startHeight, float endHeight)
 {
     Vector2 end = start.Go(range, azimuth);
     Vector2 startL = start.Go(Width, azimuth - MathHelper.PiOver2);
     Vector2 startR = start.Go(Width, azimuth + MathHelper.PiOver2);
     Vector2 endL = end.Go(Width, azimuth - MathHelper.PiOver2);
     Vector2 endR = end.Go(Width, azimuth + MathHelper.PiOver2);
     horizontalPlate = new Plate(quarter, startL.ToVector3(startHeight), startR.ToVector3(startHeight), endL.ToVector3(endHeight), endR.ToVector3(endHeight), Texture, Texture, false);
     verticalPlate = new Plate(quarter, start.ToVector3(startHeight + Width), start.ToVector3(startHeight - Width), end.ToVector3(endHeight + Width), end.ToVector3(endHeight - Width), Texture, Texture, false);
 }
예제 #2
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <summary>
        /// Updates the town logic. It looks for the quarter the player is located in and for the nearby quarter that should be drawn as well.
        /// </summary>
        /// <param name="gameTime">Game time</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            Debug.Write("Current quarter", currentQuarter.Name);

            Vector2 playerPosition = Game.Player.PositionInQuarter.XZToVector2();
            Vector2 quarterSize    = new Vector2(currentQuarter.BitmapSize.Width * TownQuarter.SquareWidth, currentQuarter.BitmapSize.Height * TownQuarter.SquareWidth);

            if (gameTime.TotalGameTime - lastQuarterChange > quarterChangeTimeOut &&
                ((playerPosition.X > quarterSize.X || playerPosition.Y > quarterSize.Y) || (playerPosition.X < 0 || playerPosition.Y < 0)) &&
                lastNearestInterfaceIndex >= 0)
            {
                //Remove drawed quaeters from drawer
                ClearDrawer();

                //Remove player from old quarter space grid
                currentQuarter.SpaceGrid.RemoveObject(Game.Player);

                //Changes current quarter
                TownQuarterInterface usedInterface = currentQuarter.Interfaces[lastNearestInterfaceIndex];
                currentQuarter = usedInterface.OppositeInterface.Quarter;

                //Moves player into new current quarter
                float   angle = ResolveQuarterAzimuthDelta(usedInterface.SidePosition, usedInterface.OppositeInterface.SidePosition);
                Vector2 delta = ResolveQuarterPositionDelta(usedInterface);
                Game.Player.MoveTo(
                    new PositionInTown(currentQuarter,
                                       Vector3.Transform(Game.Player.PositionInQuarter, Matrix.CreateTranslation(-delta.ToVector3(0)) * Matrix.CreateRotationY(angle)).XZToVector2() // reverse transform of nearest quarter
                                       ),
                    Game.Player.Azimuth - angle
                    );
                Game.Drawer.MovePanorama(-delta, -angle);

                //Assings player to new space grid
                currentQuarter.SpaceGrid.AddObject(Game.Player);
                Game.Drawer.ShowMessage(gameTime, String.Format("You've entered {0}.", currentQuarter.Name));

                //Restart for drawing
                lastNearestInterfaceIndex = -1;
                currentQuarterDrawed      = false;

                lastQuarterChange = gameTime.TotalGameTime;
            }

            FillDrawer();

            currentQuarter.Update(gameTime, false);
        }
예제 #3
0
파일: Plate.cs 프로젝트: havri/ActionGame
 /// <summary>
 /// Creates a new plate.
 /// </summary>
 /// <param name="homeQuarter">Town quarter where is it located</param>
 /// <param name="upperLeft">Upper left corner</param>
 /// <param name="upperRight">Upper right corner</param>
 /// <param name="lowerLeft">Lower left corner</param>
 /// <param name="lowerRight">Lower right corner</param>
 /// <param name="front">Front side texture</param>
 /// <param name="back">Back side texture</param>
 /// <param name="enableDefaultLightning">Determines if the default lightning is used</param>
 public Plate(TownQuarter homeQuarter, Vector3 upperLeft, Vector3 upperRight, Vector3 lowerLeft, Vector3 lowerRight, Texture2D front, Texture2D back, bool enableDefaultLightning)
     : base(upperLeft.XZToVector2(), upperRight.XZToVector2(), lowerLeft.XZToVector2(), lowerRight.XZToVector2())
 {
     quarter = homeQuarter;
     ul = upperLeft;
     ur = upperRight;
     ll = lowerLeft;
     lr = lowerRight;
     this.back = back;
     this.front = front;
     graphicsDevice = front.GraphicsDevice;
     frontVertices = new VertexPositionNormalTexture[4];
     backVertices = new VertexPositionNormalTexture[4];
     indexes = new short[6];
     BuildEffects(enableDefaultLightning);
 }
예제 #4
0
 /// <summary>
 /// Creates a new spatial object.
 /// </summary>
 /// <param name="model">Model</param>
 /// <param name="quarter">Town quarter</param>
 /// <param name="positionInQuarter">Position inside the town quarter</param>
 /// <param name="azimuth">Azimuth</param>
 /// <param name="worldTransform">World transform matrix</param>
 public SpatialObject(Model model, TownQuarter quarter, Vector3 positionInQuarter, double azimuth, Matrix worldTransform)
     : base(new PositionInTown(quarter, positionInQuarter.XZToVector2()), azimuth, (model == null? Vector2.Zero : model.GetSize(worldTransform).XZToVector2()))
 {
     Load(model, new PositionInTown(quarter, positionInQuarter.XZToVector2()), positionInQuarter.Y, azimuth, worldTransform);
 }
예제 #5
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <summary>
        /// Creates and generates the whole town.
        /// </summary>
        /// <param name="game">The game</param>
        /// <param name="loadingFrom">Loading form where the generating progress will be shown</param>
        public Town(ActionGame game, Loading loadingFrom)
            : base(game)
        {
            EmptyTownQuarterOwner.LoadContent(game.Content);

            quarters = new TownQuarter[game.Settings.TownQuarterCount];

            //Town graph creation
            loadingFrom.SetLabel("Generating town graph...");
            loadingFrom.SetValue(0);
            int[] degrees = new int[game.Settings.TownQuarterCount];
            bool[,] edges = new bool[game.Settings.TownQuarterCount, game.Settings.TownQuarterCount]; // Graph is unoriented (symetric). edges[i, j] can be true only if i<j!
            for (int i = 0; i < game.Settings.TownQuarterCount - 1; i++) // First is made path through all. Graph has to have only one component.
            {
                int j = i + 1;
                degrees[i]++;
                degrees[j]++;
                edges[i, j] = true;
            }
            for (int i = 0; i < game.Settings.TownQuarterCount; i++)
            {
                loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount);
                for (int j = i + 1; j < game.Settings.TownQuarterCount; j++) //graph isn't oriented and reflexion is denied
                {
                    if (!edges[i, j] && degrees[i] < MaxQuarterDegree && degrees[j] < MaxQuarterDegree)
                    {
                        if (game.Random.NextDouble() < 0.65)
                        {
                            degrees[i]++;
                            degrees[j]++;
                            edges[i, j] = true;
                        }
                    }
                }
            }

            //Quarter creating by degrees
            loadingFrom.SetLabel("Generating quarters and streets...");
            loadingFrom.SetValue(0);
            for (int i = 0; i < game.Settings.TownQuarterCount; i++)
            {
                loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount);
                float perimeterLength = MinSideLengthPerInterface * Math.Max(degrees[i], 4); // Even interface isn't needed the side must be there
                perimeterLength *= (float)game.Random.NextDouble() + 1f; //Minimal length can be doubled
                float width = (perimeterLength / 2f) * (float)(game.Random.NextDouble() * 0.3 + 0.35); //aspect ratio
                float height = (perimeterLength / 2f) - width;
                if (width < MinQuarterSideLength)
                    width = MinQuarterSideLength;
                if (height < MinQuarterSideLength)
                    height = MinQuarterSideLength;

                do
                {
                    try
                    {
                        TownQuarter quarter = new TownQuarter(game, new Vector2(width, height), degrees[i]);
                        quarters[i] = quarter;
                    }
                    catch (NoSpaceForInterfaceException)
                    {
                        float widthIncement = MinSideLengthPerInterface * (float)game.Random.NextDouble();
                        width += widthIncement;
                        height += MinSideLengthPerInterface - widthIncement;
                    }
                }
                while (quarters[i] == null);
            }

            //Joining interfaces
            loadingFrom.SetLabel("Building town...");
            loadingFrom.SetValue(0);
            for (int i = 0; i < game.Settings.TownQuarterCount; i++)
            {
                loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount);
                for (int j = i + 1; j < game.Settings.TownQuarterCount; j++)
                {
                    if (edges[i, j])
                    {
                        TownQuarterInterface ifaceI = (from iface in quarters[i].Interfaces where iface.OppositeInterface == null orderby game.Random.Next() select iface).First();
                        TownQuarterInterface ifaceJ = (from iface in quarters[j].Interfaces where iface.OppositeInterface == null orderby game.Random.Next() select iface).First();
                        ifaceI.OppositeInterface = ifaceJ;
                        ifaceJ.OppositeInterface = ifaceI;
                        ifaceI.LeftPathGraphVertex.AddNeighborBothDirection(ifaceJ.RightPathGraphVertex, TownQuarter.SquareWidth);
                        ifaceI.RightPathGraphVertex.AddNeighborBothDirection(ifaceJ.LeftPathGraphVertex, TownQuarter.SquareWidth);
                    }
                }
            }
            foreach (var quarter in quarters)
            {
                quarter.BuildInterfaceRoadSigns();
            }

            //Town map base creating
            {
                Bitmap mapRaster = new Bitmap(MapImageWidth, MapImageHeight);
                using (Graphics graphics = Graphics.FromImage(mapRaster))
                {
                    graphics.FillRectangle(Brushes.White, 0, 0, mapRaster.Width, mapRaster.Height);
                    float angleJump = MathHelper.TwoPi / Game.Settings.TownQuarterCount;
                    float radius = Math.Min(MapImageWidth, MapImageHeight) / 2f - 20f;
                    PointF center = new PointF(MapImageWidth / 2f, MapImageHeight / 2f);

                    for (int i = 0; i < Game.Settings.TownQuarterCount; i++)
                    {
                        for (int j = i + 1; j < Game.Settings.TownQuarterCount; j++)
                        {
                            if (edges[i, j])
                            {
                                graphics.DrawLine(Pens.Green,
                                    center.X + (float)Math.Cos(i * angleJump) * radius,
                                    center.Y + (float)Math.Sin(i * angleJump) * radius,
                                    center.X + (float)Math.Cos(j * angleJump) * radius,
                                    center.Y + (float)Math.Sin(j * angleJump) * radius
                                    );
                            }
                        }
                    }

                    for (int i = 0; i < Game.Settings.TownQuarterCount; i++)
                    {
                        graphics.FillEllipse(Brushes.Black,
                            center.X + (float)Math.Cos(i * angleJump) * radius - 3.5f,
                            center.Y + (float)Math.Sin(i * angleJump) * radius - 3.5f,
                            7, 7);
                        graphics.DrawString(quarters[i].Name, new Font("Verdana", 12), Brushes.Black, center.X + (float)Math.Cos(i * angleJump) * radius, center.Y + (float)Math.Sin(i * angleJump) * radius - 16);
                    }
                }
                mapImage = mapRaster;
            }

            GC.Collect();

            //Selecting starting quarter
            currentQuarter = quarters[0];
        }
예제 #6
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <summary>
        /// Updates the town logic. It looks for the quarter the player is located in and for the nearby quarter that should be drawn as well.
        /// </summary>
        /// <param name="gameTime">Game time</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            Debug.Write("Current quarter", currentQuarter.Name);

            Vector2 playerPosition = Game.Player.PositionInQuarter.XZToVector2();
            Vector2 quarterSize = new Vector2(currentQuarter.BitmapSize.Width * TownQuarter.SquareWidth, currentQuarter.BitmapSize.Height * TownQuarter.SquareWidth);
            if (gameTime.TotalGameTime - lastQuarterChange > quarterChangeTimeOut
                && ((playerPosition.X > quarterSize.X || playerPosition.Y > quarterSize.Y) || (playerPosition.X < 0 || playerPosition.Y < 0))
                && lastNearestInterfaceIndex >= 0)
            {
                //Remove drawed quaeters from drawer
                ClearDrawer();

                //Remove player from old quarter space grid
                currentQuarter.SpaceGrid.RemoveObject(Game.Player);

                //Changes current quarter
                TownQuarterInterface usedInterface = currentQuarter.Interfaces[lastNearestInterfaceIndex];
                currentQuarter = usedInterface.OppositeInterface.Quarter;

                //Moves player into new current quarter
                float angle = ResolveQuarterAzimuthDelta(usedInterface.SidePosition, usedInterface.OppositeInterface.SidePosition);
                Vector2 delta = ResolveQuarterPositionDelta(usedInterface);
                Game.Player.MoveTo(
                    new PositionInTown(currentQuarter,
                        Vector3.Transform(Game.Player.PositionInQuarter, Matrix.CreateTranslation(-delta.ToVector3(0)) * Matrix.CreateRotationY(angle)).XZToVector2() // reverse transform of nearest quarter
                        ),
                    Game.Player.Azimuth - angle
                    );
                Game.Drawer.MovePanorama(-delta , -angle);

                //Assings player to new space grid
                currentQuarter.SpaceGrid.AddObject(Game.Player);
                Game.Drawer.ShowMessage(gameTime, String.Format("You've entered {0}.", currentQuarter.Name));

                //Restart for drawing
                lastNearestInterfaceIndex = -1;
                currentQuarterDrawed = false;

                lastQuarterChange = gameTime.TotalGameTime;
            }

            FillDrawer();

            currentQuarter.Update(gameTime, false);
        }
예제 #7
0
 /// <summary>
 /// Creates a new position in the town
 /// </summary>
 /// <param name="quarter">The quarter</param>
 /// <param name="position">Position inside the quarter</param>
 public PositionInTown(TownQuarter quarter, Vector2 position)
 {
     this.positionInQuarter = position;
     this.quarter           = quarter;
 }
예제 #8
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <summary>
        /// Creates and generates the whole town.
        /// </summary>
        /// <param name="game">The game</param>
        /// <param name="loadingFrom">Loading form where the generating progress will be shown</param>
        public Town(ActionGame game, Loading loadingFrom)
            : base(game)
        {
            EmptyTownQuarterOwner.LoadContent(game.Content);

            quarters = new TownQuarter[game.Settings.TownQuarterCount];

            //Town graph creation
            loadingFrom.SetLabel("Generating town graph...");
            loadingFrom.SetValue(0);
            int[] degrees = new int[game.Settings.TownQuarterCount];
            bool[,] edges = new bool[game.Settings.TownQuarterCount, game.Settings.TownQuarterCount]; // Graph is unoriented (symetric). edges[i, j] can be true only if i<j!
            for (int i = 0; i < game.Settings.TownQuarterCount - 1; i++)                              // First is made path through all. Graph has to have only one component.
            {
                int j = i + 1;
                degrees[i]++;
                degrees[j]++;
                edges[i, j] = true;
            }
            for (int i = 0; i < game.Settings.TownQuarterCount; i++)
            {
                loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount);
                for (int j = i + 1; j < game.Settings.TownQuarterCount; j++) //graph isn't oriented and reflexion is denied
                {
                    if (!edges[i, j] && degrees[i] < MaxQuarterDegree && degrees[j] < MaxQuarterDegree)
                    {
                        if (game.Random.NextDouble() < 0.65)
                        {
                            degrees[i]++;
                            degrees[j]++;
                            edges[i, j] = true;
                        }
                    }
                }
            }

            //Quarter creating by degrees
            loadingFrom.SetLabel("Generating quarters and streets...");
            loadingFrom.SetValue(0);
            for (int i = 0; i < game.Settings.TownQuarterCount; i++)
            {
                loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount);
                float perimeterLength = MinSideLengthPerInterface * Math.Max(degrees[i], 4);            // Even interface isn't needed the side must be there
                perimeterLength *= (float)game.Random.NextDouble() + 1f;                                //Minimal length can be doubled
                float width  = (perimeterLength / 2f) * (float)(game.Random.NextDouble() * 0.3 + 0.35); //aspect ratio
                float height = (perimeterLength / 2f) - width;
                if (width < MinQuarterSideLength)
                {
                    width = MinQuarterSideLength;
                }
                if (height < MinQuarterSideLength)
                {
                    height = MinQuarterSideLength;
                }

                do
                {
                    try
                    {
                        TownQuarter quarter = new TownQuarter(game, new Vector2(width, height), degrees[i]);
                        quarters[i] = quarter;
                    }
                    catch (NoSpaceForInterfaceException)
                    {
                        float widthIncement = MinSideLengthPerInterface * (float)game.Random.NextDouble();
                        width  += widthIncement;
                        height += MinSideLengthPerInterface - widthIncement;
                    }
                }while (quarters[i] == null);
            }


            //Joining interfaces
            loadingFrom.SetLabel("Building town...");
            loadingFrom.SetValue(0);
            for (int i = 0; i < game.Settings.TownQuarterCount; i++)
            {
                loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount);
                for (int j = i + 1; j < game.Settings.TownQuarterCount; j++)
                {
                    if (edges[i, j])
                    {
                        TownQuarterInterface ifaceI = (from iface in quarters[i].Interfaces where iface.OppositeInterface == null orderby game.Random.Next() select iface).First();
                        TownQuarterInterface ifaceJ = (from iface in quarters[j].Interfaces where iface.OppositeInterface == null orderby game.Random.Next() select iface).First();
                        ifaceI.OppositeInterface = ifaceJ;
                        ifaceJ.OppositeInterface = ifaceI;
                        ifaceI.LeftPathGraphVertex.AddNeighborBothDirection(ifaceJ.RightPathGraphVertex, TownQuarter.SquareWidth);
                        ifaceI.RightPathGraphVertex.AddNeighborBothDirection(ifaceJ.LeftPathGraphVertex, TownQuarter.SquareWidth);
                    }
                }
            }
            foreach (var quarter in quarters)
            {
                quarter.BuildInterfaceRoadSigns();
            }

            //Town map base creating
            {
                Bitmap mapRaster = new Bitmap(MapImageWidth, MapImageHeight);
                using (Graphics graphics = Graphics.FromImage(mapRaster))
                {
                    graphics.FillRectangle(Brushes.White, 0, 0, mapRaster.Width, mapRaster.Height);
                    float  angleJump = MathHelper.TwoPi / Game.Settings.TownQuarterCount;
                    float  radius    = Math.Min(MapImageWidth, MapImageHeight) / 2f - 20f;
                    PointF center    = new PointF(MapImageWidth / 2f, MapImageHeight / 2f);

                    for (int i = 0; i < Game.Settings.TownQuarterCount; i++)
                    {
                        for (int j = i + 1; j < Game.Settings.TownQuarterCount; j++)
                        {
                            if (edges[i, j])
                            {
                                graphics.DrawLine(Pens.Green,
                                                  center.X + (float)Math.Cos(i * angleJump) * radius,
                                                  center.Y + (float)Math.Sin(i * angleJump) * radius,
                                                  center.X + (float)Math.Cos(j * angleJump) * radius,
                                                  center.Y + (float)Math.Sin(j * angleJump) * radius
                                                  );
                            }
                        }
                    }

                    for (int i = 0; i < Game.Settings.TownQuarterCount; i++)
                    {
                        graphics.FillEllipse(Brushes.Black,
                                             center.X + (float)Math.Cos(i * angleJump) * radius - 3.5f,
                                             center.Y + (float)Math.Sin(i * angleJump) * radius - 3.5f,
                                             7, 7);
                        graphics.DrawString(quarters[i].Name, new Font("Verdana", 12), Brushes.Black, center.X + (float)Math.Cos(i * angleJump) * radius, center.Y + (float)Math.Sin(i * angleJump) * radius - 16);
                    }
                }
                mapImage = mapRaster;
            }

            GC.Collect();

            //Selecting starting quarter
            currentQuarter = quarters[0];
        }
예제 #9
0
        /// <summary>
        /// Searches for shortest path in the graph. Uses Dijkstra 1-1 form (A*).
        /// </summary>
        /// <param name="from">Source vertex</param>
        /// <param name="to">Target vertex</param>
        /// <param name="keepInTheSameQuarter">Indicator whether the searching has to use only vertices from the same quarter as the from position is in</param>
        /// <returns>Set of vertices forming result path</returns>
        public static IEnumerable <PathGraphVertex> FindShortestPath(PathGraphVertex from, PathGraphVertex to, bool keepInTheSameQuarter)
        {
            keepInTheSameQuarter = keepInTheSameQuarter && from.Position.Quarter == to.Position.Quarter;
            TownQuarter fromQuarter = from.Position.Quarter;

            LinkedList <PathGraphVertex> resultPath = new LinkedList <PathGraphVertex>();
            HashSet <PathGraphVertex>    closed     = new HashSet <PathGraphVertex>();
            Dictionary <PathGraphVertex, PathGraphVertex> cameFrom = new Dictionary <PathGraphVertex, PathGraphVertex>();
            Dictionary <PathGraphVertex, float>           gScore   = new Dictionary <PathGraphVertex, float>();

            gScore.Add(from, 0);
            Dictionary <PathGraphVertex, float> fScore = new Dictionary <PathGraphVertex, float>();

            fScore.Add(from, gScore[from] + HeuristicDistance(from, to));
            HashSet <PathGraphVertex> open = new HashSet <PathGraphVertex>();

            open.Add(from);

            while (open.Count != 0)
            {
                float           lowestScore  = float.MaxValue;
                PathGraphVertex lowestVertex = null;
                foreach (PathGraphVertex openedOne in open)
                {
                    float score = fScore[openedOne];
                    if (score < lowestScore)
                    {
                        lowestVertex = openedOne;
                    }
                }
                PathGraphVertex current = lowestVertex;//open.OrderBy(x => fScore[x]).First();
                if (current == to)
                {
                    PathGraphVertex t = to;
                    while (t != from)
                    {
                        resultPath.AddFirst(t);
                        t = cameFrom[t];
                    }
                    resultPath.AddFirst(from);
                    return(resultPath);
                }
                open.Remove(current);

                closed.Add(current);
                foreach (PathGraphVertex n in current.Neighbors)
                {
                    if (closed.Contains(n) || (keepInTheSameQuarter && n.Position.Quarter != fromQuarter))
                    {
                        continue;
                    }
                    else
                    {
                        float tempGSore = gScore[current] + current.GetDistanceToNeighbor(n);
                        if (!open.Contains(n) || tempGSore <= gScore[n])
                        {
                            cameFrom.SetValue(n, current);
                            gScore.SetValue(n, tempGSore);
                            fScore.SetValue(n, gScore[n] + HeuristicDistance(current, n));
                            if (!open.Contains(n))
                            {
                                open.Add(n);
                            }
                        }
                    }
                }
            }

            throw new PathNotFoundException("Source and target vertices aren't in the same component.");
        }
예제 #10
0
 public People.Human CreateAllyGuard(TownQuarter targetQuarter)
 {
     return(null);
 }
예제 #11
0
 /// <summary>
 /// Creates a new position in the town
 /// </summary>
 /// <param name="quarter">The quarter</param>
 /// <param name="position">Position inside the quarter</param>
 public PositionInTown(TownQuarter quarter, Vector2 position)
 {
     this.positionInQuarter = position;
     this.quarter = quarter;
 }