示例#1
0
        private void button1_Click(object sender, EventArgs e)
        {
            PictureBox usebox = Pictestellipse;

            cBall ballhit = new cBall(new PointF(100, 100), new PointF(2, 7));
            EllipseBlock eb = new EllipseBlock(new RectangleF(90, 105, 32, 16));

            var Ballpoly = ballhit.GetBallPoly();
            var EllipsePoly = eb.GetPoly();
            /*
                   Polygon ballpoly = ballhit.GetBallPoly();
            Vector Adjustment = new Vector();
            GeometryHelper.PolygonCollisionResult pcr = GeometryHelper.PolygonCollision(EllipsePoly, ballpoly, new Vector(ballhit.Velocity.X,ballhit.Velocity.Y));

            //minimumtranslationvector will be the normal we want to mirror the ball speed through.
            ballhit.Velocity = ballhit.Velocity.Mirror(pcr.MinimumTranslationVector);
            ballhit.Velocity = new PointF(-ballhit.Velocity.X, -ballhit.Velocity.Y);
            ballhit.Location = new PointF(ballhit.Location.X + Adjustment.X, ballhit.Location.Y + Adjustment.Y);

             * */

            GeometryHelper.PolygonCollisionResult pcr =
                GeometryHelper.PolygonCollision(EllipsePoly, Ballpoly, new Vector(ballhit.Velocity.X, ballhit.Velocity.Y));
            PointF reflectedVelocity = ballhit.Velocity;

            //only if an intersection occurs or will occur.
            if (pcr.Intersect || pcr.WillIntersect)
            {
                //minimumtranslationvector should work to be used as the normal to reflect across.

            }

            //calculate Normal of ellipse at that position.

            var addevent = new PaintEventHandler((g, pea) =>
            {
                ballhit.Draw(pea.Graphics);
                eb.Draw(pea.Graphics);

            });
            usebox.Paint += addevent;

            //force update.
            usebox.Invalidate();
            usebox.Update();
        }
示例#2
0
 public override bool HitBlock(BCBlockGameState currentstate,cBall ballobject, Block blockhit)
 {
     return !(blockhit.MustDestroy());
 }
示例#3
0
            /// <summary>
            /// 
            /// </summary>
            /// <param name="Origin">cBall object to be used as the origin location for rotary calculations.</param>
            /// <param name="Derived"></param>
            public SpinShotsubBallInfo(cBall pOrigin, cBall pDerived, double pAngle, double pAngleSpeed, double pRadius)
            {
                OriginBall = pOrigin;
                    BallObject = pDerived;

                    Angle = pAngle;
                    AngleSpeed = pAngleSpeed;
                    Radius = pRadius;
                    //hook our ball's BallImpact Event...
                    BallObject.BallImpact += new cBall.ballimpactproc(BallObject_BallImpact);
                    //the "owner" class should be hooking it as well so that we (as a SpinShotsubballinfo) are removed from any relevant future calculations,
                    //allowing the ball to "fly off".
            }
示例#4
0
        public void SparkleEmitter(cBall ballobj, BCBlockGameState gamestate)
        {
            PointF VelocityUse = new PointF((float)(ballobj.Velocity.X * 0.1 + (BCBlockGameState.rgen.NextDouble() - 0.5) * 2),
                    (float)(ballobj.Velocity.Y * 0.1 + (BCBlockGameState.rgen.NextDouble() - 0.5) * 2));
                Color usesparklecolor = BCBlockGameState.Choose(new Color[] { Color.Red, Color.Yellow, Color.LimeGreen, Color.Pink, Color.Magenta, Color.Chartreuse });
                if (BCBlockGameState.rgen.NextDouble() > 0.8) return; //don't add a particle.
                if (BCBlockGameState.rgen.NextDouble() > 0.5)
                {

                    VelocityUse = new PointF(0, 0);

                }
                gamestate.Particles.Add(new Sparkle(ballobj.Location, VelocityUse, usesparklecolor));
        }
示例#5
0
        public List<Block> proxyperformframe(cBall ballobject, BCBlockGameState ParentGameState, ref List<cBall> ballsadded, ref List<cBall> ballsremove, out bool removethis)
        {
            removethis = false;
                if (proxylife.ContainsKey(ballobject))
                {
                    proxylife[ballobject]++;

                }
                else
                {
                    proxylife.Add(ballobject, 0);
                }
                if (proxylife[ballobject] > 0)
                {
                    Debug.Print("force removing a ball");
                    removethis = true;

                }
                return null;
        }
