예제 #1
0
        /// <summary>
        /// A streak of lightning is drawn simply by piecing together a long string of small line segments, 
        /// each of which is slightly rotated.
        /// </summary>
        private void DrawLightningStreak(LineBatch lineBatch, Color color, Vector2 start, Vector2 end, int numSegments,
            float deviation)
        {
            Random randomGen = new Random();

            Vector2 disp = end - start;
            Vector2 unitDisp = Vector2.Normalize(disp);
            Vector2 stepVector = unitDisp * disp.Length() / (float)numSegments;
            Vector2 perpVec = new Vector2(-stepVector.Y, stepVector.X);
            perpVec.Normalize();

            Vector2 startPoint = start;
            Vector2 endPoint = new Vector2();

            for (int i = 0; i < numSegments; ++i)
            {
                endPoint = start + stepVector * (i + 1);

                // If this is an intermediate segment, apply an offset perpendicular to the line connecting start to end.
                if (i < numSegments - 1)
                {
                    float random = (float)randomGen.NextDouble();
                    float offset = (random >= 0.5f ? 1 : -1) * random * deviation;

                    endPoint += perpVec * offset;
                }

                lineBatch.DrawLine(startPoint, endPoint, color);

                startPoint = endPoint;
            }
        }
예제 #2
0
        /// <summary>
        /// This draws the box with streaks of lightning representing its edges.
        /// </summary>
        public void Draw(LineBatch lineBatch, Color color, int numSegments, float deviation)
        {
            // Let's compute the coordinates of all the vertices to make the line drawing simpler.

            Vector2 upperLeft = new Vector2(rectangle.Left, rectangle.Top);
            Vector2 upperRight = new Vector2(rectangle.Right, rectangle.Top);
            Vector2 lowerLeft = new Vector2(rectangle.Left, rectangle.Bottom);
            Vector2 lowerRight = new Vector2(rectangle.Right, rectangle.Bottom);

            // Now draw the lightning streaks.

            DrawLightningStreak(lineBatch, color, upperLeft, upperRight, numSegments, deviation);
            DrawLightningStreak(lineBatch, color, upperRight, lowerRight, numSegments, deviation);
            DrawLightningStreak(lineBatch, color, lowerRight, lowerLeft, numSegments, deviation);
            DrawLightningStreak(lineBatch, color, lowerLeft, upperLeft, numSegments, deviation);
        }
