Beispiel #1
0
        public void ShowPath()
        {
            m_shootingBall = (Ball)m_aComingBalls[0];
            EPointF loc    = m_shootingBall.Loc;
            double  dAngle = -Math.PI * Angle / 180;
            float   fSpeed = 1000;
            EPointF pntVel = EPointF.FromLengthAndAngle(fSpeed, (float)dAngle);

            EPoint  pntGridStick = null;
            EPointF pntBounce;

            int nMaxTests = 40;             //if more bounces than this is calculated, then something has gone wrong as it's outside the system

//			EH.Put("Start at "+loc.ToString());
            while (nMaxTests-- > 0)
            {
                if (m_playArea.m_pathCalc.GetFirstStickOrBounce(ref loc, ref pntVel, out pntGridStick, out pntBounce, true) == false)
                {
//					EH.Put("Test num:"+nMaxTests.ToString() + " loc"+loc.ToString());
//					EH.Put("Bounce:" + loc.ToString()+" vel:"+pntVel.ToString());
//					loc = pntBounce.Copy();
                }
                else
                {
//					if (m_spTarget!=null)
//						m_spTarget.Loc = m_playArea.Grid.GetGfxLocFromGridLoc(pntGridStick);
                    break;
                }
            }
        }
Beispiel #2
0
        public override System.Collections.ArrayList GeneratePoints(EPoint ptStart)
        {
            //Calculate curve's control and end anchor points:
            //Control point is the start point + offset to control
            EPoint ptControl = ptStart + this._ptControl;
            //End point is control point + offset to anchor:
            EPoint ptAnchor = ptControl + this._ptAnchor;

            //now calculate two bezier handles for the curve (Flash uses quadratic beziers, GDI+ uses cubic).
            //The two handles are 2/3rds from each endpoint to the control point.
            EPointF diff  = (ptControl - ptStart).ToEPointF();
            EPointF ctrl1 = EPointF.FromLengthAndAngle(diff.Length * 2 / 3, diff.Angle) + ptStart.ToEPointF();

            //EPointF ctrl1 = ptStart.ToEPointF() + diff/2f;
            //EPointF ctrl1 = new EPointF(ptStart.X + (1f * (ptControl.X - ptStart.X) / 2f), ptStart.Y + (1f * (ptControl.Y - ptStart.Y) / 2f));

            diff = (ptControl - ptAnchor).ToEPointF();
            EPointF ctrl2 = EPointF.FromLengthAndAngle(diff.Length * 2 / 3, diff.Angle) + ptAnchor.ToEPointF();

            //diff = (ptAnchor-ptControl).ToEPointF();
            //EPointF ctrl2 = ptControl.ToEPointF() + diff/2f;
            //ctrl2 = new EPointF(ptControl.X + (1f * (ptAnchor.X - ptControl.X) / 2f), ptControl.Y + (1f * (ptAnchor.Y - ptControl.Y) / 2f));

            System.Collections.ArrayList pts = new System.Collections.ArrayList();
            pts.Add(ptStart.ToEPointF());
            pts.Add(ctrl1);
            pts.Add(ctrl2);
            pts.Add(ptAnchor.ToEPointF());
            return(pts);
        }