示例#6
0
 public BallBehave(cBall ballBehavioursEdit)
 {
     _ballEdit = ballBehavioursEdit;
     InitializeComponent();
 }
 public PolygonObstacleBaseEventArgs(BCBlockGameState pgstate, cBall pBall, PolygonObstacle pObstacle)
 {
     _gameState = pgstate;
     _Ball = pBall;
     _Obstacle = pObstacle;
 }
示例#8
0
 public abstract List<Block> FrameTick(cBall ballobject, BCBlockGameState ParentGameState, ref List<cBall> ballsadded, ref List<cBall> ballsremove, out bool removethis);
示例#9
0
 public override sealed List<Block> PerformFrame(cBall ballobject, BCBlockGameState ParentGameState, ref List<cBall> ballsadded, ref List<cBall> ballsremove, out bool removethis)
 {
     List<Block> result = FrameTick(ballobject, ParentGameState, ref ballsadded, ref ballsremove, out removethis);
     removethis = Destroyself || removethis;
     return result;
 }
示例#10
0
 public virtual void BehaviourRemoved(cBall onBall, BCBlockGameState currstate)
 {
 }
示例#11
0
        public override void BehaviourAdded(cBall onBall, BCBlockGameState currstate)
        {
            base.BehaviourAdded(onBall, currstate);

            //start timer...
            currstate.DelayInvoke(_TimeLength, DelayRoutine, null);
        }
示例#12
0
        public override List<Block> PerformFrame(cBall ballobject, BCBlockGameState ParentGameState, ref List<cBall> ballsadded, ref List<cBall> ballsremove, out bool removethis)
        {
            //if (ballobject.Behaviours.Count <= 2)
            //{   //only if we are the only behaviour...
                for (int i = 0; i < (int) (7*BCBlockGameState.ParticleGenerationFactor); i++)
                {
                    ParentGameState.Particles.Add(new FireParticle(ballobject));

                }
            //}
            return base.PerformFrame(ballobject, ParentGameState, ref ballsadded, ref ballsremove,out removethis);
        }
示例#13
0
 public override HitWallReturnConstants HitWall(BCBlockGameState currentstate, cBall ballobject)
 {
     _NumBounces--;
     if(_NumBounces <= 0) return HitWallReturnConstants.HitBall_Destroy; //is destroyed regardless.
     return HitWallReturnConstants.HitBall_Default;
 }
示例#14
0
 public override bool HitBlock(BCBlockGameState currentstate, cBall ballobject, Block blockhit)
 {
     //currentstate.Balls.Remove(ballobject);
     return true;
 }
示例#15
0
 public void invokeballimpact(cBall withball)
 {
     bool doignore = false;
     ballimpactproc tempcopy = BallImpact;
     if (tempcopy != null)
         tempcopy.Invoke(withball);
 }
示例#16
0
        public override void BehaviourAdded(cBall onBall, BCBlockGameState currstate)
        {
            base.BehaviourAdded(onBall, currstate);
                    BaseBehaviour AddedBehaviour = (BaseBehaviour)Activator.CreateInstance(useBehaviour);

                    currstate.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => onBall.Behaviours.Add(AddedBehaviour)));

                    currstate.DelayInvoke(_Span,delayroutine,new object[]{onBall,AddedBehaviour});
        }
示例#17
0
 public void invokebeforeblockimpact(cBall withball)
 {
     ballimpactproc tempcopy = BeforeBallImpact;
     if (tempcopy != null) tempcopy.Invoke(withball);
 }
示例#18
0
 public virtual bool HitBlock(BCBlockGameState currentstate, cBall ballobject, Block blockhit)
 {
     //throw new NotImplementedException();
     return true;
 }
示例#19
0
        protected bool InvokeObstacleHit(BCBlockGameState gstate,cBall Source,PolygonObstacle obstacle)
        {
            var copied = ObstacleHit;
            if (copied != null)
            {
                var created = new PolygonObstacleHitEventArgs(gstate, Source, obstacle);
                copied(this, created);
                return created.Cancel;
            }

            return false;
        }
示例#20
0
        public override List<Block> PerformFrame(cBall ballobject, BCBlockGameState ParentGameState, ref List<cBall> ballsadded, ref List<cBall> ballsremove, out bool removethis)
        {
            //spew out 3 waterparticles at random velocities (<=2)
            const int WaterBallSpewCount = 1;
            for (int i = 1; i < WaterBallSpewCount; i++)
            {
                //calculate the random velocities.
                float xvel = ((float)BCBlockGameState.rgen.NextDouble() * 2) - 1f;
                float yvel = ((float)BCBlockGameState.rgen.NextDouble() * 2) - 1f;
                //add current ball speeds by a factor of .3.
                xvel+= (ballobject.Velocity.X/3);
                yvel+=(ballobject.Velocity.Y/3);
                PointF pointvelocity = new PointF(xvel,yvel);
                //create and add the new particle.
               // ParentGameState.Particles.Add(new WaterParticle(ballobject.Location, pointvelocity));
            }

            return base.PerformFrame(ballobject, ParentGameState, ref ballsadded, ref ballsremove,out removethis);
        }
