Exemplo n.º 1
0
        /// <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];
        }
Exemplo n.º 2
0
        /// <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();
                }
            }
        }