/// <summary>
 /// Generates an Obstacle at the given location with a random number of points created using a random radius.
 /// </summary>
 /// <param name="pLocation"></param>
 /// <param name="MinPoints"></param>
 /// <param name="MaxPoints"></param>
 /// <param name="MinRadius"></param>
 /// <param name="MaxRadius"></param>
 /// <param name="pDrawBrush"></param>
 /// <param name="pDrawPen"></param>
 public PolygonObstacle(PointF pLocation,int MinPoints,int MaxPoints,float MinRadius,float MaxRadius,PolygonBlockDrawMethod drawMethod)
     : base(pLocation,null,0)
 {
     _Location = pLocation;
     _Poly = new Polygon(BCBlockGameState.GenPoly(MinRadius,MaxRadius,MinPoints,MaxPoints));
     _Poly.Offset(pLocation);
     _DrawMethod = drawMethod;
     //base.Size = _Poly.GetBounds().Size;
 }
 public PolygonObstacle(IEnumerable<PointF> Points,Brush pDrawBrush,Pen pDrawPen)
     : base(CenterPoint(Points),null,0)
 {
     _DrawMethod = new FilledPolyDrawMethod(pDrawPen, pDrawBrush);
     _Poly = new Polygon(Points.ToArray());
     //base.Size = _Poly.GetBounds().Size;
 }
        public override bool PerformFrame(BCBlockGameState gamestate)
        {
            if (_Abilities.Any())
            {
                List<GameCharacterAbility> addabilities = new List<GameCharacterAbility>();
                List<GameCharacterAbility> removeabilities = new List<GameCharacterAbility>();

                foreach (GameCharacterAbility gma in _Abilities)
                {
                    if (gma.PerformFrame(this, gamestate))
                        removeabilities.Add(gma);

                }
                foreach (var removeit in removeabilities)
                {
                    Abilities.Remove(removeit);
                }
                foreach (var addit in addabilities)
                {
                    Abilities.Add(addit);
                }

            }
            bool nobasecall = false;
            if (!flInit)
            {
                flInit = true;
                //hook the GameClient events...
                gamestate.ClientObject.ButtonDown += ClientObject_ButtonDown;
                gamestate.ClientObject.ButtonUp += ClientObject_ButtonUp;

            }
            if (EnemyAction == "DEATH") return base.PerformFrame(gamestate);
            if (EnemyAction == "DYING")
            {
                if (DateTime.Now - DeadTime.Value > new TimeSpan(0, 0, 0, 1))
                {
                    EnemyAction = "DEATH";
                    BCBlockGameState.Soundman.PlaySound("MARDEATH2");
                    Velocity = new PointF(0, -4);
                    _GravityEffect = new PointF(0, 8f);
                    Nocollisions = true;
                    nobasecall = true;

                }

                return base.PerformFrame(gamestate);

            }

            /*    case Keys.W:
             return ButtonConstants.Button_E;
             case Keys.A:
             return ButtonConstants.Button_F;
             case Keys.S:
             return ButtonConstants.Button_G;
             case Keys.D:
             return ButtonConstants.Button_H;*/
            if (EnemyAction == "IDLELEFT" || EnemyAction == "IDLERIGHT")
            {
                if (Buttonspressed[ButtonConstants.Button_F])
                {
                    EnemyAction = "WALKLEFT";

                }
                else if (Buttonspressed[ButtonConstants.Button_H])
                {
                    EnemyAction = "WALKRIGHT";

                }

            }

            switch (EnemyAction)
            {
                case "IDLELEFT":
                    if (!isonground) EnemyAction = "JUMPLEFT";
                    break;
                case "IDLERIGHT":
                    if (!isonground) EnemyAction = "JUMPRIGHT";
                    break;
                case "JUMPLEFT":
                    if (isonground)
                        EnemyAction = "WALKLEFT";
                    Decelerate();
                    break;
                case "JUMPRIGHT":
                    if (isonground)
                        EnemyAction = "WALKRIGHT";
                    Decelerate();
                    break;
                case "WALKLEFT":

                    Decelerate();
                    if (Math.Abs(Velocity.X) < 0.1) EnemyAction = "IDLELEFT";
                    if (!isonground) EnemyAction = "JUMPLEFT";
                    break;
                case "WALKRIGHT":
                    Decelerate();
                    if (Math.Abs(Velocity.X) < 0.1) EnemyAction = "IDLERIGHT";
                    if (!isonground) EnemyAction = "JUMPRIGHT";
                    break;

            }

            //check for ball collisions.
            foreach (var loopball in gamestate.Balls)
            {
                Polygon ppoly = loopball.GetBallPoly();
                Polygon boundbox = new Polygon(this.GetRectangleF());
                var result = GeometryHelper.PolygonCollision(ppoly, boundbox, new Vector(0, 0));
                if (result.Intersect)
                {
                    Die(gamestate);
                    break;

                }

            }

            if (!nobasecall) return base.PerformFrame(gamestate); else return false;
        }
        public override bool PerformFrame(BCBlockGameState gamestate)
        {
            if (Frozen) return false;
            PointF usedoffset=PointF.Empty;
            BCBlockGameState.IncrementLocation(gamestate, ref _Location, _Velocity,ref usedoffset);
            _Poly.Offset(usedoffset);
            if (!(new Polygon(gamestate.GameArea).Contains(_Poly)))
            {
                //reflect
                var result = GeometryHelper.PolygonCollision(new Polygon(gamestate.GameArea), _Poly, Velocity);
                var copied = new PointF(-result.MinimumTranslationVector.X, -result.MinimumTranslationVector.Y);
                if (Math.Abs(result.MinimumTranslationVector.X) > Math.Abs(result.MinimumTranslationVector.Y))
                {
                    //mirror X speed.
                    Velocity = new PointF(-Velocity.X, Velocity.Y);
                }
                else
                {
                    Velocity = new PointF(Velocity.X, -Velocity.Y);
                }

            }
            _Velocity = _VelocityDecayFunction(this, _Velocity);
            CurrAngle += AngleSpeed;
            _AngleSpeed = _AngleSpeedDecayFunction(this, _AngleSpeed);

            //check for ball collisions.
            foreach (cBall checkball in gamestate.Balls)
            {
                Polygon ballpoly = checkball.GetBallPoly();

                if (_Poly.IntersectsWith(ballpoly) && !InvokeBeforeObstacleHit(gamestate,checkball,this))
                {
                    //only if it intersects.
                    Vector Adjustment;
                    GeometryHelper.PolygonCollisionResult pcr = GeometryHelper.PolygonCollision(_Poly,
                                                                                                ballpoly, new Vector(checkball.Velocity.X+Velocity.X, checkball.Velocity.Y+Velocity.Y));

                    Adjustment = pcr.MinimumTranslationVector;
                    checkball.Velocity = checkball.Velocity.Mirror(pcr.MinimumTranslationVector);
                    checkball.Velocity = new PointF(checkball.Velocity.X, checkball.Velocity.Y);
                    checkball.Location = new PointF(checkball.Location.X - Adjustment.X, checkball.Location.Y - Adjustment.Y);
                    BCBlockGameState.Soundman.PlaySound("bounce");
                    //determine percentage of "knockback" to us based on the ratio between the ball radius and our average radius.
                    float ourAverage = _Poly.AverageRadius();
                    float ballradii = checkball.Radius;
                    float ratio = ballradii / ourAverage;
                    PointF mCenter = GetRectangle().CenterPoint();
                    Velocity = new PointF(Velocity.X + pcr.MinimumTranslationVector.X * ratio, Velocity.Y + pcr.MinimumTranslationVector.Y * ratio);
                    //get angle between the ball's previous location (assumed from the velocity) and it's current pos,
                    //with our center point as the pivot.
                    PointF PrevPosition = checkball.PrevLocation;
                    PointF CurrLocation = checkball.Location;
                    var PrevAngle = BCBlockGameState.GetAngle(mCenter, PrevPosition);
                    var CurrentAngle = BCBlockGameState.GetAngle(mCenter, CurrLocation);
                    AngleSpeed = CurrentAngle - PrevAngle;

                    //reduce our size, as well.
                    _Poly = _Poly.Scale(0.9f);

                    if (_Poly.Area() < MinimumSize && !InvokeObstacleHit(gamestate,checkball,this))
                    {
                        //Fire the OnDestroy event
                        if(!InvokeObstacleDestroy(gamestate,checkball,this))
                            return true; //tweak: make it explode or something, too.
                    }

                }

            }

            if (_fShoot)
            {
                if (delayoffset++ == _ShootDelay)
                {
                    delayoffset = 0;
                    //shoot lightning. Because lightning is da' shit.
                    //choose a random point on this polygon.
                    PointF selectedpoint = BCBlockGameState.Choose(Poly.Points);
                    //get angle between that point and the paddle.
                    //if there is no paddle, use a random value.
                    double fireangle = gamestate.PlayerPaddle != null ?
                                           BCBlockGameState.GetAngle(selectedpoint, gamestate.PlayerPaddle.CenterPoint()) :
                                           BCBlockGameState.rgen.NextDouble() * Math.PI * 2;
                    PointF createdvel = BCBlockGameState.VaryVelocity(new PointF((float)Math.Cos(fireangle), (float)Math.Sin(fireangle)), Math.PI / 12);

                    LightningShot ls = new LightningShot(selectedpoint, createdvel)
                                           {
                                               DamageBlocks = false,
                                               DamagePaddle = true
                                           };
                    gamestate.Defer(() => gamestate.GameObjects.AddLast(ls));
                }

            }

            return !gamestate.GameArea.IntersectsWith(_Poly.GetBounds().ToRectangle());
        }