示例#21
0
 public PolygonObstacleHitEventArgs(BCBlockGameState pgstate, cBall pBall, PolygonObstacle pObstacle)
     : base(pgstate, pBall, pObstacle)
 {
 }
示例#22
0
 public virtual HitWallReturnConstants HitWall(BCBlockGameState currentstate, cBall ballobject)
 {
     // throw new NotImplementedException();
     return HitWallReturnConstants.HitBall_Default;
 }
示例#23
0
        public override bool PerformFrame(BCBlockGameState gamestate)
        {
            bool retval = base.PerformFrame(gamestate);

                //add some particles around the edges of the explosion, moving outward...
                if (gamestate.Particles.Count((w)=>!w.Important) < BCBlockGameState.MaxParticles)
                {
                    for (int i = 0; i < (int)(25f * BCBlockGameState.ParticleGenerationFactor); i++)
                    {
                        const float speedmult = 1;
                        //choose a random Angle...
                        double randomangle = Math.PI * 2 * BCBlockGameState.rgen.NextDouble();
                        //create the appropriate speed vector, based on our radius...
                        double usespeed = (_CurrentRadius / _MaxRadius) * speedmult;
                        //should be proportional to how close we are to the maximum radius; max radius will have particles move 1...
                        usespeed += ((BCBlockGameState.rgen.NextDouble() * 0.6) - 0.3);

                        PointF addpointLocation = new PointF(Location.X + (float)Math.Cos(randomangle) * _CurrentRadius,
                                                             Location.Y + (float)Math.Sin(randomangle) * _CurrentRadius);

                        //create a dustparticle...
                        PointF PointSpeed = new PointF((float)(Math.Cos(randomangle) * usespeed),
                                                       (float)(Math.Sin(randomangle) * usespeed));
                        Particle addparticle = null;
                        if (i % 5 != 0)
                        {
                            addparticle = new DustParticle(addpointLocation, PointSpeed);

                        }
                        else if (_ShowOrbs)
                        {
                            //LightOrb...
                            LightOrb lo = new LightOrb(addpointLocation, ExplosionColor,
                                                       (float)BCBlockGameState.rgen.NextDouble() * 10 + 5);
                            lo.Velocity = PointSpeed;
                            addparticle = lo;

                        }

                        if (addparticle != null) gamestate.Particles.Add(addparticle);

                    }
                }

                //each frame, check for blocks that are within the given radius. Hell with it, we'll check their centerpoints...

                if (gamestate.PlayerPaddle != null)
                {
                    //if(

                    if (DamagePaddle && BCBlockGameState.RectangleIntersectsCircle(gamestate.PlayerPaddle.Getrect(), Location, _CurrentRadius))
                    {

                        gamestate.PlayerPaddle.HP -= 1f;
                    }
                }

                if (_EffectObjects)
                {
                    //find all GameObjects that implement IExplodable.
                    //we might be bothered to do the same for Balls, I suppose. No promises.

                    IEnumerable<IExplodable> result = BCBlockGameState.Join<IExplodable>(
                        (from ball in gamestate.Balls where ball is IExplodable && (BCBlockGameState.Distance(Location,ball.Location) < _CurrentRadius)  select ball as IExplodable),
                        (from obj in gamestate.GameObjects where obj is IExplodable select obj as IExplodable));

                        //in order to prevent contention issues, we will defer the loop that "effects" each item until the next gametick iteration starts.
                    gamestate.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() =>
                    {
                        foreach (var iterateresult in result)
                        {

                            PointF useVelocityEffect = new PointF(Math.Max(1,Velocity.X),Math.Max(1,Velocity.Y));

                            iterateresult.ExplosionInteract(this, Location, useVelocityEffect);

                        }

                    }));

                }

                List<Block> removethese = new List<Block>();
                if (_DamageBlocks)
                {
                    var blowemup = from p in gamestate.Blocks
                                   where
                                       BCBlockGameState.Distance(Location.X, Location.Y, p.CenterPoint().X,
                                                                 p.CenterPoint().Y) < _CurrentRadius
                                   select p;
                    if (blowemup.Any())
                    {
                        foreach (var loopblock in blowemup)
                        {
                            //destroy it.

                            if (loopblock is DestructionBlock)
                            {
                                //special handling for combos
                                Debug.Print("DestructionBlock detected in ExplosionEffect...");
                                (loopblock as DestructionBlock).ComboCount = this.ComboCount + 1;

                            }
                            if (DestroyAll || loopblock.MustDestroy())
                            {
                                loopblock.StandardSpray(gamestate);
                                removethese.Add(loopblock);
                            }

                        }

                        lock (gamestate.Blocks)
                        {
                            foreach (Block removeit in removethese)
                            {
                                //get angle between the center of the explosion and the block's center.
                                double Angle = BCBlockGameState.GetAngle(CenterPoint(), removeit.CenterPoint());
                                int useSpeed = BCBlockGameState.ClampValue((int)_MaxRadius / 2, 1, 5);
                                PointF useVelocity = BCBlockGameState.GetVelocity(useSpeed, Angle);
                                cBall tempball = new cBall(new PointF(removeit.CenterPoint().X-useVelocity.X,removeit.CenterPoint().Y-useVelocity.Y), useVelocity);
                                tempball.PreviousVelocity = useVelocity;
                                tempball.Behaviours.Add(new TempBallBehaviour());
                                //add a proxy behaviour to remove it as well.
                                //tempball.Behaviours.Add(new ProxyBallBehaviour("ExplosionEffect", null, proxyperformframe, null, null, null, null, null, null));
                                //gamestate.Balls.AddLast(tempball);

                                List<cBall> discardlist = new List<cBall>();
                                try
                                {
                                    //this is... well, cheating...

                                    //we cannot add GameObjects to the List, except by plopping them in the ref AddedObject parameter.
                                    //however, we cannot "force" the PerformBlockHit of a block (say a destruction block) to add a GameObject (another ExplosionEffect, in that case)

                                    //we cheat. we swap out the entire gamestate.GameObject LinkedList with a new one, call the routine, and then
                                    //we add any added GameObjects to our ref parameter, and swap the old list back in, hoping nobody notices our
                                    //audacity to fiddle with core game state objects...
                                    var copiedref = gamestate.GameObjects;
                                    gamestate.GameObjects = new LinkedList<GameObject>();

                                    removeit.PerformBlockHit(gamestate, tempball);
                                    gamestate.Blocks.Remove(removeit);
                                    var tempadded = gamestate.GameObjects;
                                    gamestate.GameObjects = copiedref;
                                    //now we add the ones we need to add to our ref array. I feel dirty.
                                    gamestate.Defer(() =>
                                    {
                                        foreach (var iterate in tempadded)
                                        {
                                            gamestate.GameObjects.AddLast(iterate);
                                        }

                                    });

                                }
                                catch
                                {

                                }
                                //we don't add the ball to our GameState, so we don't have to worry about it persisting :D

                                //the idea is that we want to invoke the actions of the block (which for many blocks will simply be destroyed).
                                //at the same time, some blocks might react weirdly to having temporary balls tossed into their centers, so we make it so the ball will only live for
                                //two frames by adding a proxyballbehaviour that ensure that.
                                //gamestate.Blocks.Remove(removeit);
                                gamestate.Forcerefresh = true;
                            }

                            //changed: instead of removing them, create a temporary ball at their center point.

                        }

                    }
                }

                return retval;
        }