예제 #3
0
        /// <summary>
        /// Draws the grid, showing the springs connecting neighboring nodes as line segments. The color of each
        /// line segment is interpolated linearly between dimColor and brightColor depending on the length
        /// of the segment.
        /// </summary>
        public void Draw(LineBatch lineBatch, Color dimColor, Color brightColor)
        {
            float dx = (bounds.Right - bounds.Left) / gridSize;
            float dy = (bounds.Bottom - bounds.Top) / gridSize;

            Vector4 vecDimColor = new Vector4(dimColor.R, dimColor.G, dimColor.B, dimColor.A);
            Vector4 vecBrightColor = new Vector4(brightColor.R, brightColor.G, brightColor.B, brightColor.A);

            for (int x = 0; x < gridSize; ++x)
            {
                for (int y = 0; y < gridSize; ++y)
                {
                    if (x < gridSize - 1)
                    {
                        float lineLength = (grid[x + 1, y].Position - grid[x, y].Position).Length();
                        float t = (lineLength - dx) / (5 * (float)Math.Sqrt(2) * dx);

                        Vector4 modulatedColorVec = Vector4.Lerp(vecDimColor, vecBrightColor, t);
                        Color modulatedColor = new Color((byte)modulatedColorVec.X, (byte)modulatedColorVec.Y, (byte)modulatedColorVec.Z,
                                                         (byte)modulatedColorVec.W);

                        lineBatch.DrawLine(grid[x, y].Position, grid[x + 1, y].Position, modulatedColor);
                    }

                    if (y < gridSize - 1)
                    {
                        float lineLength = (grid[x, y + 1].Position - grid[x, y].Position).Length();
                        float t = (lineLength - dy) / (5 * (float)Math.Sqrt(2) * dx);

                        Vector4 modulatedColorVec = Vector4.Lerp(vecDimColor, vecBrightColor, t);
                        Color modulatedColor = new Color((byte)modulatedColorVec.X, (byte)modulatedColorVec.Y, (byte)modulatedColorVec.Z,
                                                         (byte)modulatedColorVec.W);

                        lineBatch.DrawLine(grid[x, y].Position, grid[x, y + 1].Position, modulatedColor);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Frees graphics content
        /// </summary>
        public override void UnloadGraphicsContent(bool unloadAllContent)
        {
            if (unloadAllContent)
            {
                if (spriteBatch != null)
                {
                    spriteBatch.Dispose();
                    spriteBatch = null;
                }

                if (lineBatch != null)
                {
                    lineBatch.Dispose();
                    lineBatch = null;
                }

                content.Unload();
                actorManager.Unload();
            }
        }
예제 #5
0
        /// <summary>
        /// Loads graphics content needed for the game.
        /// </summary>
        public override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {
                if (content == null)
                    content = new ContentManager(ScreenManager.Game.Services, "Content");

                grid = new MassSpringGrid(60, 5f, 100f, 0.5f,
                    new Rectangle(safeAreaWidth, safeAreaHeight, screenSafeWidth, screenSafeHeight));

                actorManager = new ActorManager();

                #region Allocate graphics content

                spriteBatch = new SpriteBatch(ScreenManager.GraphicsDevice);
                lineBatch = new LineBatch(ScreenManager.GraphicsDevice);
                starTexture = content.Load<Texture2D>("blank");

                Animation countdownAnim = new Animation(content, 300, 100);
                countdownAnim.AddFrame(new AnimationFrame(TimeSpan.FromSeconds(2.0f / 3.0f), "ready"));
                countdownAnim.AddFrame(new AnimationFrame(TimeSpan.FromSeconds(2.0f / 3.0f), "set"));
                countdownAnim.AddFrame(new AnimationFrame(TimeSpan.FromSeconds(2.0f / 3.0f), "go"));

                countdownSprite = new Sprite();
                countdownSprite.AddAnimation("default", countdownAnim);
                countdownSprite.SetCurrentAnimation("default");

                #endregion

                #region Set up lightning boxes

                playerLightningBox = new LightningBox(new Rectangle(safeAreaWidth + 10, screenHeight - safeAreaHeight - 38 - 150, screenSafeWidth - 30, 150));
                computerLightningBox = new LightningBox(new Rectangle(safeAreaWidth + 10, safeAreaHeight + 38, screenSafeWidth - 30, 150));

                #endregion

                #region Collision Categories for physics

                // Collision Categories:
                //
                // 1 = player paddle
                // 10 = ball
                // 11 = gravity ball
                // 12 = obstacle
                // 13 = computer paddle
                // 14 = bullet
                // 20 = screen borders
                // 21 = player lightning box
                // 22 = borders for obstacles
                // 23 = computer lightning box

                #endregion

                #region Create Player Paddle Actor Template

                Actor playerPaddleTemplate = new Actor(ScreenManager.Game,
                    new ActorBehavior[] { new GamePadPaddleController(actorManager),
                                          new DistortGridBehavior(actorManager, grid, DistortGridDetail.High),
                                          new ConstrainToRectangleBehavior(actorManager, playerLightningBox.Rectangle,
                                                                           Physics.Enums.CollisionCategories.Cat21) },
                    content, "paddle", 100, 100 * 0.174089069f);

                playerPaddleTemplate.PhysicsBody =
                    Physics.Dynamics.BodyFactory.Instance.CreateRectangleBody(playerPaddleTemplate.Sprite.Width,
                                                                              playerPaddleTemplate.Sprite.Height, 1);

                playerPaddleTemplate.PhysicsGeom =
                    Physics.Collisions.GeomFactory.Instance.CreateRectangleGeom(playerPaddleTemplate.PhysicsBody,
                    playerPaddleTemplate.Sprite.Width, playerPaddleTemplate.Sprite.Height);

                playerPaddleTemplate.PhysicsGeom.CollisionCategories = Physics.Enums.CollisionCategories.Cat1;
                playerPaddleTemplate.PhysicsGeom.CollidesWith = Physics.Enums.CollisionCategories.Cat1 |
                                                          Physics.Enums.CollisionCategories.Cat10 |
                                                          Physics.Enums.CollisionCategories.Cat11;

                playerPaddleTemplate.PhysicsBody.LinearDragCoefficient = 0.01f;
                playerPaddleTemplate.PhysicsBody.RotationalDragCoefficient = 300.0f;

                actorManager.AddActorTemplate(playerPaddleTemplate, "Player Paddle");

                #endregion

                #region Create Computer Paddle Actor Template

                Actor computerPaddleTemplate = new Actor(ScreenManager.Game,
                    new ActorBehavior[] { new DistortGridBehavior(actorManager, grid, DistortGridDetail.High),
                                          new ConstrainToRectangleBehavior(actorManager, computerLightningBox.Rectangle,
                                                                           Physics.Enums.CollisionCategories.Cat23),
                                          new AIPaddleController(actorManager) },
                    content, "paddle2", 100, 100 * 0.174089069f);

                computerPaddleTemplate.PhysicsBody =
                    Physics.Dynamics.BodyFactory.Instance.CreateRectangleBody(playerPaddleTemplate.Sprite.Width,
                                                                              playerPaddleTemplate.Sprite.Height, 1);

                computerPaddleTemplate.PhysicsGeom =
                    Physics.Collisions.GeomFactory.Instance.CreateRectangleGeom(playerPaddleTemplate.PhysicsBody,
                    playerPaddleTemplate.Sprite.Width, playerPaddleTemplate.Sprite.Height);

                computerPaddleTemplate.PhysicsGeom.CollisionCategories = Physics.Enums.CollisionCategories.Cat13;
                computerPaddleTemplate.PhysicsGeom.CollidesWith = Physics.Enums.CollisionCategories.Cat13 |
                    Physics.Enums.CollisionCategories.Cat10 | Physics.Enums.CollisionCategories.Cat11;

                computerPaddleTemplate.PhysicsBody.LinearDragCoefficient = 0.01f;
                computerPaddleTemplate.PhysicsBody.RotationalDragCoefficient = 300.0f;

                actorManager.AddActorTemplate(computerPaddleTemplate, "Computer Paddle");

                #endregion

                #region Create Obstacle Actor Template

                Actor obstacleActorTemplate = new Actor(ScreenManager.Game,
                    new ActorBehavior[] { new DistortGridBehavior(actorManager, grid, DistortGridDetail.High),
                                          new ConstrainToRectangleBehavior(actorManager, new Rectangle(
                        computerLightningBox.Rectangle.X,
                        computerLightningBox.Rectangle.Y + computerLightningBox.Rectangle.Height,
                        computerLightningBox.Rectangle.Width,
                        playerLightningBox.Rectangle.Y - (computerLightningBox.Rectangle.Y + computerLightningBox.Rectangle.Height)),
                                                                           Physics.Enums.CollisionCategories.Cat22),
                                          new ShootOffRandomlyBehavior(actorManager, 300, 350),
                                          new InteractWithBlackHolesBehavior(actorManager) },
                    content, "obstacle", 45.0f, 45.0f);

                obstacleActorTemplate.PhysicsBody =
                    Physics.Dynamics.BodyFactory.Instance.CreateRectangleBody(obstacleActorTemplate.Sprite.Width,
                                                                              obstacleActorTemplate.Sprite.Height, 0.001f);

                obstacleActorTemplate.PhysicsGeom =
                    Physics.Collisions.GeomFactory.Instance.CreateRectangleGeom(obstacleActorTemplate.PhysicsBody,
                    obstacleActorTemplate.Sprite.Width, obstacleActorTemplate.Sprite.Height);

                obstacleActorTemplate.PhysicsGeom.CollisionCategories = Physics.Enums.CollisionCategories.Cat12;
                obstacleActorTemplate.PhysicsGeom.CollidesWith = Physics.Enums.CollisionCategories.Cat1 |
                    Physics.Enums.CollisionCategories.Cat10 | Physics.Enums.CollisionCategories.Cat11 |
                    Physics.Enums.CollisionCategories.Cat12;

                obstacleActorTemplate.PhysicsBody.LinearDragCoefficient = 0.0f;

                actorManager.AddActorTemplate(obstacleActorTemplate, "Obstacle");

                #endregion

                #region Create Ball Actor Template

                float ballDiameter = 25.0f;

                Actor ballTemplate = new Actor(ScreenManager.Game,
                    new ActorBehavior[] { new DistortGridBehavior(actorManager, grid, DistortGridDetail.High),
                                          new ConstrainToRectangleBehavior(actorManager, new Rectangle(safeAreaWidth, safeAreaHeight, screenSafeWidth, screenSafeHeight),
                                                                           Physics.Enums.CollisionCategories.Cat20),
                                          new ShootOffRandomlyBehavior(actorManager, 300, 301.0f),
                                          new InteractWithBlackHolesBehavior(actorManager) },
                    content, "ball", ballDiameter, ballDiameter);

                ballTemplate.PhysicsBody =
                    Physics.Dynamics.BodyFactory.Instance.CreateCircleBody(ballDiameter / 2.0f, 0.001f);

                ballTemplate.PhysicsGeom =
                    Physics.Collisions.GeomFactory.Instance.CreateCircleGeom(ballTemplate.PhysicsBody, ballDiameter / 2.0f, 16);

                ballTemplate.PhysicsBody.LinearDragCoefficient = 0.0f;

                ballTemplate.PhysicsGeom.CollisionCategories = Physics.Enums.CollisionCategories.Cat10;
                ballTemplate.PhysicsGeom.CollidesWith = Physics.Enums.CollisionCategories.Cat1 |
                                                        Physics.Enums.CollisionCategories.Cat10 |
                                                        Physics.Enums.CollisionCategories.Cat13;

                actorManager.AddActorTemplate(ballTemplate, "Ball");

                #endregion

                #region Create Gravity Ball Actor Template

                float gravityBallDiameter = 55.0f;

                Actor gravBallTemplate = new Actor(ScreenManager.Game,
                    new ActorBehavior[] { new BlackHoleBehavior(actorManager, grid),
                                          new ConstrainToRectangleBehavior(actorManager, new Rectangle(safeAreaWidth, safeAreaHeight, screenSafeWidth, screenSafeHeight),
                                                                           Physics.Enums.CollisionCategories.Cat20),
                                          new LiveTemporarilyBehavior(actorManager, TimeSpan.FromSeconds(2.9f), TimeSpan.FromSeconds(0.5)) },
                    content, "GravityBall", gravityBallDiameter, 2.0f);

                gravBallTemplate.PhysicsBody =
                    Physics.Dynamics.BodyFactory.Instance.CreateCircleBody(gravityBallDiameter / 2.0f, 3.0f);

                gravBallTemplate.PhysicsGeom =
                    Physics.Collisions.GeomFactory.Instance.CreateCircleGeom(gravBallTemplate.PhysicsBody,
                    gravityBallDiameter / 2.0f, 16);

                gravBallTemplate.PhysicsBody.LinearDragCoefficient = 0.0f;

                gravBallTemplate.PhysicsGeom.CollisionCategories = Physics.Enums.CollisionCategories.Cat11;
                gravBallTemplate.PhysicsGeom.CollidesWith = Physics.Enums.CollisionCategories.Cat11 |
                    Physics.Enums.CollisionCategories.Cat10 | Physics.Enums.CollisionCategories.Cat1 |
                    Physics.Enums.CollisionCategories.Cat13;

                actorManager.AddActorTemplate(gravBallTemplate, "Gravity Ball");

                #endregion

                #region Create Bullet Actor Template

                float bulletDiameter = 5.0f;

                Actor bulletTemplate = new Actor(ScreenManager.Game,
                    new ActorBehavior[] { new ConstrainToRectangleBehavior(actorManager, new Rectangle(safeAreaWidth, safeAreaHeight, screenSafeWidth, screenSafeHeight),
                                                                           Physics.Enums.CollisionCategories.Cat20),
                                          new DieUponCollisionBehavior(actorManager),
                                          new InteractWithBlackHolesBehavior(actorManager) },
                    content, "projectile", bulletDiameter, bulletDiameter);

                bulletTemplate.PhysicsBody =
                    Physics.Dynamics.BodyFactory.Instance.CreateCircleBody(bulletDiameter / 2.0f, 0.001f);

                bulletTemplate.PhysicsGeom =
                    Physics.Collisions.GeomFactory.Instance.CreateCircleGeom(bulletTemplate.PhysicsBody, bulletDiameter / 2.0f, 16);

                bulletTemplate.PhysicsBody.LinearDragCoefficient = 0.0f;

                bulletTemplate.PhysicsGeom.CollisionCategories = Physics.Enums.CollisionCategories.Cat14;
                bulletTemplate.PhysicsGeom.CollidesWith = Physics.Enums.CollisionCategories.Cat1 |
                    Physics.Enums.CollisionCategories.Cat10 | Physics.Enums.CollisionCategories.Cat11 |
                    Physics.Enums.CollisionCategories.Cat12 | Physics.Enums.CollisionCategories.Cat13;

                actorManager.AddActorTemplate(bulletTemplate, "Bullet");

                #endregion

                #region Place basic gameplay objects

                playerPaddle = actorManager.InstantiateTemplate("Player Paddle");
                playerPaddle.PhysicsBody.Position = new Vector2(safeAreaWidth + screenSafeWidth / 2.0f, screenHeight - safeAreaHeight - 38 - 150 / 2);

                computerPaddle = actorManager.InstantiateTemplate("Computer Paddle");
                computerPaddle.PhysicsBody.Position = new Vector2(safeAreaWidth + screenSafeWidth / 2.0f, safeAreaHeight + 38 + 150 / 2);

                ball = actorManager.InstantiateTemplate("Ball");
                ball.PhysicsBody.Position = new Vector2(safeAreaWidth + screenSafeWidth / 2, safeAreaHeight + screenSafeHeight / 2);
                PauseBallForNewRound();

                ShootOffRandomlyBehavior shootOffBehavior = (ShootOffRandomlyBehavior)ball.GetBehavior(typeof(ShootOffRandomlyBehavior));
                shootOffBehavior.JustStarting = false;

                AIPaddleController ai = (AIPaddleController)computerPaddle.GetBehavior(typeof(AIPaddleController));
                ai.Ball = ball;

                PopulateArenaWithObstacles();

                #endregion
            }

            // Set the projection matrix for the line batch
            lineBatch.SetProjection(Matrix.CreateOrthographicOffCenter(
                0.0f, ScreenManager.GraphicsDevice.Viewport.Width,
                ScreenManager.GraphicsDevice.Viewport.Height, 0.0f, 0.0f, 1.0f));
        }