Beispiel #3
0
		public float CheckCollisionsWithBallFromTime(Ball a_ball, float a_fTime, ref PropsAtCollision[] propsAtCollisionList)
		{
			propsAtCollisionList[0].Ball = this;
			propsAtCollisionList[1].Ball = a_ball;

			float fCollisionTime;
			EPointF pntCircleAtCollisionLoc;
			EPointF pntTouchLoc;

			EPointF locThis = this.Loc + this.Velocity*a_fTime;
			EPointF velThis = this.Velocity*(1.0f-a_fTime);

			EPointF locOther = a_ball.Loc + a_ball.Velocity*a_fTime;
			EPointF velOther = a_ball.Velocity*(1.0f-a_fTime);

			if (Endogine.Collision.Collision.CalcFirstCircleCircleCollisions(locThis, locOther, velThis, velOther, this.Radius, a_ball.Radius, out pntCircleAtCollisionLoc, out fCollisionTime))
			{
				propsAtCollisionList[0].Loc = locThis+velThis*fCollisionTime;
				propsAtCollisionList[1].Loc = locOther + velOther*fCollisionTime;

				propsAtCollisionList[0].Velocity = this.Velocity.Copy();
				propsAtCollisionList[1].Velocity = a_ball.Velocity.Copy();

				EPointF relativeVel = this.Velocity-a_ball.Velocity;

				EPointF pntTmp = EPointF.FromLengthAndAngle(this.Radius, (propsAtCollisionList[1].Loc-propsAtCollisionList[0].Loc).Angle);
				pntTouchLoc = propsAtCollisionList[0].Loc+pntTmp;

				EPointF debugLoc = propsAtCollisionList[1].Loc-propsAtCollisionList[0].Loc;

				//the amount of energy transferred to the other depends on the collision angle vs the C:\Documents and Settings\Jonas\Mina dokument\Visual Studio Projects\EndoTest01\Endogine\Sprite.csrelative velocity's angle
				float velAngle = relativeVel.Angle;
				EPointF pntX = propsAtCollisionList[0].Loc - pntTouchLoc;
				float angleOrientation = Endogine.Collision.Collision.GetOrientationAngle(pntX.Angle - velAngle);
				//if "wall" is same angle as relative move angle: no energy transferred.
				//if "wall" is 90 degrees off, all energy is transferred.
				float fTransferredEnergyFactor = Math.Abs((float)((angleOrientation-Math.PI/2)/(Math.PI/2)));
				//float fTransferredEnergyFactor = (float)(Math.Cos(angleOrientation*2));

				EPointF pntDiff = propsAtCollisionList[1].Loc - pntTouchLoc;
				EPointF pntAddedVel = EPointF.FromLengthAndAngle(relativeVel.Length*fTransferredEnergyFactor, pntDiff.Angle);

				propsAtCollisionList[1].Velocity+=pntAddedVel;

				//total energy and angle must be the same, so adjust the other's velocity (must be an thought error somewhere?)
				propsAtCollisionList[0].Velocity = (this.Velocity+a_ball.Velocity) - propsAtCollisionList[1].Velocity;
				
//				propsAtCollisionList[0].Velocity = EPointF.FromLengthAndAngle(
//					(this.Velocity+a_ball.Velocity).Length - propsAtCollisionList[1].Velocity.Length,
//					(this.Velocity+a_ball.Velocity).Angle - propsAtCollisionList[1].Velocity.Angle);
				propsAtCollisionList[0].Velocity.Length = this.Velocity.Length+a_ball.Velocity.Length - propsAtCollisionList[1].Velocity.Length;

				return fCollisionTime * (1.0f-a_fTime) + a_fTime;
			}
			else
				return -1;
		}
Beispiel #4
0
        private void DrawLineWithCaps(Graphics g, Pen pen, EPointF start, EPointF end, float capLength)
        {
            //pen caps aren't flexible enough...
            //			pen.StartCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
            //			pen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
            EPointF pntDiff = end - start;

            g.DrawLine(pen, start.ToPointF(), end.ToPointF());
            g.DrawLine(pen, start.ToPointF(), (start + EPointF.FromLengthAndAngle(capLength, pntDiff.Angle + (float)Math.PI / 4)).ToPointF());
            g.DrawLine(pen, start.ToPointF(), (start + EPointF.FromLengthAndAngle(capLength, pntDiff.Angle - (float)Math.PI / 4)).ToPointF());

            g.DrawLine(pen, end.ToPointF(), (end + EPointF.FromLengthAndAngle(capLength, pntDiff.Angle + (float)Math.PI + (float)Math.PI / 4)).ToPointF());
            g.DrawLine(pen, end.ToPointF(), (end + EPointF.FromLengthAndAngle(capLength, pntDiff.Angle + (float)Math.PI - (float)Math.PI / 4)).ToPointF());
        }