示例#24
0
        public virtual List<Block> PerformFrame(cBall ballobject, BCBlockGameState ParentGameState, ref List<cBall> ballsadded, ref List<cBall> ballsremove,out bool removethis)
        {
            removethis=false;
            if(!mInitialized)
            {
                useball = ballobject;
                prevstate = ParentGameState;
                BehaviourAdded(ballobject, ParentGameState);
                mInitialized=true;

            }
            //throw new NotImplementedException();
            return null;
        }
示例#25
0
        /// <summary>
        /// Creates the Spinshot, using the given ball as the origin
        /// </summary>
        /// <param name="gamestate"></param>
        /// <param name="useorigin"></param>
        /// <param name="pLocation"></param>
        /// <param name="Numorbit"></param>
        /// <param name="radius"></param>
        /// <param name="rotationspeed"></param>
        /// <param name="pVelocity"></param>
        public SpinShot(BCBlockGameState gamestate, cBall useorigin, PointF pLocation, int Numorbit, float radius, float rotationspeed)
            : base(pLocation, useorigin.Velocity)
        {
            SubObjects = new List<SpinShotsubBallInfo>();
                OurBall = useorigin;

                OurBall.BallImpact += new cBall.ballimpactproc(OurBall_BallImpact);
                gamestate.Balls.AddLast(OurBall);
                //we let the game logic handle the ball, but our performframe will "update" the position of the sub-balls.
                //speaking of which- we need to create those.
                float Angleuse = (float)((Math.PI * 2) / Numorbit);
                float useangle = 0;
                for (int i = 0; i < Numorbit; i++)
                {
                    useangle = ((float)i) * Angleuse;
                    PointF useposition = new PointF((float)(Math.Cos(useangle) * radius) + pLocation.X,
                        (float)(Math.Sin(useangle) * radius) + pLocation.Y);
                    cBall derivedball = new cBall(useposition, new PointF(0.1f, 0.1f));
                    //derivedball.Behaviours.Add(new TempBallBehaviour());
                    derivedball.Behaviours.Add(new NonReboundableBallBehaviour());
                    derivedball.Behaviours.Add(new ParticleEmitterBehaviour(SparkleEmitter));
                    derivedball.DrawPen = new Pen(Color.Transparent);
                    derivedball.DrawBrush = spinshotbrush;
                    SpinShotsubBallInfo subinfo = new SpinShotsubBallInfo(OurBall, derivedball, useangle, rotationspeed, radius);
                    SubObjects.Add(subinfo);
                    gamestate.Balls.AddLast(derivedball);

                }
        }