Beispiel #5
0
        private void regenpoints()
        {
            PolyPoints = new List<PointF>();
            double currangle = 0, angleincrement = Math.PI / (NumPolyPoints * 2);

            for (int i = 0; i < NumPolyPoints; i++)
            {
                PolyPoints.Add(new PointF((float)(Math.Cos(currangle)*Radius),(float)(Math.Sin(currangle)*Radius)));

                currangle+=angleincrement;

            }
            BallPoly = new Polygon(PolyPoints.ToArray());
               //done...
        }
 public override void Draw(object source, Polygon pb, Graphics g)
 {
     var Grabpoints = pb.getPoints().ToArray();
     g.FillPolygon(_FillBrush, Grabpoints);
     //g.DrawPolygon(_LinePen, Grabpoints);
     foreach (var iterateA in Grabpoints)
     {
         foreach (var iterateB in Grabpoints)
         {
             if (iterateA != iterateB)
             {
                 //draw a line.
                 g.DrawLine(LinePen, iterateA, iterateB);
             }
         }
     }
 }
 // Calculate the projection of a polygon on an axis and returns it as a [min, max] interval
 public static void ProjectPolygon(Vector axis, Polygon polygon, ref float min, ref float max)
 {
     // To project a point on an axis use the dot product
     float d = axis.DotProduct(polygon.Points[0]);
     min = d;
     max = d;
     for (int i = 0; i < polygon.Points.Count; i++)
     {
         d = polygon.Points[i].DotProduct(axis);
         if (d < min)
         {
             min = d;
         }
         else
         {
             if (d > max)
             {
                 max = d;
             }
         }
     }
 }
        // Check if polygon A is going to collide with polygon B for the given velocity
        public static PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector velocity)
        {
            if (polygonA == null || polygonB == null)
            {
                Debug.Print("balls");

            }
            PolygonCollisionResult result = new PolygonCollisionResult();
            result.Intersect = true;
            result.WillIntersect = true;

            int edgeCountA = polygonA.Edges.Count;
            int edgeCountB = polygonB.Edges.Count;
            float minIntervalDistance = float.PositiveInfinity;
            Vector translationAxis = new Vector();
            Vector edge;

            // Loop through all the edges of both polygons
            for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++)
            {
                if (edgeIndex < edgeCountA)
                {
                    edge = polygonA.Edges[edgeIndex];
                }
                else
                {
                    edge = polygonB.Edges[edgeIndex - edgeCountA];
                }

                // ===== 1. Find if the polygons are currently intersecting =====

                // Find the axis perpendicular to the current edge
                Vector axis = new Vector(-edge.Y, edge.X);
                axis.Normalize();

                // Find the projection of the polygon on the current axis
                float minA = 0; float minB = 0; float maxA = 0; float maxB = 0;
                ProjectPolygon(axis, polygonA, ref minA, ref maxA);
                ProjectPolygon(axis, polygonB, ref minB, ref maxB);

                // Check if the polygon projections are currentlty intersecting
                if (IntervalDistance(minA, maxA, minB, maxB) > 0) result.Intersect = false;

                // ===== 2. Now find if the polygons *will* intersect =====

                // Project the velocity on the current axis
                float velocityProjection = axis.DotProduct(velocity);

                // Get the projection of polygon A during the movement
                if (velocityProjection < 0)
                {
                    minA += velocityProjection;
                }
                else
                {
                    maxA += velocityProjection;
                }

                // Do the same test as above for the new projection
                float intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.WillIntersect = false;

                // If the polygons are not intersecting and won't intersect, exit the loop
                if (!result.Intersect && !result.WillIntersect) break;

                // Check if the current interval distance is the minimum one. If so store
                // the interval distance and the current distance.
                // This will be used to calculate the minimum translation vector
                intervalDistance = Math.Abs(intervalDistance);
                if (intervalDistance < minIntervalDistance)
                {
                    minIntervalDistance = intervalDistance;
                    translationAxis = axis;

                    Vector d = polygonA.Center - polygonB.Center;
                    if (d.DotProduct(translationAxis) < 0) translationAxis = -translationAxis;
                }
            }

            // The minimum translation vector can be used to push the polygons appart.
            // First moves the polygons by their velocity
            // then move polygonA by MinimumTranslationVector.
            if (result.WillIntersect) result.MinimumTranslationVector = translationAxis * minIntervalDistance;

            return result;
        }
        //splits this polygon into triangular sectors, each of which is returned as a new polygon in the return array.
        public Polygon[] Split()
        {
            Polygon[] returnpoly = new Polygon[Points.Count];
            for (int i = 0; i < Points.Count - 1;i++ )
            {

                //First, second, Center will be the polygon order.
                Polygon pg = new Polygon(new PointF[] { Points[i], Points[i + 1], Center });

                returnpoly[i] = pg;
            }

            // add last poly. Last-First-Center
            returnpoly[returnpoly.Length - 1] = new Polygon(new PointF[] { Points.Last(), Points.First(), Center });

            return returnpoly;
        }
 public bool IntersectsWith(Polygon otherpoly)
 {
     return (GeometryHelper.PolygonCollision(this, otherpoly, new Vector(0, 0)).Intersect);
 }
 public bool Contains(Polygon Otherpoly)
 {
     return Otherpoly.Points.All(this.Contains);
 }