Beispiel #5
0
        public override void EnterFrame()
        {
            this._frameNum++;

            float   f     = (float)Math.Sin((float)this._frameNum / 7f);
            EPointF ptNew = EPointF.FromLengthAndAngle(50, f * 0.5f);

            ptNew.Y *= 0.2f;

            if (this._ptOffset == null)
            {
                this._ptOffset = ptNew;
            }
            EPointF ptDiff = ptNew - this._ptOffset;

            this._ptOffset   = ptNew;
            this.Parent.Loc += ptDiff;
        }
Beispiel #6
0
		public float CheckCollisionsWithLinesFromTime(float a_fTime, ref PropsAtCollision propsAtCollision)
		{
			float fCollisionTime;
			EPointF pntCircleAtCollisionLoc;
			EPointF pntTouchLoc;

			EPointF locThis = this.Loc + this.Velocity*a_fTime;
			EPointF velThis = this.Velocity*(1.0f-a_fTime);

			float fFirstHitTime = 99;
			foreach (ERectangleF rctLine in GameMain.Instance.Table.Lines)
			{
				if (Endogine.Collision.Collision.CalcCircleLineCollision(locThis, this.Radius, velThis, rctLine, out pntTouchLoc, out pntCircleAtCollisionLoc))
				{
					fCollisionTime = (pntCircleAtCollisionLoc-locThis).Length / velThis.Length;
					if (fCollisionTime < fFirstHitTime)
					{
						fFirstHitTime = fCollisionTime;
						float fNormal = (float)Endogine.Collision.Collision.GetNormalAngle(rctLine)+(float)Math.PI/2;
						//the line's direction, it shouldn't matter if it's up or down, or left or right - same bounce regardless
						fNormal = Endogine.Collision.Collision.GetOrientationAngle(fNormal);

						float fVelAngle = velThis.Angle;
						float fAngleDiff = fVelAngle-fNormal;
						float fAfterBounceAngle = fVelAngle-fAngleDiff*2;

						propsAtCollision.Loc = pntCircleAtCollisionLoc;
						propsAtCollision.Velocity = EPointF.FromLengthAndAngle(velThis.Length, fAfterBounceAngle);
					}
				}
			}
			
			propsAtCollision.Ball = this;

			if (fFirstHitTime <= 1)
				propsAtCollision.Time =  fFirstHitTime * (1.0f-a_fTime) + a_fTime;
			return propsAtCollision.Time;
		}