示例#26
0
        public cBall(cBall clonethis)
        {
            Radius = clonethis.Radius;
            Location = clonethis.Location;
            Velocity = clonethis.Velocity;
            DrawBrush = (Brush)clonethis.DrawBrush.Clone();
            DrawPen = (Pen)clonethis.DrawPen.Clone();
            //Behaviours = clonethis.Behaviours;
            //Don't Set Behaviours directly. go through each.
            foreach (var loopbehave in clonethis.Behaviours)
            {
                Behaviours.Add(loopbehave);

            }

            DrawColor = clonethis.DrawColor;
        }
示例#27
0
        void OurBall_BallImpact(cBall ballimpact)
        {
            //throw new NotImplementedException();
                hasbeendestroyed = true;

                //release All the balls in our subobjects.
                foreach (var subobj in SubObjects)
                {
                    subobj.ReleaseBall();

                }
                SubObjects = new List<SpinShotsubBallInfo>();
        }
示例#28
0
        public static void CollideBalls(cBall BallA, cBall BallB)
        {
            double RatioA = BallB.Mass / (BallA.Mass + BallB.Mass);
            double RatioB = BallA.Mass / (BallA.Mass + BallB.Mass);

            //Get the velocities of each ball.
            PointF VelR = new PointF(BallB.Velocity.X-BallA.Velocity.X,BallB.Velocity.Y-BallA.Velocity.Y);
            //I = (1+e)*N*(Vr • N)

            //Va = -I*(Mb / (Ma+Mb))
            //Vb = +I*(Ma / (Ma+Mb))

            //angle between the two balls.
            double angle = BCBlockGameState.GetAngle(BallA.Location,BallB.Location);
            //create a vector of magnitude 1 of that angle.
            PointF N = new PointF((float)Math.Cos(angle),(float)Math.Sin(angle));
        }
示例#29
0
 void BallObject_BallImpact(cBall ballimpact)
 {
     //release the ball... Set it's Speed to getSpeedVector.
         ballimpact.Velocity = getSpeedVector();
         //"owner" SpinShot will properly 'release' the ball by removing us from the collection.
 }
示例#30
0
        public override List<Block> PerformFrame(cBall ballobject, BCBlockGameState ParentGameState, ref List<cBall> ballsadded, ref List<cBall> ballsremove, out bool removethis)
        {
            List<Block> returnval = base.PerformFrame(ballobject, ParentGameState, ref ballsadded, ref ballsremove, out removethis);
            if (!Waiting)
            {
                //if we aren't "waiting", then set waiting to true, cache the current speed of the ball, and initialize startWaitTime.

                cachedSpeed = ballobject.Velocity;
                ballobject.Velocity = PointF.Empty; //set speed to 0
                Waiting=true;
                startWaitTime=DateTime.Now;
                prevbehaviours=ballobject.Behaviours;
                ballobject.Behaviours = new List<iBallBehaviour>();
                ballobject.Behaviours.Add(this);

            }
            else if(Waiting)
            {
                //if we <ARE> waiting, then check the times.
                if (TimeElapsed > waitTime)
                {

                    //waiting is over!
                   ballobject.Velocity=cachedSpeed;
                   ballobject.Behaviours = prevbehaviours;
                    //and remove ourselves..
                    removethis=true;

                }
            }

            return returnval;
        }