Beispiel #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="a_loc">start loc</param>
        /// <param name="a_vel">find first collision/bounce while moving this amount</param>
        /// <param name="pntGridStick"></param>
        /// <returns>true if it hit something to stick to (another ball, or ceiling)</returns>
        public bool GetFirstStickOrBounce(ref EPointF a_loc, ref EPointF a_vel,
                                          out EPoint pntGridStick, out EPointF pntBounce, bool bMoveBallAfterCollision)
        {
            EPointF pntCollision = new EPointF(0, 0);
            EPointF pntCircleAtCollision;
            EPointF pntNormal = new EPointF(0, 0);
            bool    bCollided = false;

            pntGridStick = null;          //new EPoint(0,0);
            pntBounce    = null;          //new EPointF(0,0);

            float     fFirstTime = 1000;
            ArrayList aBalls     = m_playArea.Grid.GetAllBalls();

            foreach (Ball ball in aBalls)
            {
                float   fTime;
                EPointF pntThisCollision;

                if (Endogine.Collision.Collision.CalcFirstCircleCircleCollisions(
                        a_loc, ball.Loc,
                        a_vel, new EPointF(0, 0),
                        m_playArea.Grid.BallDiameter / 2 - 1, m_playArea.Grid.BallDiameter / 2 - 1,         //it's more like the original if we subtract 1
                        out pntThisCollision, out fTime))
                {
                    if (fTime < fFirstTime)
                    {
                        pntCollision = pntThisCollision;
                        fFirstTime   = fTime;
                    }
                }
            }
            if (fFirstTime < 1000)
            {
                EPointF pntfGrid = m_playArea.Grid.GetGridLocFromGfxLoc(pntCollision);
                pntGridStick = m_playArea.Grid.RoundToClosestGridLoc(pntfGrid);
                a_loc        = m_playArea.Grid.GetGfxLocFromGridLoc(pntGridStick);
                a_vel        = new EPointF(0, 0);
                return(true);
            }

            //check wall bounces and ceiling stick
            for (int nLineNum = 0; nLineNum < m_playArea.m_aCollisionLines.Count; nLineNum++)
            {
                ERectangleF rctLine = (ERectangleF)m_playArea.m_aCollisionLines[nLineNum];
                if (Endogine.Collision.Collision.CalcCircleLineCollision(a_loc, m_playArea.Grid.BallDiameter / 2, a_vel, rctLine, out pntCollision, out pntCircleAtCollision))
                {
                    if (nLineNum == 0)
                    {
                        //hit ceiling: make it stick!
                        EPointF pntfGrid = m_playArea.Grid.GetGridLocFromGfxLoc(pntCollision);
                        EndogineHub.Put(pntCollision.ToString() + "  " + pntfGrid.ToString());
                        pntGridStick = m_playArea.Grid.RoundToClosestGridLoc(pntfGrid);
                        a_loc        = m_playArea.Grid.GetGfxLocFromGridLoc(pntGridStick);
                        a_vel.X      = 0;
                        a_vel.Y      = 0;
                        return(true);
                    }

                    //TODO: check all lines, and use the one that is collided with first.
                    //Then a new test should be done from the bounce point

                    pntBounce = pntCollision;
                    //bounce against a wall: which direction will it have afterwards
                    double dNormal = Endogine.Collision.Collision.GetNormalAngle(rctLine);
                    //the line's direction, it shouldn't matter if it's up or down, or left or right - same bounce regardless
                    if (dNormal >= Math.PI)
                    {
                        dNormal -= Math.PI;
                    }
                    if (dNormal >= Math.PI / 2)
                    {
                        dNormal -= Math.PI / 2;
                    }

                    double dVelAngle = Math.Atan2(a_vel.X, -a_vel.Y);

                    double dAfterBounceAngle = dNormal - (dVelAngle - dNormal);
                    //just so it's easier to debug:
                    if (dAfterBounceAngle > Math.PI)
                    {
                        dAfterBounceAngle -= Math.PI;
                    }

                    //how far can it move before hitting wall
                    EPointF pntBefore   = new EPointF(pntCircleAtCollision.X - a_loc.X, pntCircleAtCollision.Y - a_loc.Y);
                    double  dPartOfMove = Endogine.Collision.PointLine.PointIsWhereOnLine(pntBefore, new ERectangleF(0, 0, a_vel.X, a_vel.Y));
                    if (dPartOfMove > 0.99)
                    {
                        dPartOfMove = 0.99;
                    }
                    else if (dPartOfMove < 0 && dPartOfMove > -0.001)
                    {
                        dPartOfMove = 0;
                    }

                    //the rest of the movement will be in bounce direction
                    a_vel = EPointF.FromLengthAndAngle(a_vel.Length, (float)dAfterBounceAngle);
                    //EPointF velNew = EPointF.FromLengthAndAngle(a_vel.Length, (float)dAfterBounceAngle);
                    //a_vel.X = velNew.X;
                    //a_vel.Y = velNew.Y;

                    //TODO: pntCircleAtCollision is not correctly calculated.
                    a_loc = pntCircleAtCollision;

                    if (bMoveBallAfterCollision)
                    {
                        a_loc.X += a_vel.X * (float)(1.0 - dPartOfMove);
                        a_loc.Y += a_vel.Y * (float)(1.0 - dPartOfMove);
                    }

                    bCollided = true;
                    break;
                }
            }
            if (!bCollided)
            {
                a_loc.X += a_vel.X;
                a_loc.Y += a_vel.Y;
            }
            return(false);
        }
        private EPointF GetLocFromHue()
        {
            float angle = (this.HSB.H - 60) / 180 * (float)Math.PI;

            return(this.Center + EPointF.FromLengthAndAngle(0.72f * this._trianglePoints[1].X, angle));
        }
Beispiel #9
0
 public override void EnterFrame()
 {
     this.Interactor.Loc = this._locOrg + EPointF.FromLengthAndAngle(this.Interactor.PartLeftToNoteOn * 7, (float)(this.Interactor.PartLeftToNoteOn * Math.PI * 2 * 4));
 }